赞
踩
本文目录
项目需要Android设备开机后,自动启动一个后台服务。
在实现过程中发现,安卓版本在8.0之后,在启动服务时会频繁出现下述异常:
“Context.startForegroundService() did not then call Service.startForeground()”。
下面依次讲述如何实现Android开机自启服务和异常处理的方法。
实现思路:定义广播接收器,在android系统开机时,后台启动服务。
- public class BootReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
-
- // 检查是否是开机广播
- if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
- Log.v("BootReceiver","BootReceiver");
- //开启服务
- Intent intent = new Intent(context, TestService.class );
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//需要增加,否则会报错
- context.startService(intent);
-
- }
-
- }
在AndroidManifest.xml里声明广播接收器。
- <receiver
- android:name=".BootReceiver"
- android:enabled="true"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- </receiver>
- Android 8.0 不再允许后台service直接通过startService方式去启动,否则就会引起IllegalStateException。
- 因此在Android 8.0 中,需要在前台启动新服务,即 Context.startForegroundService()。
- 在系统创建服务后,应用有5秒的时间来调用该服务的 startForeground() 方法以显示新服务的用户可见通知。
- 如果应用在此时间限制内未调用 startForeground(),则系统将停止服务并声明此应用为 ANR。
- <!--android 9.0上使用前台服务,需要添加权限,此权限为级别为nomarl-->
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
- public class BootReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
-
- // 检查是否是开机广播
- if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
- Log.v("BootReceiver","BootReceiver");
- //开启服务
- Intent intent = new Intent(context, TestService.class );
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//需要增加,否则会报错
- context.startService(intent);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//安卓8.0之后
- context.startForegroundService(new Intent(context, TestService.class));
- } else {
- context.startService(new Intent(context, TestService.class));
- }
-
- }
-
- }
在Server中onStartCommand()方法中调用startForeground(),声明有服务在挂着,否则系统会停止服务,提示异常。
- public static final String CHANNEL_ID_STRING = "id";
- public static final String CHANNEL_NAME_STRING = "name";
- private Notification notification;
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- //适配8.0service
- NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
- NotificationChannel mChannel = null;
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
- mChannel = new NotificationChannel(CHANNEL_ID_STRING, CHANNEL_NAME_STRING, NotificationManager.IMPORTANCE_LOW);
- notificationManager.createNotificationChannel(mChannel);
- notification = new Notification.Builder(getApplicationContext(), CHANNEL_ID_STRING).build();
- startForeground(1, notification);
- }
-
- //其他初始化操作...
-
- return super.onStartCommand(intent, flags, startId);
-
- }
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。