前不久有个朋友过来给我汇报bug. 拿到他的logcat日志之后:

我发现了以下错误:

4-25 15:51:30.102 14544 14544 E MtaSDK : 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=0x42 color=0x00000000 vis=PRIVATE) 04-25 15:51:30.102 14544 14544 E MtaSDK : at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220) 04-25 15:51:30.102 14544 14544 E MtaSDK : at android.os.Handler.dispatchMessage(Handler.java:109) 04-25 15:51:30.102 14544 14544 E MtaSDK : at android.os.Looper.loop(Looper.java:166) 04-25 15:51:30.102 14544 14544 E MtaSDK : at android.app.ActivityThread.main(ActivityThread.java:7555) 04-25 15:51:30.102 14544 14544 E MtaSDK : at java.lang.reflect.Method.invoke(Native Method) 04-25 15:51:30.102 14544 14544 E MtaSDK : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469) 04-25 15:51:30.102 14544 14544 E MtaSDK : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)

起初我还以为是cordova-plugin-wechat的问题,但仔细一想这貌似是腾讯mta在捕获异常。

所以问题还是应该关注在

Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification:

并且这个问题仅在android 8.1上出现。经过一番查阅后发现,在android8.1之后我们必须创建自己的通知通道。

于是在项目里搜索了一下,发现cordova-plugin-backgroundmode里有使用到startForeground这个方法,我们可以在调用的地方增加以下代码:

修改cordova-plugin-background-mode/src/android/ForegroundService.java文件

找到下面代码

  Notification.Builder notification = new Notification.Builder(context)
                .setContentTitle(title)
                .setContentText(text)
                .setOngoing(true)
                .setSmallIcon(getIconResId(settings));
在后面增加以下代码:

```java

    //upgrade to sdk 26, fix problems with android 8.1
    if (android.os.Build.VERSION.SDK_INT >= 26) {
      //Set the channel’s ID//
       String CHANNEL_ONE_ID = "com.yourapp.ONE";
       //Set the channel’s user-visible name//
       String CHANNEL_ONE_NAME = "Channel One";
         //This only needs to be run on Devices on Android O and above
         NotificationManager notificationManager =
                 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
         NotificationChannel mChannel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_DEFAULT);
         mChannel.enableLights(true);
         mChannel.setLightColor(Color.MAGENTA);
         if (notificationManager != null) {
             notificationManager.createNotificationChannel(mChannel);
         }
         notification.setChannelId(CHANNEL_ONE_ID);
    }        

    if (settings.optBoolean("hidden", true)) {
        notification.setPriority(Notification.PRIORITY_MIN);
    }


本来想给插件提一下pr,但是发现之前已经有很多人提过了,但是插件暂时也没在维护了。
大家可以手动修改吧。