Ich verwende derzeit die startWakefulService-Funktion, die in Oreo abstürzt. Ich erkenne, dass ich entweder zu startForegroundService () wechseln und einen Vordergrunddienst verwenden muss oder zu JobIntentService wechseln muss, aber aufgrund meines Codes unten bin ich nicht sicher, was ich tun soll. (Sorry, ich bin ein Android-Neuling). Alle Punkte in die richtige Richtung werden sehr geschätzt.
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GCMIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(), GCMIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Dies ist der aktuelle Fehler, den ich bekomme, wenn er auf Android 8.x läuft
Schwerwiegende Ausnahme: Java.lang.RuntimeException Empfänger com.heyjude.heyjudeapp.gcm.GcmBroadcastReceiver kann nicht gestartet werden: Java.lang.IllegalStateException: Dienst darf nicht gestartet werden cmp = com.app.app/.gcm.GCMIntentService (hat Extras)}: App befindet sich im Hintergrund.
Ich erlebe das gleiche Verhalten.
Warum tritt dieses Problem auf?
Aufgrund der neuen Background Execution Limits von Android 8 sollten Sie Dienst-Hintergrund nicht starten.
Wie ich das Problem behoben habe
Migrieren Sie Ihre GCMIntetService
nach JobIntentService
anstelle von IntentService
.
Bitte befolgen Sie diese Schritte: 1) Fügen Sie Ihrem Dienst die Berechtigung BIND_JOB_SERVICE hinzu:
<service Android:name=".service.GCMIntentService"
Android:exported="false"
Android:permission="Android.permission.BIND_JOB_SERVICE"/>
2) Verwenden Sie in Ihrer GCMIntentService
anstelle der IntentService
Android.support.v4.app.JobIntentService
und überschreiben Sie onHandleWork Entfernen Sie dann die override
in Ihrer onHandleIntent
.
public class GCMIntentService extends JobIntentService {
// Service unique ID
static final int SERVICE_JOB_ID = 50;
// Enqueuing work in to this service.
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, GCMIntentService.class, SERVICE_JOB_ID, work);
}
@Override
protected void onHandleWork(@NonNull Intent intent) {
onHandleIntent(intent);
}
private void onHandleIntent(Intent intent) {
//Handling of notification goes here
}
}
Schliessen Sie schließlich in Ihrer GCMBroadcastReceiver
Ihre GCMIntentService
ein.
public class GCMBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GCMIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
// startWakefulService(context, (intent.setComponent(comp)));
//setResultCode(Activity.RESULT_OK);
GCMIntentService.enqueueWork(context, (intent.setComponent(comp)));
}
}
Diese Implementierung funktioniert für mich, nachdem wir unser Ziel-SDK auf 27 aktualisiert haben, und ich hoffe, es funktioniert für Sie.
Basierend auf der Dokumentation :
Ab Android O machen Einschränkungen bei der Hintergrundprüfung diese Klasse zu Nr länger allgemein nützlich. (Es ist im Allgemeinen nicht sicher, einen Dienst .__ vom Empfang einer Sendung aus zu starten, da Sie keine Zusicherung haben , Dass sich Ihre App zu diesem Zeitpunkt im Vordergrund befindet und dies daher zulässig ist ) .) Stattdessen sollten Entwickler Android.app.job.JobScheduler für .__ verwenden. Planen Sie einen Job, und dies erfordert nicht, dass die App eine Reaktivierung aufhält sperren Sie dabei (das System sorgt dafür, dass eine Wecksperre für den Job gehalten wird).
Die einzige Alternative ist, einen ForeGroundService zu starten oder JobScheduler/JobIntentService zu verwenden
Sie können den Vordergrunddienst wie folgt starten:
@Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GCMIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(), GCMIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
ContextCompat.startForegroundService(context,intent.setComponent(comp));
...
}
Sie müssen auch startService()
von Ihrer Service-Klasse aus aufrufen und eine Benachrichtigung anzeigen. Sie können meine Antwort auf dieser SO für Implementierungsdetails verfolgen.