【问题标题】:Android background notifications with Firebase Cloud Messaging not received未收到带有 Firebase 云消息传递的 Android 后台通知
【发布时间】:2017-02-06 22:54:51
【问题描述】:

我搜索了很多关于应用程序在后台或关闭时的通知。顺便说一句,我正在使用 Firebase Cloud Messaging。它对我不起作用。我使用的是 Android 设置,当应用在前台或手机未锁定时,会收到通知。

  • 安装后,令牌会正确打印并订阅主题。
  • 当我在应用在前台处于活动状态(因此屏幕解锁并显示应用)时发送通知时,我会收到onMessageReceived 中所述的通知和标题。
  • 当我在应用未显示但仍在最近的应用中且屏幕解锁时发送通知时,我会收到标题和消息如@中所述的通知987654323@.
  • 当我在应用未显示但仍在最近的应用中并且屏幕锁定时发送通知时没有收到任何信息。
  • 当我在应用*关闭并从最近的应用中删除时发送通知时,没有收到任何信息。

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

附言。我阅读了有关受保护应用程序的打瞌睡模式,即使我将我的应用程序与受保护的应用程序放在一起,我也没有收到任何信息。我正在华为 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>

Gradle

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'

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());
    }
}

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.
    }
}

通知负载

{
    "to": "/topics/mytopic",
    "priority": "high",
    "notification": {
        "sound": "default",
        "badge": "1",
        "body": "the body text",
        "title": "title text"
     },
     "data": {
         "id": "id",
         "channel": "channel"
     }
}

编辑 - 为 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);
    }
}

更新有效负载

如果我像这样在 cmets 中将我的有效负载更改为建议的方式,它仍然无法正常工作。也许这与我正在测试的安装了 Android 6.0.1 的华为 P8 Lite 有关。

{
    "to": "/topics/mytopic",
    "priority": "high",
    "data": {
        "sound": "default",
        "badge": "1",
        "body": "the body text",
        "title": "title text"
    }
}

更新 2.0

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

【问题讨论】:

  • 可能duplicate(我从未使用过新的 Firebase 云消息传递,但在 GCM 中,您需要一个 WakefulBroadcastReceiver,在清单中声明了 WakeLock 权限和接收器,以便在应用关闭时接收)
  • 我也试过了,我更新了我的代码。
  • 耶稣,你为什么将接收者命名为“服务”?祝你好运跟上你自己的代码。
  • 糟糕,让我们改变它。但仍然没有运气:(
  • 如果您的工作快速且在 onMessageReceived 中处理,则无需管理唤醒锁。接收推送消息会自动唤醒设备。这就是推送消息的重点,对吧?

标签: android firebase android-notifications firebase-cloud-messaging


【解决方案1】:

当应用程序关闭时,它会关闭服务。您必须重新启动服务。

在您的 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);
    }
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      Firebase 有不同类型的通知,每种都有特殊处理。

      • 假设您使用的是数据推送,则不需要特殊处理或 WakefulBroadcastReceiver。
      • 如果您使用通知推送,通知将自动出现在系统托盘中。你不能在那里做任何特殊处理。

      在这里查看官方文档:https://firebase.google.com/docs/cloud-messaging/android/receive

      【讨论】:

        猜你喜欢
        • 2020-07-16
        • 2020-06-16
        • 2019-02-06
        • 2020-07-28
        • 2017-05-05
        • 2017-12-24
        • 1970-01-01
        • 2019-10-08
        • 2018-11-21
        相关资源
        最近更新 更多