Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

你好,部分手机上会遇到这种错误 Unable to stop service com.shihoo.daemon.PlayMusicService@292e357: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=包名/com.shihoo.daemon.PlayMusicService }: app is in background uid UidRecord #13

Open
2697a opened this issue Jul 11, 2019 · 9 comments

Comments

@2697a
Copy link

2697a commented Jul 11, 2019

Unable to stop service com.shihoo.daemon.PlayMusicService@292e357: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=包名/com.shihoo.daemon.PlayMusicService }: app is in background uid UidRecord

@ShihooWang
Copy link
Owner

高版本的开启服务需要用startForegroundService(Intent service)
你的targetSdkVersion 版本多少?

@2697a
Copy link
Author

2697a commented Jul 11, 2019

你好,targetSdkVersion 是28

@2697a
Copy link
Author

2697a commented Jul 11, 2019

启动服务的时候为何不加一个版本判断呢?

@ShihooWang
Copy link
Owner

是的,需要判断Android O版本,给一个前台通知。
项目里面所有的后台Service都需要一个前台通知。

@2697a
Copy link
Author

2697a commented Jul 11, 2019

if (Build.VERSION.SDK_INT >= 26) {
startForegroundService(new Intent(this, MyService.class));
} else {
WatchProcessPrefHelper.setIsStartSDaemon(this, true);
DaemonEnv.startServiceSafely(this, MyService.class, false);
}这样写吗?我刚入门,请指教一下

@ShihooWang
Copy link
Owner

ShihooWang commented Jul 11, 2019

你好,那我贴一下代码,供你参考:
public class ForegroundNotificationUtils {
// 通知渠道的id
private static final String CHANNEL_ID = "保活";
private static final int CHANNEL_POSITION = 1;

public static void startForegroundNotification(Service service){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
        //启动前台服务而不显示通知的漏洞已在 API Level 25 修复
        NotificationManager manager = 
                (NotificationManager)service.getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel Channel = new NotificationChannel(CHANNEL_ID,"主服 
      务",NotificationManager.IMPORTANCE_HIGH);
        Channel.enableLights(true);//设置提示灯
        Channel.setLightColor(Color.GREEN);//设置提示灯颜色
        Channel.setShowBadge(true);//显示logo
        Channel.setDescription("我是描述");//设置描述
        Channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); //设置锁屏可见 
       VISIBILITY_PUBLIC=可见
        manager.createNotificationChannel(Channel);
        Notification notification = new Notification.Builder(service)
                .setChannelId(CHANNEL_ID)
                .setContentTitle("主服务")//标题
                .setContentText("运行中...")//内容
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.drawable.icon1)//自己弄一个小图标,小图标一定需要设置,否则会报错(如果不设置它启动服务前台化不会报错,但是你会发现这个通知不会启动),如果是普通通知,不设置必然报错
                .setLargeIcon(BitmapFactory.decodeResource(service.getResources(),R.drawable.icon1))
                .build();
        service.startForeground(CHANNEL_POSITION,notification);//服务前台化只能使用startForeground()方法,不能使用 notificationManager.notify(1,notification); 这个只是启动通知使用的,使用这个方法你只需要等待几秒就会发现报错了
    }else {
        //利用漏洞在 API Level 18 及以上的 Android 系统中,启动前台服务而不显示通知
        Notification notification = new Notification.Builder(service)
                .setContentTitle("主服务")//设置标题
                .setContentText("运行中...")//设置内容
                .setWhen(System.currentTimeMillis())//设置创建时间
                .setSmallIcon(R.drawable.icon1)//设置状态栏图标
                .setLargeIcon(BitmapFactory.decodeResource(service.getResources(),R.drawable.icon1))//设置通知栏图标
                .build();
        service.startForeground(CHANNEL_POSITION,notification);
    }
}


public static void deleteForegroundNotification(Service service){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationManager mNotificationManager = (NotificationManager) service.getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel mChannel = mNotificationManager.getNotificationChannel(CHANNEL_ID);
        if (null != mChannel) {
            mNotificationManager.deleteNotificationChannel(CHANNEL_ID);
        }
    }else {
        NotificationManager notificationManager = (NotificationManager) service.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(CHANNEL_POSITION);
    }
}

}
所有启动的后台Service的onCreate中 都调用这个startForegroundNotification(Service service)方法。
在Service的onDestroy()中调用deleteForegroundNotification(Service service)方法。

@2697a
Copy link
Author

2697a commented Jul 11, 2019

萬分感謝,我是通过gradle引入的,startForegroundNotification()和deleteForegroundNotification()这两个方法只用在我继承AbsWorkService的Service类中实现吧?引入的框架里的服务里面不用加吧?

@ShihooWang
Copy link
Owner

需要加的。
所有启动的后台Service,都要加。

本工程代码不多,你可以下载后以library的形式添加到你的工程中去,这样方便在某些部分调整下,适配自己的业务逻辑

@2697a
Copy link
Author

2697a commented Jul 12, 2019

好的,谢谢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants