Android 8.0 Oreo 通知頻道Notification channels

這是在我們針對API 26(Oreo)的應用中更新我們的FCM內容的快速提示。

我不得不更新當前的應用程序(將targetSdkVersion更改為26)以支持Android Oreo(8.0)。一切都很好(在以前的版本中),但在 Oreo,這不是快樂的情況。通知未按預期工作:當設備收到推送通知時,應用程序崩潰。這是logcat中的例外:
Fatal Exception: java.lang.RuntimeException: Unable to start receiver com.google.firebase.iid.FirebaseInstanceIdInternalReceiver: java.lang.IllegalStateException: Not allowed to start service Intent { act=com.google.firebase.INSTANCE_ID_EVENT pkg=PACKAGE cmp=COMPONENT }: app is in background uid UidRecord{c5e5e69 u0a325 RCVR bg:+1m25s411ms idle procs:1 seq(0,0,0)}
 at android.app.ActivityThread.handleReceiver(ActivityThread.java:3397)
 at android.app.ActivityThread.-wrap18(Unknown Source)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1780)
 at android.os.Handler.dispatchMessage(Handler.java:105)
 at android.os.Looper.loop(Looper.java:164)
 at android.app.ActivityThread.main(ActivityThread.java:6938)
 at java.lang.reflect.Method.invoke(Method.java)
 at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

研究問題

在對問題進行快速研究後,主要原因是:“ 不允許開始服務 ”。當您嘗試在應用程序處於後台或未運行時啟動服務時,會從Android系統拋出此消息。那是起點。所有帖子都引用了後台執行限制:最佳解決方案是在中間創建一個通知接收器,以便在匹配時執行服務。第一個錯誤:我的代碼中沒有。使用Firebase Messaging Cloud,沒有服務啟動的地方。所以?還有其他解決方案嗎?

將FCM至少更新為11.2.0

在玩完這個之後,我發現FCM版本11.4.0支持Android Oreo。實際上,在11.2.0中引入了Oreo的支持。你可以隨心所欲地使用它。
dependencies {
  compile 'com.google.firebase:firebase-core:11.4.0'
  compile 'com.google.firebase:firebase-messaging:11.4.0'
}
另外,Oreo為名為Notification Channels的通知引入了一個新概念。必須將所有通知分配給頻道,否則不會顯示。因此,如果我們的應用定位到API 26,並且我們應該出於任何原因顯示通知,我們必須將其分配給頻道。否則,您將收到類似這樣的警告Toast消息:

將通知分配給通道

第一步是創建一個頻道ID。創建一個的最佳位置是strings.xml文件。
<string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
完美,我們的最後一步是代碼方面的分配。在您調用通知方法以顯示通知的同一位置,您應該添加通道分配:
private void sendNotification(String messageTitle, String messageBody) {

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher2);

        Intent intent = new Intent(this, HomeActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

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

        String channelId = getString(R.string.default_notification_channel_id);
        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "channel name",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
                .setLargeIcon(bitmap)
                .setSmallIcon(R.drawable.logo)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
就是這樣!現在應用程序應該在使用Oreo的設備上運行。

留言

這個網誌中的熱門文章

Android - 使用 adb 安装apk

Android ContentProvider 實現多個應用程式共享資料

Android TextView autosizing 自動調整大小