android版本适配

371 阅读6分钟

一操作系统和targetSdkVersion对应关系

Android操作系统版本与对应的targetSdkVersion。targetSdkVersion的理解:大于项目targetSdkVersion的系统版本系统适配,小于等于targetSdkVersion的变动开发者自己适配,这种方式可以让未来系统兼容几年前开发的app,能运行。投机者想,targetSdkVersion改小,一劳永逸,但是应用市场上架要求不答应,除非你的应用不上架,否则,还得学适配。

二6.0适配

android 6.0 动态权限,每个用到的地方都要请求,用户可能从设置中关闭权限

二7.0适配

android7.0共享文件

三8.0适配

1.明确申请使用权限

2.通知分类适配

3.悬浮窗适配

4.安装未知应用

5.应用图标

四9.0适配

网络请求http适配

startForegroundService需要清单文件写前台服务权限

不能在非Activity 环境中启动 Activity,解决方法就是 Intent 中添加标志FLAG_ACTIVITY_NEW_TASK

刘海屏适配

五10.0适配

1分区存储

android10之前,很多开发者一股脑把文件扔到SD卡,SD卡文件一团乱,应用卸载了,文件还存在,google忍不了不懂规则的开发者,搞出一个分区储存。

10.0之前关于文件路径和权限:

 sp中保存数据,会在InternalStorage(内部储存)目录data/data/youpackage/shared_prefs/xxx.xml创建文件------仅能自己读写不需要读写权限

sqlite中保存数据,会在InternalStorage(内部储存)目录data/data/youpackage/databases/xxx.db创建文件 ---------仅能自己读写不需要读写权限

 getFilesDir()中保存文件,会在InternalStorage(内部储存)目录,/data/data/youpackage/files/xxx创建文件--------------仅能自己读写不需要读写权限

getCacheDir()中保存文件,会在InternalStorage(内部储存)目录,/data/data/youpackage/cache/xxx 创建文件-----------仅能自己读写不需要读写权限

getExternalFilesDir(null)中保存文件,会在ExternalStorage(外部储存目录,/sdcard/Android/data/youpackage/files/xxx 创建文件------自己读写不需要读写权限

 getExternalCacheDir()中保存文件,会在ExternalStorage(外部储存)目录,/sdcard/Android/data/youpackage/cache/xxx 创建文件----自己读写不需要读写权限

自身app读写以上6个路径10.0之前和10.0之后一样没有改变,也都不需要权限,系统设置中清空缓存是清空的getCacheDir和getExternalCacheDir所有文件, 清空数据清空的是youpackage下所以文件夹和文件。卸载应用,以上6个路径文件跟随卸载

其他app读写以上6个路径,前四个是绝对私有无法读取(10.0之前和10.0之后一样没有改变),后两个路径 6.0之前不需要动态权限,6.0 到9.0申请动态读写权限就能读写其他app该路径下的文件(读写其他appSD沙盒内文件)。

Environment.getExternalStorageDirectory() 6.0之前不需要动态权限,6.0 到9.0需要申请读写权限就能读写所有公共文件,卸载应用,储存到该位置的文件不会跟随卸载

综上,9.0以前的版本对于ExternalStorage和Environment毫无隐私而言(即便是其他app的沙盒文件,也可以搞到),于是google针对这两类的文件的读写进行了优化。

android10的优化如下:

第一类SD沙盒优化:禁止自身app访问其他app外部存储沙盒(哪怕有读写权限),除非其他app向外部提供FileProvider,同理也禁止其他app访问自身app的外部存储沙盒,除非自身提供FileProvider。

第二类公共目录优化分为三项:

1.自身app读自己保存的图片视频,音频,下载,不需要任何权限,写入这类文件也不需要申请任何权限,但是需要通过内容提供者去读写文件。并且写入的文件类型只能在规定的文件夹下 (否则会抛出异常):

图片(包括照片和屏幕截图),只可以存储在 DCIM/ 和 Pictures/ 目录中。系统将这些文件添加到 MediaStore.Images 数据库表格中。

 视频,只可以存储在 DCIM/、Movies/ 和 Pictures/ 目录中。系统将这些文件添加到 MediaStore.Video 数据库表格中。

音频,只可以存储在 Alarms/、Audiobooks/、Music/、Notifications/、Podcasts/ 和 Ringtones/ 目录中,以及位于 Music/ 或 Movies/ 目录中的音频播放列表中。系统将这些文件添加到 MediaStore.Audio 数据库表格中。

下载的文件,只可以存储在 Download/ 目录中。在搭载 Android 10(API 级别 29)及更高版本的设备上,这些文件存储在 MediaStore.Downloads 表格中。此表格在 Android 9(API 级别 28)及更低版本中不可用

2,自身app读其他app保存的图片视频,音频,需要申请的权限,在通过内容提供者去读文件。

3, 自身app读其他app保存的下载(PDF,TXT等),只能通过系统框架读取

4,读取 Exif 元数据,需要申请媒体位置权限(没搞懂)

官方文档地址

到了这里,我们仅仅明确了不同情况的访问方式和是否需要请求权限,具体到适配代码,就需要按照情况来处理。

图片写入公共目录

读取公共目录图片(记得如果读取的是不是自己下载的,记得申请权限哦~)

视频写入公共目录

读取公共目录视频(记得如果读取的是不是自己下载的,记得申请权限哦~)

音频写入公共目录

读取公共目录音频(记得如果读取的是不是自己下载的,记得申请权限哦~)

下载写入公共目录

读取公共目录下载(记得如果读取的是不是自己下载的,记得使用SAF哦~)

2.后台定位权限限制(官方更加推荐前台服务去获取定位)

3.蓝牙申请定位权限变更

4.更改读取DeviceId时使用的与电话相关的权限。原来的READ_PHONE_STATE权限不管用了,需要READ_PRIVILEGED_PHONE_STATE权限才行。并且此权限是系统权限。我们的app是获取不到的,这项改动表示第三方应用无法获取Device ID这类唯一标识。具体变更:

TelephonyManager

我们在日常开发中一般是获取设备getDeviceId()方法,android10之后我们可以获取android_id或者自己生成一个uuid

5.后台app禁止弹出页面,解决办法

六 11适配

1. 更改读取电话号码时使用的与电话相关的权限。原来的READ_PHONE_STATE权限不管用了,需要READ_PHONE_NUMBERS权限才行。

2.继续加强后台获取位置权限

其他适配