Android M 6.0
增加了运行时的权限申请
Android N 7.0
强制执行StrictMode API,Intent的Uri中scheme
不能为file
类型。如果要共享文件,需要使用content://
类型的data
。如果要共享文件,则使用FileProvider。
官方FileProvider说明
官方是这么说明FileProvider的:
FileProvider是ContentProvider的一个特殊子类,方便了应用间的安全的应用内文件共享,通过创建一个
content://
的Uri而不是一个file://
类型的Uri。
使用FileProvider需要经过以下的几个步骤:
- 声明一个FileProvider
- 确定可用的文件
- 获取文件的Uri
- 为Uri授予临时权限
- 把Uri提供给其他应用
官方说明:在授权的时候,需要注意的是如果设备的运行API级别位于Android 4.1 (API Level 16)与Android 5.1(API Level 22)之间,需要创建一个ClipData对象,并为这个ClipData对象授予权限
1 | shareContentIntent.setClipData(ClipData.newRawUri("", contentUri)); |
Android O 8.0
Android 8.0引入了通知Channel,允许为要显示的每种通知类型创建用户可自定义的渠道。
后台限制执行
现在,在Manifest里面注册的广播接收器无法在后台使用。
未知软件源限制
Android 8.0移除了“允许未知来源”的开关。如果想安装应用,则需要申请权限
1 | <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> |
注意:这里申请权限需要跳转到“允许安装未知应用”界面进行授权
1 | Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES); |
Android P 9.0
Http请求失败
9.0中的默认禁止了Http请求,需要改用Https。可以添加网络配置:
1 |
|
然后在Manifest中声明:
1 | android:networkSecurityConfig="network_security_config" |
可以指定特定域名:
1 |
|
前台服务
想创建前台服务,需要申请FOREGROUND_SERVICE权限
设备序列号
在 Android 9 中,调用Build.SERIAL 会始终返回 UNKNOWN 以保护用户的隐私。如果你的应用需要访问设备的硬件序列号,那么需要先请求 READ_PHONE_STATE 权限,然后调用 Build.getSerial
Android Q 10
文件的存储
Android 10的文件存储机制改为了沙盒模式,只能访问自己目录下的文件和公共媒体文件,但是10以下的机型还是使用的老式的文件存储方式。
应用私有目录
应用的外部私有目录对应/Android/data/package_name/
,内部对应了/data/data/package_name
。应用的私有目录文件访问方式与之前的版本保持一致,不需要改动。
共享目录
包含媒体文件、文档以及其他文件。
- 共享目录需要通过MediaStore API或者Storage Access Framework的方式访问。
- MediaStore API在共享目录下创建文件或者访问应用自己创建的文件,是不需要申请存储权限的。
- MediaStore API访问其他应用在共享目录下创建的文件,需要申请存储权限,否则通过ContentResolver查询不到文件的Uri。
- MediaStore API不能访问其他应用创建的非媒体文件,如pdf、office、doc、txt等,只能通过Storage Access Framework方式访问。
如果应用还未完成适配工作,可以暂时让应用以兼容模式运行,需要在Manifest中声明:
1 | android:requestLegacyExternalStorage="true" |
然后在代码中判断是否是兼容模式:
1 | Environment.isExternalStorageLegacy() |
存储访问框架
- 调用存储相关操作的Intent;
- 用户看到系统选择器,供其浏览文档提供其并选择将执行存储文件相关的位置或文档;
- 应用获得对代表用户所选位置或文档的URI的读写访问权限。
但是发现一个不方便的地方:如果采用Storage Access Framework的话,保存文件的时候只能通过打开窗口来选择保存的地方,不能直接在后台完成所有操作。
如果是在10.0之前的话,应该可以直接通过访问文件来读写文件,只要获取了写权限。但是现在10之后,不需要写权限了,各个应用是拥有沙箱机制的。
定位权限
如果需要使用后台位置权限,则需要声明新的权限ACCESS_BACKGROUND_LOCATION
。
媒体文件位置权限
图片之类的文件会带有位置信息,而这个信息是敏感的。在Android 10之后如果要访问媒体位置,则需要声明ACCESS_MEDIA_LOCATION
权限。
Android R 11
分区存储
从Android 11开始执行强制分区存储机制,之前Android 10中声明的android:requestLegacyExternalStorage="true"
已经不起作用了。
另外,Android 11允许使用除了MediaStore API之外的API通过文件路径直接访问存储空间中的媒体文件,包括:
- File API
- 原生库,如fopen()
单次权限授予
就是短时间内授予用户权限。
请求位置权限
Android 11中取消了“始终允许”这一选项,也就是不会授予后台访问位置权限。建议递增位置权限请求,比如先请求前台的权限,再在某一需要的时候请求后台权限。
软件包可见性
新特性,用于限制其他软件获取用户当前安装的软件信息。
前台服务类型
如果需要在前台访问位置信息,则需要在Manifest中声明相应的前台服务类型。
权限自动重置
如果用户的应用经过数个月的时间没有使用的话,那么系统就会自动清除该应用的运行时数据来保护用户的隐私。
读取手机号
如果要读取手机号的话,需要在Manifest中声明READ_PHONE_STATE
权限。