GCMNetworkManager не запускает PeriodicTask после перезагрузки

Приложение показывает ожидаемое поведение, если приложение работает на переднем плане, в фоновом режиме или убито. Однако, как только он перезагружен, PeriodicTask перестает работать

Ниже приведены соответствующие биты кода:

В AndroidManifest :

 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <service android:name=".tracking.MyTaskService" android:exported="true" android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE"> <intent-filter> <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" /> </intent-filter> </service> 

PeriodicTask config:

 PeriodicTask task = new PeriodicTask.Builder() .setService(MyTaskService.class) .setTag(TASK_TAG_PERIODIC) .setPeriod(30L) .setFlex(10L) .setExtras(bundle) .setPersisted(true) .build(); mGcmNetworkManager.schedule(task); 

В Logcat я получаю следующее:

 E/NetworkScheduler.TED: Couldn't start service: Intent { act=com.google.android.gms.gcm.ACTION_TASK_READY cmp=xxx.xxxxxx.xxx/.tracking.MyTaskService (has extras) } 

Добавляем все необходимые сведения:

AndroidManifest.xml

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.example.gcmnetworkmanagerquickstart"> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- [START manifest_service] --> <service android:name=".MyTaskService" android:exported="true" android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE"> <intent-filter> <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" /> </intent-filter> </service> <!-- [END manifest_service] --> </application> </manifest> 

Основная деятельность

 public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private static final int RC_PLAY_SERVICES = 123; public static final String TASK_TAG_PERIODIC = "periodic_task"; private GcmNetworkManager mGcmNetworkManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGcmNetworkManager = GcmNetworkManager.getInstance(this); if(checkPlayServicesAvailable()){ startPeriodicTask(); } } public void startPeriodicTask() { Log.d(TAG, "startPeriodicTask"); PeriodicTask task = new PeriodicTask.Builder() .setService(MyTaskService.class) .setTag(TASK_TAG_PERIODIC) .setPeriod(5) .setPersisted(true) .build(); mGcmNetworkManager.schedule(task); } private boolean checkPlayServicesAvailable() { GoogleApiAvailability availability = GoogleApiAvailability.getInstance(); int resultCode = availability.isGooglePlayServicesAvailable(this); if (resultCode != ConnectionResult.SUCCESS) { if (availability.isUserResolvableError(resultCode)) { // Show dialog to resolve the error. availability.getErrorDialog(this, resultCode, RC_PLAY_SERVICES).show(); } else { // Unresolvable error Toast.makeText(this, "Google Play Services error", Toast.LENGTH_SHORT).show(); } Log.d(TAG, "Play Services NOT Available"); return false; } else { Log.d(TAG, "Play Services Available"); return true; } } } 

MyTaskService

 public class MyTaskService extends GcmTaskService { private static final String TAG = "MyTaskService"; @Override public void onInitializeTasks() { } @Override public int onRunTask(TaskParams taskParams) { Log.d(TAG, "onRunTask: " + taskParams.getTag()); return doPeriodicTask(); } private int doPeriodicTask() { Log.d(TAG, "doPeriodicTask Called"); return GcmNetworkManager.RESULT_SUCCESS; } } 

Build.gradle (модуль приложения)

 apply plugin: 'com.android.application' android { compileSdkVersion 26 buildToolsVersion "26.0.0" defaultConfig { applicationId "com.google.example.gcmnetworkmanagerquickstart" minSdkVersion 14 targetSdkVersion 26 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } allprojects { repositories { jcenter() google() } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' implementation 'com.android.support:appcompat-v7:26.0.0-beta2' compile 'com.squareup.okhttp:okhttp:2.7.0' compile 'com.google.android.gms:play-services-gcm:11.0.2' } 

Edit1: После нескольких дней анализа я выяснил следующее:

  1. Это проблема, связанная с устройством. Например, не происходит на устройствах-подключаемых устройствах.
  2. Это часть более крупной проблемы. Устройства, демонстрирующие это поведение, также не работают AlarmManager с RECEIVE_BOOT_COMPLETED broadcast receiver AlarmManager , FirebaseJobScheduler и RECEIVE_BOOT_COMPLETED broadcast receiver .
  3. Одним из решений является это решение . Однако это решение имеет как минимум 2 проблемы. (1) Когда вы убиваете приложение, разрешение AccessibilityService сбрасывается. Это означает, что каждый раз, когда вы открываете приложение после этого, необходимо предоставить разрешение на использование вручную. (2) Если приложение убито, перезагрузка после этого не ударит по RECEIVE_BOOT_COMPLETED broadcast receiver
  4. Сумасшедший поиск: в устройствах с одним плюсом, если ваше приложение имеет test слово в структуре пакета, все работает!
  5. Если вы настроите белый список приложений на настройки> Приложения (расположение и имя этого могут отличаться на разных устройствах), все работает так, как ожидалось.
  6. Запуск приложений, к которым вы должны вручную добавить приложение, содержит хорошо известные приложения, такие как WhatsApp, Facebook, Instagram и многие другие. Когда вы устанавливаете эти приложения, они автоматически добавляются в этот список! Я еще не видел пользовательский API, опубликованный любым из этих производителей для этого. Это заставляет меня думать, что эти приложения белые, перечисленные со стороны производителей.

Solutions Collecting From Web of "GCMNetworkManager не запускает PeriodicTask после перезагрузки"

Обновление: обнаружена ошибка, которая не будет исправлена ​​(не подлежит), которая может быть связана с темой. Похоже, что поведение службы доступности несовместимо между устройствами. Некоторые из них отключат услугу, некоторые из них возобновятся и т. Д. Это соответствует жалобам пользователей, найденным в Интернете, и с вашими наблюдениями хорошо.

Лучший совет, который я могу дать, – сделать сервис как можно более минимальным для другого процесса (чтобы он не был убит при отключении приложения), а также при загрузке, если он включен, а если нет – используйте Чтобы обеспечить быстрый доступ к экрану настроек специальных возможностей Android, для удобства доступа.


Я не знаком с конкретной проблемой, но я считаю, что это решение будет работать для вас. Я использую этот код для AlarmManager в производстве.

В AndroidManifest.xml:

  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <receiver android:name=".BootListener"> <intent-filter> <category android:name="android.intent.category.DEFAULT"/> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> 

И создать класс

 public class BootListener extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // If your bootstrap is in Application class, then it will be called anyway - nothing to do here. // else - call your bootsrap here } } 

я полагаю, что

(2) Если приложение убито, перезагрузка после этого не ударит по радиоприемнику RECEIVE_BOOT_COMPLETED

Неправильно, при перезагрузке Android не знает, что ваше приложение было убито. Это никогда не было проблемой для моего приложения (+ 1.2M пользователей).

PeriodicTask config:

 PeriodicTask task = new PeriodicTask.Builder() .setService(MyTaskService.class) .setTag(TASK_TAG_PERIODIC) .setPeriod(30L) .setFlex(10L) .setExtras(bundle) **/* you put this line here */** .setPersisted(true) .build(); PeriodicTask task = new PeriodicTask.Builder() .setService(MyTaskService.class) .setTag(TASK_TAG_PERIODIC) /* you don't have ".setExtras(bundle)" line here */ /* try adding this line from above, as logcat is showing this */ .setPeriod(5) .setPersisted(true) .build();