Android版本适配(二)

不同版本的变化

Android6.0发布时间: 2015年5月28日

主要变化:

  1. 运行时权限
  2. 增加低电耗模式和应用待机模式
  3. 取消支持 Apache HTTP 客户端
  4. 移除硬件标识符访问权
  5. WLAN 和网络连接变更
  6. 相机服务变更
Android7.0发布时间: 2016年8月22日

主要变化:

  1. 私有文件访问权限更改
  2. 多窗口支持(分屏显示)
  3. 通知增强功能
  4. 随时随地低电耗模式
  5. 多语言区域支持,更多语言
  6. 新增的表情符号
  7. Chrome 和 WebView 配合使用
  8. APK signature scheme v2
Android8.0发布时间:2017年8月22日

主要变化:

  1. 通知渠道
  2. 启动图标
  3. 统一的布局外边距和内边距
  4. 自动填充框架
  5. 画中画模式
  6. 多显示器支持媒体增强功能
Android9.0发布时间:2018年8月7日

主要变化:

  1. 刘海屏适配
  2. 通知功能的变更
  3. 隐私权变更
  4. 对使用非 SDK 接口的限制 和 适配策略
  5. 非Activity-Context启动Activity
  6. Apache HTTP 客户端弃用,影响采用非标准 ClassLoader 的应用
  7. 前台服务

注意:每个版本都有比较多的变化,但并不是所有内容都需要适配。适配某个版本,需要将targetSdkVersion改为对应的版本号,点击sync Now然后进行适配。

Android8.0适配

(1)通知渠道(Channeld)适配

Android O版本对通知做了规范性的控制,强制用户在发送通知的时候,对通知进行系统性的管理,新增了ChanneID,用来允许要为显示的每种通知类型创建用户可自定义的渠道,用户界面将通知渠道称之为通知类别。

注意:在8.0中所有通知的实现都需要提供通知渠道,否则,所有通知在8.0系统上面都不能正常显示

适配流程

1.创建 NotificationChannel 对象,并设置应用内唯一的通知 ID。在 NotificationManager 中注册通知渠道对象。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel newsChannel = new NotificationChannel(CHANNEL_NEWS, "新闻",NotificationManager.IMPORTANCE_HIGH);
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.createNotificationChannel(newsChannel);
}

2.配置通知渠道的属性,比如提示声音等。

public void sendNews(View view) {
    NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Notification notification = new NotificationCompat.Builder(this, CHANNEL_NEWS)
         .setContentTitle("新闻标题")
         .setContentText("新闻内容")
         .setAutoCancel(true)
         .build();
    manager.notify(1, notification);
}
public void sendNoChannel(View view) {
    NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Notification notification = new NotificationCompat.Builder(this)
         .setContentTitle("没有渠道的通知")
         .setContentText("通内容")
         .setAutoCancel(true)
         .setSmallIcon(R.mipmap.ic_launcher)
         .build();
    manager.notify(1, notification);
}

4.通知完成后需要及时关闭通道

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    //关闭通知通道
    notificationManager.deleteNotificationChannel("新闻");
}

(2)悬浮窗适配

8.0 API 新增了一种悬浮窗的窗口类型,TYPE_APPLICATION_OVERLAY;
如果应用使用 SYSTEM_ALERT_WINDOW 权限并且尝试使用以下窗口类型之一来在其他应用和系统窗口上方显示提醒窗口:

TYPE_PHONE 
TYPE_PRIORITY_PHONE 
TYPE_SYSTEM_ALERT 
TYPE_SYSTEM_OVERLAY 
TYPE_SYSTEM_ERROR 
TYPE_TOAST

这些窗口将始终显示在使用 TYPE_APPLICATION_OVERLAY 窗口类型的窗口下方。
如果该应用适配了8.0,则应用只能使用TYPE_APPLICATION_OVERLAY窗口类型来创建悬浮窗。(其它窗口类型在8.0已经被废弃掉)

适配流程

1.申请权限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

2.给悬浮窗设置type

public static void showLogoutDialog(final Context context) {
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    View view = View.inflate(context, R.layout.dialog_logout, null);
    builder.setView(view);
    final AlertDialog dialog = builder.create();
    if (Build.VERSION.SDK_INT>=26) {//8.0新特性
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
    }else{
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    }
    dialog.show();
}

(3)安装Apk适配

Android 8.0去除了“允许未知来源”选项,所以如果我们的App有安装App的功能(检查更新之类的),那么会无法正常安装。

适配流程

1.首先在AndroidManifest文件中添加安装未知来源应用的权限,这样系统会自动询问用户完成授权。

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

2.当然也可以先使用 canRequestPackageInstalls()查询是否有此权限,如果没有的话使用Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES这个action将用户引导至安装未知应用权限界面去授权。

private static final int REQUEST_CODE_UNKNOWN_APP = 100;

private void installAPK(){

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        boolean hasInstallPermission = getPackageManager().canRequestPackageInstalls();
        if (hasInstallPermission) {
            //安装应用
        } else {
            //跳转至“安装未知应用”权限界面,引导用户开启权限
            Uri selfPackageUri = Uri.parse("package:" + this.getPackageName());
            Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, selfPackageUri);
            startActivityForResult(intent, REQUEST_CODE_UNKNOWN_APP);
        }
    }else {
        //安装应用
    }

}

//接收“安装未知应用”权限的开启结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_UNKNOWN_APP) {
        installAPK();
    }
}    

(4)权限适配

Android 8.0中PHONE权限组新增两个权限

ANSWER_PHONE_CALLS:允许您的应用通过编程方式接听呼入电话。要在您的应用中处理呼入电话,您可以使用 acceptRingingCall() 函数。
READ_PHONE_NUMBERS:权限允许您的应用读取设备中存储的电话号码。

(5)广播适配

Android 8.0 引入了新的广播接收器限制,静态广播无法正常接收,因此应该移除所有为隐式广播 Intent 注册的广播接收器。
解决方案:使用动态广播代替静态广播。

(6)透明主题的Activity适配

Android 8.0 非全屏透明页面不允许设置方向,否则报错(后面8.1系统谷歌就去掉了这个限制)

适配流程

1.要么去掉对应activity中的 screenOrientation 属性,或者对应设置方向的代码。
2.要么舍弃透明效果,在它的Theme中添加:

<item name="android:windowIsTranslucent">false</item>    

3.使用透明的dialog或者PopupWindow来代替,也可以用DialogFragment

(7)其他

项目使用了ActiveAndroid,在 8.0 或 8.1 系统上使用 26 或以上的版本的 SDK 时,调用 ContentResolver 的 notifyChange 方法通知数据更新,或者调用 ContentResolver 的 registerContentObserver 方法监听数据变化时,会出现上述异常。
解决方案:

1.在清单文件配置:

<provider
   android:name="com.activeandroid.content.ContentProvider"
   android:authorities="com.jz.androidclient"
   android:enabled="true"
   android:exported="false"/>

2.去掉这个监听刷新的方法,改为广播刷新

Android9.0适配

Android P 限制了明文流量的网络请求,非加密的流量请求都会被系统禁止掉
解决方案:

1.在资源文件新建xml目录,新建文件network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>

2.清单文件配置:

<application
    android:networkSecurityConfig="@xml/network_security_config">
    <!--Android 9.0加的-->
    <uses-library
        android:name="org.apache.http.legacy"
        android:required="false" />
</application>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容