启动前台服务通知有问题,服务通知的渠道无效。

13

我在应用商店上有一个拥有50000用户的应用程序。最近,我更新了我的Android Studio并将SDK编译到27。我进行了一些更改以支持Android 8的更改,包括通知更改(例如,通知应具有唯一通道)。在运行Android 8的Android One手机上进行了测试,一切都很顺利。 在更新应用程序后,我在Android 8设备上看到了这些崩溃(大多数是Google Pixel手机)。

Fatal Exception: android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=-2 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0xffffcf00 actions=3 vis=PRIVATE)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1768)
   at android.os.Handler.dispatchMessage(Handler.java:106)
   at android.os.Looper.loop(Looper.java:164)
   at android.app.ActivityThread.main(ActivityThread.java:6494)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

我在Crashlytics上看到了7个这样的错误。每一个都有相同的日志,大约有5000多次崩溃,涉及约10个用户。因此,显然应用程序正在循环崩溃。

我遇到的问题是,这些日志没有提供任何日志,可以让我看到我的应用程序中发起此崩溃的源。 有没有办法找出哪个类抛出了这个崩溃?有什么帮助吗?

此外,我有这个通知的代码:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {

            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel mChannel = notificationManager.getNotificationChannel(id);
            if (mChannel == null) {
                mChannel = new NotificationChannel(id, name, importance);
                mChannel.setDescription(description);
                notificationManager.createNotificationChannel(mChannel);
            }
        }



    NotificationCompat.Builder builder = new NotificationCompat.Builder(context,id);
            builder.setContentTitle(pushMessages.size() + context.getString(R.string.new_notification))
                    .setContentIntent(pendingIntent)
                    .setContentText(pushMessages.get(0))
                    .setStyle(inboxStyle)
                    .setGroup(GROUP_KEY_NOTIFICATIONS)
                    .setGroupSummary(true)
                    .setAutoCancel(true);

            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                builder.setSmallIcon(R.drawable.notification_img)
                        .setColor(context.getResources().getColor(R.color.settings_yellow));


            } else {
                builder.setSmallIcon(R.mipmap.ic_launcher);
            }
            summaryNotification = builder.build();
notificationManager.notify(i, summaryNotification);

@sukhbir,我已经按照你提供的链接做了所有的事情。但是没有任何帮助。 - Fahid Nadeem
@FahidNadeem 我遇到了你描述的同样的问题。你找到了解决方案吗?谢谢。 - Royz
检查错误...它说通道为空...希望这有所帮助。 - mboy
5个回答

9
您忘记为通知设置频道ID。
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) builder.setChannelId(youChannelID);
< p >如果语句是可选的,取决于你的Min SDK级别。< /p >

1
所有其他解决方案都是关于创建自己的频道和方法,但没有人说到区别是,如果SDK >= O,则必须设置频道ID。感谢这个精彩的答案。 - Mahir Özdin
1
无需对API级别进行if检查,根据setChannelId的Javadoc: 在{@link android.os.Build.VERSION_CODES#O}之前的版本上无操作。 - Mustafa Berkay Mutlu

5

看起来在8.1中,您必须创建自己的通知渠道。

 private void startForeground() {
    String channelId ="";
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        createNotificationChannel("my_service", "My Background Service");
    }else{
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), channelId);
        Notification notification = notificationBuilder.setOngoing(true)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setPriority(PRIORITY_MIN)
                .setCategory(Notification.CATEGORY_SERVICE)
                .build();
        startForeground(101, notification);
    }


}

并在此之后

进行翻译


 @RequiresApi(Build.VERSION_CODES.O)
private String createNotificationChannel(String channelId ,String channelName){
    NotificationChannel chan = new NotificationChannel(channelId,
            channelName, NotificationManager.IMPORTANCE_NONE);
    chan.setLightColor(Color.BLUE);
    chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    manager.createNotificationChannel(chan);
    return channelId;
}

更新:在 Android P 中,还要添加前台权限。
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

0

看起来你需要创建通知渠道并将其传递给前台服务。

你可以在应用程序类中创建以下方法来创建通道:

private void createChannel(Context context, String channelId, String name) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel serviceChannel = new NotificationChannel(
                channelId,
                name,
                NotificationManager.IMPORTANCE_DEFAULT
        );
        serviceChannel.setSound(null, null);
        NotificationManager manager = context.getSystemService(NotificationManager.class);
        manager.createNotificationChannel(serviceChannel);
    }
}

0

我刚刚在我的应用程序中解决了这个问题,问题出在使用我的通知的类中,我将NotificationChannel的CHANNEL_ID和CHANNEL_NAME保存在一个字符串和常量、静态或最终变量中,但是我将这些值移动到XML Resource.String中,因为它们是我从不更改的值,并且我使用GetString(Resource.String.CH_NAME_GPS_ERROR_ID)获取它们,我不知道为什么,但它起作用了,我希望这也能解决你的问题。


0

是的,有一种方法可以找出哪个类引发了这个错误。

首先,您需要找出哪个类调用了Service.startForeground。该类可能会引发它。

使用Android Studio,进入Service类的源代码并找到startForeground方法。按住ctrl(或Mac上的Command)并单击方法签名。它将列出从所有库中调用该方法的类,包括文档引用。

enter image description here

我仍然面临着同样的问题。我认为现在已经存档的RoboSpice正在抛出这些错误。唯一的方法是重构整个代码库以使用其他东西(可能是Rx+Retrofit)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接