From 01f8f9e16c23daaff8ce2223f209dfe8a4a00b00 Mon Sep 17 00:00:00 2001 From: Roberto Fierros Z Date: Wed, 23 Sep 2020 03:33:33 -0500 Subject: [PATCH] [Bugfix][Android] Use JobServiceIntent to fetch the FCM token in the background (#678) ### Highlights - Changes the mechanism by which the library fetches the FCM token in the background. ### Context In newer Android versions (8+), background applications cannot start `IntentService`'s. Using the notifications library in these newer Android versions will result in a lot of exceptions of the type `java.lang.IllegalStateException`. Sample stack trace: ``` java.lang.IllegalStateException: at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1522) at android.app.ContextImpl.startService (ContextImpl.java:1478) at android.content.ContextWrapper.startService (ContextWrapper.java:650) at com.wix.reactnativenotifications.RNNotificationsModule.startFcmIntentService (RNNotificationsModule.java:135) at com.wix.reactnativenotifications.RNNotificationsModule.initialize (RNNotificationsModule.java:50) at com.facebook.react.bridge.ModuleHolder.doInitialize (ModuleHolder.java:222) at com.facebook.react.bridge.ModuleHolder.markInitializable (ModuleHolder.java:97) at com.facebook.react.bridge.NativeModuleRegistry.notifyJSInstanceInitialized (NativeModuleRegistry.java:102) at com.facebook.react.bridge.CatalystInstanceImpl$2.run (CatalystInstanceImpl.java:441) at android.os.Handler.handleCallback (Handler.java:790) at android.os.Handler.dispatchMessage (Handler.java:99) at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java:26) at android.os.Looper.loop (Looper.java:164) at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:225) at java.lang.Thread.run (Thread.java:764) ``` Now, in order to start intents in the background, the `JobIntentService` class must be extended. This PR consists in basically the same changes proposed by @migbot in https://github.com/wix/react-native-notifications/pull/491 (this PR was closed for inactivity a few months ago). Should close https://github.com/wix/react-native-notifications/issues/671; --- lib/android/app/src/main/AndroidManifest.xml | 3 ++- .../RNNotificationsModule.java | 2 +- .../fcm/FcmInstanceIdRefreshHandlerService.java | 13 ++++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/android/app/src/main/AndroidManifest.xml b/lib/android/app/src/main/AndroidManifest.xml index 5b06abe7e..abd988a58 100644 --- a/lib/android/app/src/main/AndroidManifest.xml +++ b/lib/android/app/src/main/AndroidManifest.xml @@ -20,7 +20,8 @@ + android:exported="false" + android:permission="android.permission.BIND_JOB_SERVICE" /> diff --git a/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java b/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java index 5f513d3fa..db9eabaa4 100644 --- a/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java +++ b/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java @@ -144,6 +144,6 @@ protected void startFcmIntentService(String extraFlag) { final Context appContext = getReactApplicationContext().getApplicationContext(); final Intent tokenFetchIntent = new Intent(appContext, FcmInstanceIdRefreshHandlerService.class); tokenFetchIntent.putExtra(extraFlag, true); - appContext.startService(tokenFetchIntent); + FcmInstanceIdRefreshHandlerService.enqueueWork(appContext, tokenFetchIntent); } } diff --git a/lib/android/app/src/main/java/com/wix/reactnativenotifications/fcm/FcmInstanceIdRefreshHandlerService.java b/lib/android/app/src/main/java/com/wix/reactnativenotifications/fcm/FcmInstanceIdRefreshHandlerService.java index dd2cc9a21..972ac369d 100644 --- a/lib/android/app/src/main/java/com/wix/reactnativenotifications/fcm/FcmInstanceIdRefreshHandlerService.java +++ b/lib/android/app/src/main/java/com/wix/reactnativenotifications/fcm/FcmInstanceIdRefreshHandlerService.java @@ -1,19 +1,22 @@ package com.wix.reactnativenotifications.fcm; -import android.app.IntentService; +import androidx.annotation.NonNull; +import androidx.core.app.JobIntentService; +import android.content.Context; import android.content.Intent; -public class FcmInstanceIdRefreshHandlerService extends IntentService { +public class FcmInstanceIdRefreshHandlerService extends JobIntentService { public static String EXTRA_IS_APP_INIT = "isAppInit"; public static String EXTRA_MANUAL_REFRESH = "doManualRefresh"; + public static final int JOB_ID = 2400; - public FcmInstanceIdRefreshHandlerService() { - super(FcmInstanceIdRefreshHandlerService.class.getSimpleName()); + public static void enqueueWork(Context context, Intent work) { + enqueueWork(context, FcmInstanceIdRefreshHandlerService.class, JOB_ID, work); } @Override - protected void onHandleIntent(Intent intent) { + protected void onHandleWork(@NonNull Intent intent) { IFcmToken fcmToken = FcmToken.get(this); if (fcmToken == null) { return;