---------------------------------------------------------------------------------------------------------------------------------------------------------------
转载声明:本文来自 https://blog.csdn.net/shijianduan1/article/details/83792026
---------------------------------------------------------------------------------------------------------------------------------------------------------------
前文:8.0平台去年就出来了, 项目从5.0 直接升到了8.0, 所以就有了这么一篇趟雷区文
今年9.0也出来了...
--------------------------------------------------------------------------------------------------------------------------------------------------------------
1.权限问题(6.0)
这个是几个月前做的了, 有点模糊,后期再补
2. Service(8.0)
8.0直接startService()会提示错误:
IllegalStateException: Not allowed to start service Intent
Android 8.0 还对特定函数做出了以下变更:
- 如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用
startService()
函数,则该函数将引发一个IllegalStateException
。- 新的
Context.startForegroundService()
函数将启动一个前台服务。现在,即使应用在后台运行,系统也允许其调用Context.startForegroundService()
。不过,应用必须在创建服务后的五秒内调用该服务的startForeground()
函数。
所在调用的时候,修改成以下:
if (Build.VERSION.SDK_INT >= 26) {
context.startForegroundService(intent);
} else {
// Pre-O behavior.
context.startService(intent);
}
同时 还需要在被调用的Service中添加代码 (其中“通知栏ID”,“通知栏名称” 非显示用,而是作为该通知的标识)
注:此处通知栏未特别设置,是使用默认的
ublic class NetChangedService extends Service {
@Override
public void onCreate() {
super.onCreate();
//8.0服务启动变化
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("通知栏ID", "通知栏名称", NotificationManager.IMPORTANCE_HIGH);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);
Notification notification = new Notification.Builder(getApplicationContext(), "通知栏ID").build();
startForeground(1, notification);
}
}
}
Android O startForegroundService(前台服务)流程分析
3.Notification(8.0)
8.0要求通知栏 有对NotificationChannel进行配置, 意义是 这样同一个“channelID”的通知栏消息可以叠加在一起,
下面代码是我将8.0需要添加的代码封装到一个方法里,这样原有代码 仅需改动一两行。(channelID也被封装进方法里,有需要自己拆分出来)
public void notify(){
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
----下面一行是新增的
builder = notificationVersion(context,builder,"NOTIFICATION_ChannelName");
notify(context, builder.build());
}
//新增,封装成了一个函数,这样方便修改
public static NotificationCompat.Builder notificationVersion(Context context,NotificationCompat.Builder builder, String channelName) {
String channelID = "com.example.app.packagename";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);
builder.setChannelId(channelID);
}
return builder;
}
4.Broadcast(8.0)
广播这块改动的算是比较大的,
影响一: 将部分系统广播改成隐式广播,
普通第三方应用无法再去监听隐式广播
影响二: 用户自定义广播
大多数情况自定义广播没有任何设置,也是隐式广播,所以也会导致收不到广播
修改方法一: sendBroiadCast()的intent 指明广播路径和apk
修改方法二:发送广播添加权限, 只有声明权限的才可以接收
修改方法三:接收广播添加权限,只有声明权限的才可以被接收
修改方法四:动态注册静态广播接收, 见参考四
参考四:Android8.0 Intent发送广播和启动服务的改动
参考五:Android Broadcast 和 BroadcastReceiver的权限限制
5.文件权限访问(7.0)
修改方法一(官方推荐):1. AndroidManifest.xml 中添加provider声明
2.新建文件res/xml/***.xml ,添加声明
3.代码修改 Uri uri = FileProvider.getUriForFile(context, "**androidmanifeest.xml里定义的*", file);
修改方法二:在application.java中 设置VmPolicy的配置。(很可惜,感觉好像失败了)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}
参考:Android笔记:Android 7.0 FileUriExposedException 解决