Android5.0
- multiDexEnabled
- Button将总是位于最上层
从5.0开始,在同一个layout下,就算你在Button上覆盖了相应的View,Button将总是位于最上层。产生原因:stateListAnimator属性。谷歌在Material Design中推出,是一个非常简单的方法用来实现在可视状态之间平滑过渡。这个属性可以通过android:stateListAnimator进行设置,可以使控件在点击时产生不同的交互。对于Button,点击时默认有个阴影的效果用于表示按下的状态(5.0以前就是简单的变色)。 解决方法:可以使用 android:stateListAnimator=”@null” 去掉阴影效果而使Button可以被正常的覆盖。
Android6.0
- 动态权限
- wifi
Android6.0之后,Wifi的使用更加严格。需要动态获取LOCATION权限,如果还想获取Wifi列表的话还需要打开GPS(位置信息)。
1 | <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> |
Android7.0
使用FileProvider授权参考
APK signature scheme v2
org.apache不支持问题
Android8.0
Notification(通知权限)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/**
* 判断通知权限是否开启
* @param context 上下文
*/
public static boolean isNotificationEnabled(Context context){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)).areNotificationsEnabled();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
ApplicationInfo appInfo = context.getApplicationInfo();
String pkg = context.getApplicationContext().getPackageName();
int uid = appInfo.uid;
try {
Class<?> appOpsClass = Class.forName(AppOpsManager.class.getName());
Method checkOpNoThrowMethod = appOpsClass.getMethod("checkOpNoThrow", Integer.TYPE, Integer.TYPE, String.class);
Field opPostNotificationValue = appOpsClass.getDeclaredField("OP_POST_NOTIFICATION");
int value = (Integer) opPostNotificationValue.get(Integer.class);
return (Integer) checkOpNoThrowMethod.invoke(appOps, value, uid, pkg) == 0;
} catch (NoSuchMethodException | NoSuchFieldException | InvocationTargetException | IllegalAccessException | RuntimeException | ClassNotFoundException ignored) {
return true;
}
} else {
return true;
}
}Notification(通知适配)
静态广播无法正常接收
Google官方声明:从android 8.0(API26)开始,对清单文件中静态注册广播接收者增加了限制,建议大家不要在清单文件中静态注册广播接收者,改为动态注册。当然,如果你还是想用静态注册的方式也是有方法的,Intent里添加Component参数可实现。
Android9.0
- 刘海屏支持
Android 9 支持最新的全面屏,其中包含为摄像头和扬声器预留空间的屏幕缺口。 通过 DisplayCutout类可确定非功能区域的位置和形状,这些区域不应显示内容。 要确定这些屏幕缺口区域是否存在及其位置,使用 getDisplayCutout() 函数。
1 |
|
Android 10.0
- Scoped Storage(分区存储)
- 特定目录(App-specific),使用getExternalFilesDir(String type)或 getExternalCacheDir()方法访问。无需权限,且卸载应用时会自动删除。
- 照片、视频、音频这类媒体文件。使用MediaStore 访问,访问其他应用的媒体文件时需要READ_EXTERNAL_STORAGE权限。
- 其他目录,使用存储访问框架SAF(Storage Access Framwork)
权限变化
后台启动 Activity 的限制
简单解释就是应用处于后台时,无法启动Activity。因为此项行为变更适用于在 Android 10 上运行的所有应用,所以这一限制导致最明显的问题就是点击推送信息时,有些应用无法进行正常的跳转(具体的实现问题导致)。所以针对这类问题,全屏 intent,注意设置最高优先级和添加USE_FULL_SCREEN_INTENT权限,这是一个普通权限。比如微信来语音或者视频通话时,弹出的接听页面就是使用这一功能。
Android11.0
- 强制执行分区存储