不同版本的变化
Android6.0发布时间: 2015年5月28日
主要变化:
- 运行时权限
- 增加低电耗模式和应用待机模式
- 取消支持 Apache HTTP 客户端
- 移除硬件标识符访问权
- WLAN 和网络连接变更
- 相机服务变更
Android7.0发布时间: 2016年8月22日
主要变化:
- 私有文件访问权限更改
- 多窗口支持(分屏显示)
- 通知增强功能
- 随时随地低电耗模式
- 多语言区域支持,更多语言
- 新增的表情符号
- Chrome 和 WebView 配合使用
- APK signature scheme v2
Android8.0发布时间:2017年8月22日
主要变化:
- 通知渠道
- 启动图标
- 统一的布局外边距和内边距
- 自动填充框架
- 画中画模式
- 多显示器支持媒体增强功能
Android9.0发布时间:2018年8月7日
主要变化:
- 刘海屏适配
- 通知功能的变更
- 隐私权变更
- 对使用非 SDK 接口的限制 和 适配策略
- 非Activity-Context启动Activity
- Apache HTTP 客户端弃用,影响采用非标准 ClassLoader 的应用
- 前台服务
注意:每个版本都有比较多的变化,但并不是所有内容都需要适配。适配某个版本,需要将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>
网友评论