Android学习

Android8 避免startForeground方法弹出通知

2019-01-11  本文已影响0人  鹅鹅鹅_

在A8中谷歌对后台service进行了严格限制,不允许默默无闻的后台service存在,若想用service,必须以startForegroundService的方式启动service且必须在service内部5s内执行startForeground方法显示一个前台通知,否则会产生ANR或者crash。

显式通知用户你在运行一个后台service

首先遇到了如下问题

Context.startForegroundService() did not then call Service.startForeground()

最后发现是因为:
1、第一个参数id不能为0

startForeground(0, builder.build());

2、与正常的通知同用一个id可以“隐藏”掉这个通知,注意,这里需要提前注册一个没有声音没有震动的通知channel,否则虽然没有弹出通知,但还是有声音有震动。

    @TargetApi(26)
    private void silentForegroundNotification() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ) {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NotificationUtil.XQW_CHANNEL_ID);
            builder.setContentTitle(getString(R.string.app_name));
            builder.setContentText("");

            builder.setDefaults(Notification.DEFAULT_ALL);
            builder.setAutoCancel(true);
            builder.setShowWhen(true);
            builder.setSmallIcon(R.drawable.notify);

            // 这里两个通知使用同一个id且必须按照这个顺序后调用startForeground
            int id = NotificationUtil.nextNotifyId();
            NotificationManagerCompat.from(this).notify(id, builder.build());
            startForeground(id, builder.build());
        }
    }

注册一个无声无振动的通知渠道

NotificationChannel silentChannel = new NotificationChannel(XQW_SILENT_CHANNEL_ID, XQW_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
silentChannel.setGroup(XQW_CHANNEL_GROUP_ID);
silentChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);//设置在锁屏界面上显示这条通知
silentChannel.setDescription("小期旺信息通知");
silentChannel.setLightColor(Color.GREEN);
silentChannel.setName("小期旺通知");
silentChannel.setSound(null, null);
silentChannel.enableVibration(false);

通过这种方式可以悄无声息的启动一个service而不必真的弹一个前台通知。原理是找到了Android的一个系统bug,也是调试的时候无意间发现的,就是下面的代码会出现一个warning

NotificationManagerCompat.from(this).notify(id, builder.build());
startForeground(id, builder.build());
com.android.systemui W/StatusBar: removeNotification for unknown key: 0|com.option.small|6|null|10089

很明显,系统删除了通知,根本就不会显示出来。
当然,这应该是系统bug,谷歌以后可能会修复之。

上一篇下一篇

猜你喜欢

热点阅读