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的設備上運行。
留言
張貼留言