Ta aplikacja wyświetla oczekiwane zachowanie, jeśli aplikacja działa na pierwszym planie, w tle lub jest uśmiercana. Jednak, gdy jest on uruchomiony ponownie na PeriodicTask
zatrzymaGCMNetworkManager nie uruchamia funkcji Okresowo po ponownym uruchomieniu komputera
Poniżej znajdują się odpowiednie fragmenty kodu:
W 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);
W logcat , Otrzymuję następujące:
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)
}
Dołączanie wszystkie istotne szczegóły:
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>
główną działalność
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 (App Module)
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: Po kilku dniach analizy, mam zorientowali się, co następuje:
- Jest to specyficzny problem urządzenie. Nie dzieje się na przykład na urządzeniach Nexus.
- Jest to część większego problemu. Urządzenia wyświetlające to zachowanie również nie działają zgodnie z oczekiwaniami z
AlarmManager
, iRECEIVE_BOOT_COMPLETED broadcast receiver
. - Jedno obejście to this solution. Jednak to rozwiązanie ma co najmniej 2 problemy. (1) Po zabiciu aplikacji, uprawnienie
AccessibilityService
jest resetowane. Oznacza to, że za każdym razem, gdy otworzysz aplikację po tym czasie, otrzymasz ręczne pozwolenie. (2) Jeśli aplikacja zostanie zabita, ponowne jej uruchomienie nie będzie miało wpływu na szybkie wyszukiwanie: w urządzeniach z jednym plusem, jeśli twoja aplikacja ma w strukturze pakietu słowo "test
", wszystko działa! - Jeśli dodasz aplikację do białej listy, przechodząc do ustawień> Aplikacje (lokalizacja i nazwa może być różna na różnych urządzeniach), wszystko działa zgodnie z oczekiwaniami.
- Uruchomione aplikacje, do których musisz ręcznie dodać aplikację, zawierają dobrze znane aplikacje, takie jak WhatsApp, Facebook, Instagram i wiele innych. Po zainstalowaniu tych aplikacji zostaną automatycznie dodane do tej listy! Nie widzę jeszcze niestandardowego interfejsu API opublikowanego przez żadnego z tych producentów. To sprawia, że myślę, że te aplikacje są białe wymienione od końca producentów.
Podczas przeglądania dzienników natknąłem się na fakt, że własna aplikacja Google dla Youtube dla dzieci ma ten sam problem: ** E/NetworkScheduler.TED: Nie można uruchomić usługi: Intent {act = com.google.android. gms.gcm.ACTION_TASK_READY cmp = com.google.android.apps.youtube.kids/com.google.android.libraries.youtube.common.gcore.gcoreclient.gcm.impl.GcmTaskServiceDelegator (ma dodatki)} ** – ranjjose
robi to dzieje się na wielu urządzeniach? – user2450263
Tak ... zdarza się to na wielu urządzeniach. Doświadczyłem tego na jednym plusie urządzeń MI. – ranjjose