Android - 5.0 跳到 8.0平台 兼容性问题

版权声明:1、本BLOG的目的、形式及内容。   此BLOG为个人维护BLOG,内容均来自 原创及互连网转载。最终目的为收集整理自己需要的文章技术等内容,不涉及商业用途。\r\n 2、有关原创文章的版权   本BLOG上原创文章未经本人许可,不得用于商业用途及传统媒体。网络媒体转载请注明出处,否则属于侵权行为。\r\n 3、有关本站侵权   本BLOG所转载的内容,均是本人未发现有对文章版权声明的文章且 https://blog.csdn.net/shijianduan1/article/details/83792026

---------------------------------------------------------------------------------------------------------------------------------------------------------------

转载声明:本文来自 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);
            }
    }
}

参考:Android8.0 启动后台Service

          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无法接收隐式广播消息

参考二:Android O行为变更--隐式广播限制

参考三:android 8.0跨App(进程)发送广播

参考四: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 解决

猜你喜欢

转载自blog.csdn.net/shijianduan1/article/details/83792026