启动前景的通知错误,服务通知的频道无效:

时间:2018-07-30 06:08:29

标签: android service notifications android-8.0-oreo android-8.1-oreo

因此,我在商店中有一个拥有50000用户的应用程序。最近,我将我的android studio更新并编译为27。我进行了一些更改以支持android 8更改,包括Notification更改(例如Notification应该具有唯一的频道)。在Android One手机(运行android 8)上进行了测试。一切顺利。 在Playstore上更新应用程序后,我在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个错误。每个都有相同的日志,大约10个用户的崩溃大约有5000多个。因此,应用程序显然崩溃了。

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

我也有以下用于通知的代码:

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

5 个答案:

答案 0 :(得分:2)

您忘记设置通知的频道ID。

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) builder.setChannelId(youChannelID);

if语句是可选的,取决于您的Min SDK级别。

答案 1 :(得分:0)

如果您使用服务类,则可以输入此代码

public class BlablaService extends Service 

    @Override
    public void onCreate(){
        super.onCreate();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            startMyOwnForeground();
        else
            startForeground(1, new Notification());
    }

    private void startMyOwnForeground(){
        String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
        String channelName = "My Background Service";
        NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
        chan.setLightColor(Color.BLUE);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        assert manager != null;
        manager.createNotificationChannel(chan);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
        Notification notification = notificationBuilder.setOngoing(true)
                .setSmallIcon(R.drawable.icon_1)
                .setContentTitle("App is running in background")
                .setPriority(NotificationManager.IMPORTANCE_MIN)
                .setCategory(Notification.CATEGORY_SERVICE)
                .build();
        startForeground(2, notification);
    } 

当然不要忘记您的AndroidManifest.xml的ForeGroundService权限

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

答案 2 :(得分:0)

您似乎在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" />

答案 3 :(得分:0)

是的,有一种方法可以找出哪个类引发此错误。 因此,首先,您需要找出哪个类正在调用Service.startForeground。该课程可以将其抛出。

使用Android Studio,转到Service类的源代码,然后找到startForeground方法。按住ctrl(在Mac上为Command),然后单击方法签名。它将列出所有调用该方法的库中的类,包括文档参考。

enter image description here

我仍然面临着同样的问题。我认为RoboSpice(现在已存档)引发了这些错误。找出的唯一方法是重构所有代码库以使用其他代码(可能是Rx + Retrofit)。

答案 4 :(得分:0)

我刚刚在应用程序中解决了这个问题,发生的是,在使用通知的类中,我将NotificationChannel的CHANNEL_ID和CHANNEL_NAME保留在String和Constant,Static或Final变量中,但是我移动了这些值到XML Resource.String,因为它们是我永远不会更改的值,我使用GetString(Resource.String.CH_NAME_GPS_ERROR_ID)来获取它们,我不知道为什么,但是它起作用了,希望这也能解决您的问题< / p>