Не нажимается, если приложение закрыто

Прежде чем маркировать это как дубликат:

Я прочитал по крайней мере 15 похожих потоков, и каждый из них либо использует старый код анализа (теперь устаревший setDefaultPushCallback), либо проблема возникла в результате вызова Parse.initialize (…) в действии, а не в Класс приложения. Но это не применимо к моему делу. Официальный пример (который я использую), очевидно, делает это правильно, поэтому код уже находится в классе Application.

Я загрузил пример Push Starter из официальных руководств Parse и попробовал его на эмуляторе. Я получаю нажатия только во время работы приложения. Когда он закрыт (удаляется из списка «последние приложения», а не убит), я больше не получаю толкает. Что делает всю функцию довольно бесполезной … Я пытался с GCM и без нее, поведение такое же.

Какие-нибудь подсказки, что может быть неправильным? Все классы являются примерами с запасом, ничего не переопределенные или не добавленные мной (за исключением id / key и вызова ParsePush.subscribeInBackground, который я скопировал из руководства). Как ни странно, примерный код не содержал ParsePush.subscribeInBackground, и QuickStart не упоминает об этом. Он даже дает кнопку «Тест», которая якобы отправляет push, который я никогда не получаю, с подпиской или без подписки. Единственный способ, которым я смог получить толчок до сих пор, заключался в том, что subscribeInBackground и отправка push вручную, хотя веб-консоль, и только так, если приложение запущено. Веб-консоль также продолжает говорить, что есть 2 зарегистрированных устройства … что неверно.

Manifest:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.parse.starter" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <!-- IMPORTANT: Change "com.parse.starter.permission.C2D_MESSAGE" in the lines below to match your app's package name + ".permission.C2D_MESSAGE". --> <permission android:protectionLevel="signature" android:name="com.parse.starter.permission.C2D_MESSAGE" /> <uses-permission android:name="com.parse.starter.permission.C2D_MESSAGE" /> <application android:name=".ParseApplication" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:allowBackup="true"> <activity android:name=".ParseStarterProjectActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.parse.PushService" /> <receiver android:name="com.parse.ParseBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.USER_PRESENT" /> </intent-filter> </receiver> <receiver android:name="com.parse.ParsePushBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.parse.push.intent.RECEIVE" /> <action android:name="com.parse.push.intent.DELETE" /> <action android:name="com.parse.push.intent.OPEN" /> </intent-filter> </receiver> <receiver android:name="com.parse.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <!-- IMPORTANT: Change "com.parse.starter" to match your app's package name. --> <category android:name="com.parse.starter" /> </intent-filter> </receiver> </application> </manifest> 

ParseApplication:

 package com.parse.starter; ... public class ParseApplication extends Application { @Override public void onCreate() { super.onCreate(); // Initialize Crash Reporting. ParseCrashReporting.enable(this); // Enable Local Datastore. Parse.enableLocalDatastore(this); ParseUser.enableAutomaticUser(); // Add your initialization code here Parse.initialize(this, "***", "***"); ParseACL defaultACL = new ParseACL(); // Optionally enable public read access. // defaultACL.setPublicReadAccess(true); ParseACL.setDefaultACL(defaultACL, true); ParsePush.subscribeInBackground("", new SaveCallback() { @Override public void done(ParseException e) { if (e == null) { Log.d("com.parse.push", "successfully subscribed to the broadcast channel."); } else { Log.e("com.parse.push", "failed to subscribe for push", e); } } }); } } 

Чтобы разъяснить, почему вы видите это поведение, Parse имеет два разных способа доставки push-уведомлений:

  1. «Parse way»: у пакета Parse SDK есть компонент, работающий в вашем приложении, который поддерживает соединение с серверными серверами Parse. Это будет работать только тогда, когда ваше приложение действительно запущено, потому что его убивает, и он прерывает соединение с сервером Parse.
  2. Уведомления «push» от GCM «Google»: это работает через Google Play Services, приложение, которое всегда работает в фоновом режиме и может запускать ваше приложение, когда это необходимо. Это всегда будет работать, если вы не остановите приложение.

В вашем случае есть конфликт com.parse.starter пакетов: com.parse.starter – это имя пакета, которое действительно было включено в пример. Это заставляет GCM не работать, потому что он уже знает пакет под другой подписью. Изменение имени вашего пакета на нечто уникальное, например com.parse.kaqqao должно решить трюк.

Для этого есть несколько причин:

  1. Существует два BroadcastReceiver: «com.parse.ParsePushBroadcastReceiver» и «com.parse.GcmBroadcastReceiver». Я считаю, что первый приемник получает приоритет над GCMBroadcastReceiver, и, таким образом, на поведение не влияет удаление или сохранение этого ресивера. Это также может быть связано с действием «com.parse.push.intent.RECEIVE», который может обрабатывать действие push-сообщений RECEIVE. Если оба приемника выполняют одну и ту же задачу анализа синтаксического сообщения (начиная с той же службы в фоновом режиме), включите фильтр намерений внутри одного приемника и разрешите ему обрабатывать всевозможные push-сообщения. Поскольку GCMBroadcastReceiver имеет разрешение C2DM.

  2. Попробуйте изменить порядок двух тегов приемника вещания в манифесте. (Сохраните GCMBroadcastReceiver перед ParsePushBroadcastReceiver)

  3. Это может быть связано с android: exported = "false", возможно, это мешает приемнику прослушивать push-сообщения, отправленные сервером. Попробуйте изменить на true.