未收到Firebase Cloud Messaging的Android后台通知

Tom*_*pee 2 android android-notifications firebase firebase-cloud-messaging

当应用程序处于后台或关闭时,我已经搜索了很多关于通知的信息.我顺便使用Firebase云消息传递.它对我不起作用.我已经使用了Android设置,当应用程序位于前台或手机未锁定时,会收到通知.

  • 安装后,令牌会正确打印并订阅该主题.
  • 当应用程序在前台处于活动状态时发送通知(因此屏幕已解锁并显示应用程序),我会收到通知和标题,如下所述onMessageReceived.
  • 当我在应用程序未显示但仍在最近的应用程序中并且屏幕已解锁时发送通知时,我会收到包含标题和消息的通知notification payload.
  • 当我在应用程序未显示但仍在最近的应用程序中并且屏幕被锁定时发送通知时,不会收到任何内容.
  • 当应用程序被关闭并从最近的应用程序中删除时,我发送通知时,不会收到任何内容.

如何更改此设置,以便即使关闭或手机被锁定,应用也会始终收到通知?

PS.我阅读了有关受保护应用程序的打盹模式,即使我将我的应用程序与受保护的应用程序放在一起我什么也得不到.我正在测试华为P8 Lite.

AndroidManifest

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme" >
    <activity android:name=".activities.MainActivity"
        android:configChanges="orientation"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service
        android:name=".services.MyAppFirebaseMessagingService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>
    <service
        android:name=".services.FirebaseIDService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>
    <receiver android:name=".services.NotificationReceiver" />
</application>
Run Code Online (Sandbox Code Playgroud)

摇篮

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.google.firebase:firebase-core:9.2.0'
    compile 'com.google.firebase:firebase-messaging:9.2.0'
}

apply plugin: 'com.google.gms.google-services'
Run Code Online (Sandbox Code Playgroud)

FirebaseMessagingService

public class MyAppFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "FCM Service";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // TODO: Handle FCM messages here.
        // If the application is in the foreground handle both data and notification messages here.
        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated.
        Log.d(TAG, "From: " + remoteMessage.getFrom());
        Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());

        showNotification(getApplicationContext());
    }

    public static void showNotification(Context context){
        Intent intent = new Intent(context, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle("FCM Message")
            .setContentText("FCM Body")
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setPriority(Notification.PRIORITY_MAX)
            .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0, notificationBuilder.build());
    }
}
Run Code Online (Sandbox Code Playgroud)

FirebaseInstanceIDService

public class FirebaseIDService extends FirebaseInstanceIdService {

    private static final String TAG = "FirebaseIDService";

    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);

        System.out.println("Devicetoken: " + refreshedToken);

        FirebaseMessaging.getInstance().subscribeToTopic("/topics/myapp");

        // TODO: Implement this method to send any registration to your app's servers.
        sendRegistrationToServer(refreshedToken);
     }

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM InstanceID token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private void sendRegistrationToServer(String token) {
         // Add custom implementation, as needed.
    }
}
Run Code Online (Sandbox Code Playgroud)

通知有效载荷

{
    "to": "/topics/mytopic",
    "priority": "high",
    "notification": {
        "sound": "default",
        "badge": "1",
        "body": "the body text",
        "title": "title text"
     },
     "data": {
         "id": "id",
         "channel": "channel"
     }
}
Run Code Online (Sandbox Code Playgroud)

编辑 - 为WakeFulBroadcastReceiver添加代码

public class NotificationReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        // cancel any further alarms
        AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        alarmMgr.cancel(alarmIntent);
        completeWakefulIntent(intent);

        // start the GcmTaskService
        MyAppFirebaseMessagingService.showNotification(context);
    }
}
Run Code Online (Sandbox Code Playgroud)

更新PAYLOAD

如果我在这样的评论中将我的有效负载更改为建议的方式,它仍然无效.也许它与我正在安装Android 6.0.1的华为P8 Lite有关.

{
    "to": "/topics/mytopic",
    "priority": "high",
    "data": {
        "sound": "default",
        "badge": "1",
        "body": "the body text",
        "title": "title text"
    }
}
Run Code Online (Sandbox Code Playgroud)

更新2.0

我已经在多个设备和版本上进行了测试.在使用Android 5的设备上,它工作正常,也没有打开应用程序和屏幕锁定.只有它不能正常工作的设备才是我自己的华为P8 Lite.仍然无法弄清楚为什么它不适用于那个.

Cli*_*ith 5

我还遇到了设备关闭时未收到通知的问题,就像重新启动后一样。

事实证明,它不适用于该解决方案的调试版本,因此必须在发布模式下进行测试。对于使用 Android Studio 的用户,请按调试按钮旁边的绿色播放按钮。


mab*_*abg 5

当应用关闭时,它会关闭服务.您必须重新启动该服务.

在Application类上,实现ActivityLifecycleCallbacks,并在onActivityDestroyed上重启服务并发出警报.

public class YourApplication extends Application implements Application.ActivityLifecycleCallbacks {
    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(this);
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
            Intent restartService = new Intent(getApplicationContext(), MyAppFirebaseMessagingService.class);
            PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(),1,restartService,PendingIntent.FLAG_ONE_SHOT);
            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            alarmManager.set(AlarmManager.ELAPSED_REALTIME,5000,pendingIntent);
    }
}
Run Code Online (Sandbox Code Playgroud)