6.0 Marshmallow 23
6.0 动态申请权限
private void checkAppPermission() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)//
{
//伪代码
/*ArrayList permissons =new ArrayList();
permissons.add(Manifest.permission.RECORD_AUDIO);
permissons.add(Manifest.permission.READ_EXTERNAL_STORAGE);
permissons.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
permissons.add(Manifest.permission.CAMERA);*/
//通过ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED判断相关权限是否允许
//若尚未允许则ActivityCompat.requestPermissions(activity, permissions.toArray(new String[permissions.size()]), permissionRequestCode);
//int requestCode=0x00000001;
}
}
6.0 位置权限
Android6.0之后,Wifi的使用更加严格。需要动态获取LOCATION权限,如果还想获取Wifi列表的话还需要打开GPS(位置信息)。
蓝牙扫描也需要位置权限。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
7.0 Nougat 24-25
7.0 应用间共享文件
https://blog.csdn.net/lmj623565791/article/details/72859156
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。
同样的,官网也给出了解决方案:
要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider 类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。
去AndroidManifest.xml声明provider,provider里边有meta-data属性,里边需要指向设有子节点一个xml文件。
核心代码FileProvider.getUriForFile(this, "com.zhy.android7.fileprovider", file);
7.0 PopupWindow位置不正确
代码来源:https://blog.csdn.net/qq_17766199/article/details/77404712
if (Build.VERSION.SDK_INT >= 24) { // Android 7.x中,PopupWindow高度为match_parent时,会出现兼容性问题,需要处理兼容性
int[] location = new int[2]; // 记录anchor在屏幕中的位置
anchor.getLocationOnScreen(location);
int offsetY = location[1] + anchor.getHeight();
if (Build.VERSION.SDK_INT >= 25) { // Android 7.1 ,8.0中,PopupWindow高度为 match_parent 时,会占据整个屏幕
// 故而需要在 Android 7.1上再做特殊处理
int screenHeight = ScreenUtils.getScreenHeight(context); // 获取屏幕高度
popupWindow.setHeight(screenHeight - offsetY); // 重新设置 PopupWindow 的高度
}
popupWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, 0, offsetY);
} else {
popupWindow.showAsDropDown(anchor);
}
7.0 三个广播被禁止监听或发送
在后台时不再能接收到 CONNECTIVITY_CHANGE 广播,前台不影响。
不能发送或是接收新增图片(ACTION_NEW_PICTURE)和新增视频(ACTION_NEW_VIDEO) 的广播。
8.0 Oreo 26-27
8.0 安装apk
安卓8.0去除了“允许未知来源”选项,如果apk里边有安装apk的功能(如应用更新),需用canRequestPackageInstalls()
查询是否有此权限,没有的话用Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES
这个action引导用户到安装未知来源应用界面去授权。
代码示例来源:https://blog.csdn.net/qq_17766199/article/details/80965631
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();
}
}
8.0广播
静态注册广播 - 在AndroidManifest.xml中设置,程序不用启动亦可接收。 典型代表:很多开机启动的APP,都是接收开机启动广播带起服务的。
动态注册广播 - 代码中注册广播,程序未启动时,无法接收广播。 、
典型代表:Go短信,将Go短信强行停止,Go短信无法接收短信。
静态广播无法清单注册,动态的可以。
Google官方声明:从android 8.0(API26)开始,对清单文件中静态注册广播接收者增加了限制,建议大家不要在清单文件中静态注册广播接收者,改为动态注册。当然,如果你还是想用静态注册的方式也是有方法的,Intent里添加Component参数可实现。
8.0通知权限Notification
Android 8.0之后通知权限默认都是关闭的,无法默认开启以及通过程序去主动开启,需要程序员读取权限开启情况,然后提示用户去开启。
代码来源:https://blog.csdn.net/yinhaide/article/details/103295050
/**
* 判断通知权限是否开启
* @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;
}
}
//前往设置开启权限
/**
* 打开设置页面打开权限
*
* @param activity activity
* @param requestCode 这里的requestCode和onActivityResult中requestCode要一致
*/
public static void startSettingActivity(@NonNull Activity activity, int requestCode) {
try {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + activity.getPackageName()));
intent.addCategory(Intent.CATEGORY_DEFAULT);
activity.startActivityForResult(intent, requestCode);
} catch (Exception e) {
e.printStackTrace();
}
}
————————————————
版权声明:本文为CSDN博主「尹海德」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yinhaide/article/details/103295050
9.0 Pie 28
自 Android 6 发布,就移除了对 Apache HTTP 客户端的支持,而推荐改用 HttpURLConnection 类,因为它可以通过透明压缩和响应缓存减少网络使用,并可最大限度降低耗电量
10.0 Q 29
最大的变化是用户隐私权
10.0 存储权限
Android Q 在外部存储设备中为每个应用提供了一个“隔离存储沙盒”(例如 /sdcard)。任何其他应用都无法直接访问您应用的沙盒文件。由于文件是您应用的私有文件,因此您不再需要任何权限即可在外部存储设备中访问和保存自己的文件。此变更可让您更轻松地保证用户文件的隐私性,并有助于减少应用所需的权限数量。
·访问自己程序的文件,不需要请求权限,取消了READ_EXTERNAL_STORAGE
和 WRITE_EXTERNAL_STORAGE
权限
·访问沙盒外的媒体共享文件,需申请新的媒体权限,READ_MEDIA_IMAGES
,READ_MEDIA_AUDIO
和READ_MEDIA_IMAGES
。
·