一、修改targetSdkVersion为30
将build.gradle的目标版本targetSdkVersion修改为30(Android 11)
targetSdkVersion 30
Android11的改变改变主要影响以Adnroid11 为目标版本的应用(targetSdkVersion>=30才有影响),和所有应用在Android11设备上适配改动(无论targetSdkVersion是多少,只要在Android11设备上运行的应用都有影响)
二、Android11需要适配的地方
1、分区存储
分区存储,将公共区域划分成了不同的集合,并且在媒体文件和其他文档之间建立了清楚的分割。经过划分之后应用不可以随意访问外部存储区中的文件,而只能访问媒体文件。如果想访问包含更多细节数据的其他文档,应用专门向用户申请有关文档的访问权限。
关于分区存储,在Android10就已经推行了,简单的说,就是应用对于文件的读写只能在沙盒环境,也就是属于自己应用的目录里面读写。其他媒体文件可以通过MediaStore进行访问。
但是在android10的时候,Google还是为开发者考虑,留了一手。在targetSdkVersion = 29应用中,设置android:requestLegacyExternalStorage=“true”,就可以不启动分区存储,让以前的文件读取正常使用。但是targetSdkVersion = 30中不行了,强制开启分区存储,设置android:requestLegacyExternalStorage="true"已经无效了。
四种访问文件的方法:
1)应用专属目录
//分区存储空间
val file = File(context.filesDir, filename)//应用专属外部存储空间
val appSpecificExternalDir = File(context.getExternalFilesDir(), filename)
2)访问公共媒体目录文件
val cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, "${MediaStore.MediaColumns.DATE_ADDED} desc")
if (cursor != null) {
while (cursor.moveToNext()) {
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
println("image uri is $uri")
} cursor.close()
}
3)SAF(存储访问框架–Storage Access Framework)
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "image/*"
startActivityForResult(intent, 100)
@RequiresApi(Build.VERSION_CODES.KITKAT)
override fun onActivityResult(requestCode:Int, resultCode:Int, data:Intent ?){
super.onActivityResult(requestCode, resultCode, data)
if (data == null || resultCode != Activity.RESULT_OK) returnif(requestCode == 100) {
val uri = data.dataprintln("image uri is $uri")
}
}
4)获取所有文件权限MANAGE_EXTERNAL_STORAGE(官方不推荐),这个权限是给文件管理类软件、杀毒软件使用的
在清单文件中添加权限,这个权限就是用来获取所有文件的管理权限
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
val intent = Intent()
intent.action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
startActivity(intent)
//判断是否获取MANAGE_EXTERNAL_STORAGE权限:
val isHasStoragePermission= Environment.isExternalStorageManager()
2、应用包可见性
在 Android 11 之前,我们可以通过 PackageManager.getInstalledPackages(0) 获取其他所有应用的包名等信息。
Android 11 为了增加安全性,更好地保护用户的隐私,对应用包的可见性做出了一些改动。
当 targetSdkVersion 为 30 时,如果我们用getPackageInfo(“another.app”,0) 获取其他应用包信息时 ,会出现 NameNotFoundException 的异常。
我们可以在 AndroidMainfest 中添加 来适配特定的使用场景:(该配置相当于是添加应用白名单)
已知想获取的包名:
<queries>
<package android:name="com.test.application1"/>
<package android:name="com.test.application2"/>
<package android:name="com.test.application3"/>
</queries>
3、权限变化
在 Android 11 中,系统为用户的私人数据提供了更多可供选择的授权方式,应用也加大了后台对位置的访问权限限制。
对应摄像头、位置信息和麦克风这几个数据类型,用户可以授予一次性的临时访问权限。
这个一次性权限的生效周期指的是:
应用 Activity 可见期间
应用转为后台后的短时间内
前台服务存活期间
当用户撤销单次授权后,应用进程退出,再次打开之后需要对应用进行重新授权期间
4、位置权限
在Android10 之前,我们通过ACCESSCOARRSELOCATION 或 ACCESSFINELOCATION(精确位置) 配置即可申请前后台位置权限。
Android 11将位置权限分为前台和后台两种权限。前文说的主要是前台权限,授权方式没有变化。应用想要申请后台权限,除了需要在清单文件中额外添加 ACCESSBACKGROUNDLOCATION 权限外,还需要应用主动引导用户到指定页面授权。
Android 11 要求面向 API 级别为 30 的应用使用递增式位置权限请求。任何同时申请前台位置权限 (无论是粗略位置还是精确位置) 和后台位置权限的请求都会被忽略并且报错。文章来源:https://www.toymoban.com/news/detail-762853.html
需要先申请前台位置权限,然后在稍晚些再申请后台位置权限。文章来源地址https://www.toymoban.com/news/detail-762853.html
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />//后台位置权限
到了这里,关于Android11 适配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!