targetSdkVersion 从23(6.0) 升级到 26(8.0) 适配记录
1. Android 7.0 适配
主要适配内容
1. FileProvider
在官方7.0的以上的系统中,尝试传递 file://URI可能会触发FileUriExposedException
可能的应用场景: 例如 拍照获取图片,图片裁剪等 ,官方也给出了适配方案,那么就是
使用fileProvider
1.1 FileProvider声明
1. 首先在清单文件中注册 provider
1 2 3 4 5 6 7 8 9
| <provider android:name="android.support.v4.content.FileProvider" android:authorities="${packageName}.fileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/nt_file_paths" /> </provider>
|
2. 在res/xml 新建 nt_file_paths.xml 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?xml version="1.0" encoding="utf-8"?> <paths> <external-path name="external_storage_root" path="." />
<cache-path name="cache" path="." />
<external-cache-path name="name" path="path" />
</paths>
|
以上是FileProvider的声明,以上声明了我们要使用 sdcard下所有目录,cache所有目录 ,具体请查阅 官网文档
1.2 FileProvider的使用
1. 创建了工具类方便uri的转换
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 27 28 29 30 31 32 33 34 35
| /** * * 适配android 7.0 N * * */ public class AndroidNCompat {
public static Uri transform(Context context,Uri origin){
return isAndroidN() ? FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", new File(origin.getPath())) : origin; }
public static Uri transform(Context context,File file) {
return isAndroidN() ? FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", file) : Uri.fromFile(file); }
public static Uri transform(Context context,String path) { return transform(context,new File(path)); }
public static boolean isAndroidN() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N; }
}
|
2. 就以调用系统相册进行图片裁剪为例
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 27 28 29
| public static void cropImageFile(Activity activity, Uri inputUri, Uri outputUri, int length, int requestCode) {
inputUri = AndroidNCompat.transform(activity, inputUri);
// outputUri = AndroidNCompat.transform(activity, outputUri);
activity.grantUriPermission(activity.getPackageName(),inputUri,Intent.FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION); activity.grantUriPermission(activity.getPackageName(),outputUri,Intent.FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);
Intent intent = new Intent("com.android.camera.action.CROP");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setDataAndType(inputUri, "image/*"); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", length); intent.putExtra("outputY", length); intent.putExtra("scale", true); intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri); intent.putExtra("return-data", false); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); activity.startActivityForResult(intent, requestCode); }
|
2. Android 8.0 适配
1. 本文主要说 通知栏,为了更好的管理通知,google推出了channel的概念,更方便用于进行更精细化的通知管理。
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 27 28 29 30 31 32 33
| public static void sendSimpleNotification2(Context context) {
String id = "channel_001"; String name = "name";
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Notification.Builder notificationBuilder = new Notification.Builder(context);
//重点 if (AndroidOCompat.isAndroidO()) {
NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(mChannel);
notificationBuilder.setChannelId(id); }
notificationBuilder .setContentTitle("活动11") .setContentText("您有一项新活动") .setSmallIcon(R.drawable.ic_launcher);
notificationManager.notify(1, notificationBuilder.build()); }
|
通知的适配比较简单,重点关注 isAndroidO 方法即可,主要在我们对于项目中已有的通知进行排查
2. 主题的 Activity 设置屏幕方向
针对 8.0 的应用,设置了透明主题的Activity,再设置屏幕方向, 会抛出一下异常信息,
1 2 3
| java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
|
例如 activity 做了如下配置:
解决方案: 去掉其中一个
参考文档列表 :
https://developer.android.com/about/versions/nougat/android-7.0
https://developer.android.com/about/versions/nougat/android-8.0