1、电商项目需要语音播报,然后集成了极光的语音播报,把消息接收、下载音频文件及播放都放在Service中进行,在8.0以下的系统没有问题,但是在8.0及以上的系统报错,日志如下:
android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1961)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:198)
at android.app.ActivityThread.main(ActivityThread.java:7015)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:521)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:837)
然后查看了官方的文档,说要把Service改成前台服务的形式:
1)、需要在Service的onCreate()中添加下面的代码:
public static final String CHANNEL_ID_STRING = "yyb001";
@Override
public void onCreate() {
super.onCreate();
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, "诺秒贷", NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(mChannel);
Notification notification = new Notification.Builder(getApplicationContext(), CHANNEL_ID_STRING).build();
startForeground(1, notification);
}
}
2)、启动服务添加兼容处理:
//开启服务兼容
Intent intentService = new Intent(SwapSpaceApplication.this, ZhkjLocalService.class);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
startForegroundService(intentService);
} else {
startService(intentService);
}
3)、另外在9.0的系统上需要添加权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
如果不加权限,9.0会报错,日志如下:
java.lang.RuntimeException: Unable to create service com.swap.space.zh.service.ZhkjLocalService: java.lang.SecurityException: Permission Denial: startForeground from pid=5827, uid=10094 requires android.permission.FOREGROUND_SERVICE
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3544)
at android.app.ActivityThread.access$1300(ActivityThread.java:199)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1666)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.SecurityException: Permission Denial: startForeground from pid=5827, uid=10094 requires android.permission.FOREGROUND_SERVICE
at android.os.Parcel.createException(Parcel.java:1942)
at android.os.Parcel.readException(Parcel.java:1910)
at android.os.Parcel.readException(Parcel.java:1860)
at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:5198)
at android.app.Service.startForeground(Service.java:695)
at com.swap.space.zh.service.ZhkjLocalService.onCreate(ZhkjLocalService.java:67)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3532)
at android.app.ActivityThread.access$1300(ActivityThread.java:199)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1666)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2、理论知识:
1). 前台服务和后台服务的区别(转载https://blog.youkuaiyun.com/o279642707/article/details/82352431):
类别 | 区别 | 应用 |
---|---|---|
前台服务 | 会在通知一栏显示 ONGOING 的 Notification, 当服务被终止的时候,通知一栏的 Notification 也会消失,这样对于用户有一定的通知作用。 | 常见的如音乐播放服务 |
后台服务 | 默认的服务即为后台服务,即不会在通知一栏显示 ONGOING 的 Notification。 当服务被终止的时候,用户是看不到效果的。 | 某些不需要运行或终止提示的服务,如天气更新,日期同步,邮件同步等。 |