Android target升级

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