近日,谷歌推送了最新的Android 11第二个开发者预览版(Developer Preview 2)更新,而这距离上一个版本已过去了一个月之久。
按照谷歌提供的里程碑列表,从今年2月份起,每月将会发布一个开发者预览版,直至第三季度Android 11最终版本推出。谷歌官方提示广大开发者,尽早开始应用程序兼容性的测试,留更充裕的时间用于后期的适配处理。
图片来自网络
本次新版本主要带来了新的隐私保护措施,用于5G、共享、连接、媒体等方面新的API,另外也有一些用户行为的变更。下面,小编将结合最新的开发者预览版,解读Android 11在第三方移动应用工具中兼容测试及适配,需要注意的要点。
01
存储及隐私的变化
在系统存储上,Android 11将正式使用沙箱模式、存储访问框架限制、媒体文件批量处理。隐私变化的更新,主要围绕“位置”,“相机”,“麦克风”三组权限,在用户选择时增加“仅这次”选项、位置权限选择框中不再显示“始终允许”选项、两次“拒绝”将视为“不再询问”。
图片来自安卓开发者平台官网
02
值得关注的新功能
在第三方移动应用开发中,值得开发者关注的是Android 11引入了“数据访问审核”功能,通知栏增加快速回复图片等媒体以及安全共享大型数据集,并对Android模拟器中的相机支持了扩展。
03
适配及新功能的使用
1)配置Android 11环境
2)沙箱适配要点提示
3)后台位置权限的适配
//targetR,必须先申请FINE OR COARSE LOCATION,然后申请BACKGROUND LOCATION,才能跳转到系统设置页面,
//否则直接申请BACKGROUND LOCATION将无效
//申请数组将android.permission.ACCESS_BACKGROUND_LOCATION、FINE、COARSE和任意权限放一起申请将报错
if (checkSelfPermission("android.permission.ACCESS_FINE_LOCATION") !=PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{"android.permission.ACCESS_FINE_LOCATION"}, 0);
}
else if (checkSelfPermission("android.permission.ACCESS_BACKGROUND_LOCATION") !=
PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{"android.permission.ACCESS_BACKGROUND_LOCATION"}, 0);
}
//target
requestPermissions(new String[]{"android.permission.ACCESS_BACKGROUND_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, 0);
4)多媒体文件的批量操作
List<Uri> list=new ArrayList<>();
list.add(Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString() + File.separator + 261));
list.add(Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString() + File.separator + 262));
PendingIntent p=MediaStore.createTrashRequest(getContentResolver(),list,true);
try {
startIntentSenderForResult(p.getIntentSender(),1,null,0,0,0);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
5)大型数据集的应用间共享
新增BlobStoreManager类,当一个应用下载完某个数据后,可以将该数据共享给指定的包名应用、或者相同签名应用、或者无限制公开,其他应用可以直接读取该数据。
应用A共享数据:
final BlobStoreManager blobStoreManager = ((BlobStoreManager) getSystemService(Context.BLOB_STORE_SERVICE));
MessageDigest md = MessageDigest.getInstance("sha256");
//传输对象
String content = "123abc123!@#";
//有效期
long expireTime = new Date(2020, 4, 1).getTime();
//名称
String label = "label123";
//标签
String tag = "test";
//传输对象sha256摘要
byte[] contentHash = new byte[0];
byte[] contentByte = new byte[0];
contentByte = content.getBytes("utf-8");
contentHash = md.digest(contentByte);
//生成blobhandle,读取者生成的时候必须四项和这里的相同
final BlobHandle blobHandle = BlobHandle.createWithSha256(contentHash,label,expireTime,tag);
//生成本次操作的会话
long sessionId = 0;
try {
sessionId = blobStoreManager.createSession(blobHandle);
} catch (IOException ex) {
ex.printStackTrace();
}
try (BlobStoreManager.Session session = blobStoreManager.openSession(sessionId)) {
try (ParcelFileDescriptor.AutoCloseOutputStream pfd =
new ParcelFileDescriptor.AutoCloseOutputStream(session.openWrite(0, contentByte.length))) {
//写入的对象,他的摘要必须和上文一致,否则报SecurityException
pfd.write(contentByte);
pfd.flush();
//允许公开访问
session.allowPublicAccess();
//或者选择相同签名访问
//session.allowSameSignatureAccess();
//或者选择指定包名访问
//session.allowPackageAccess("com.target.pkg",certificate);
//都不选择,默认仅自己可访问
session.commit(getMainExecutor(), integer-> {
//0成功 1失败
});
}
}
应用B读取数据:
final BlobStoreManager blobStoreManager = ((BlobStoreManager) getSystemService(Context.BLOB_STORE_SERVICE));
MessageDigest md = MessageDigest.getInstance("sha256");
//传输对象
String content = "123abc123!@#";
//有效期
long expireTime = new Date(2020, 4, 1).getTime();
//名称
String label = "label123";
//标签
String tag = "test";
//传输对象sha256摘要
byte[] contentHash = new byte[0];
byte[] contentByte = new byte[0];
contentByte = content.getBytes("utf-8");
contentHash = md.digest(contentByte);
BlobHandle blobHandle = BlobHandle.createWithSha256(contentHash,label,expireTime,tag);
try (ParcelFileDescriptor.AutoCloseInputStream pfd =
new ParcelFileDescriptor.AutoCloseInputStream(blobStoreManager.openBlob(blobHandle))) {
//读取数据
byte[] buffer = new byte[64];
pfd.read(buffer);
}
6)数据访问审核的使用
为了让开发者更便利的的感知到,所开发应用中敏感操作的调用,AppOpsManager中新增类AppOpsCollector,可以在整个应用范围内,包括自己、jar、第三方sdk,注册该监听,当调用需要危险权限的方法时,会触发回调,应用内只能注册一个,后注册覆盖前一个。
使用方式:
AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
appOpsManager.setNotedAppOpsCollector(new AppOpsManager.AppOpsCollector() {
@Override
public void onNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
}
@Override
public void onSelfNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
}
@Override
public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncNotedAppOp){
}
});
注册后,如调用WifiManager的startscan方法将会触发onNoted回调,日志显示fine_location权限被调用。
Android11预览版发布具体执行时间点
目前,Android 11仍然处于预览版本阶段,关于之后版本的更新迭代,MobTech将实时关注谷歌对Android 11发布里程碑,在名为“平台稳定性”的里程碑后,确定适配细节。
关于Android 11公布的新特性及变化,MobTech将持续进行关注,并进行对应的适配,从而保证旗下开发者服务相关SDK产品的用户体验。主要聚焦以下三方面内容:
“平台稳定性”里程碑,意味着Android 11已确定最终的内部和外部API、面向应用的最终行为,以及最终的非SDK 灰名单,可帮助开发者规划的最终测试和发布。
据谷歌官方消息, Android 11预计将在年 6月发布的Beta版2到达“平台稳定性”里程碑。自此以后,不会再有任何会影响应用的变更。因此,谷歌建议所有应用、游戏、SDK、库和游戏引擎开者,将“平台稳定性”里程碑作为规划最终兼容性测试和公开发布的目标。
以上就是小编关于Android 11预览版的适配解读,如咨询相关适配问题,或针对SDK适配问题,有更好解读的朋友,欢迎在底部留言区撩小编~
-END-