权限更改
随着Android7.0的到来,随之,权限获取也随之更改,因为部分7.0手机就会出现无法下载乃至加载完成后无法安全或者安装失败的问题,因为,我们适配7.0版本是很重要的,不然部分7.0手机就会出现上述问题。
在api23版本开始部分权限需要动态获取,共有9组权限,每组权限中只要有一个权限成功即为全部申请成功,然而7.0也是一样的在下载前需要动态获取文件的读写权限,一定要获取,博主记得华为mate 9就会出现这个问题。关于动态获取权限的问题,稍后会贴博客,或者自行百度。
目录被限制访问
一直以来,在目录及文件的访问保护方面iOS做的是很到位的,如:ios的沙箱机制。但,Android在这方面的保护就有些偏弱了,在Android中应用可以读写手机存储中任何一个目录及文件,这也带来了很多的安全问题。现在Android也在着力解决这一问题。
在Android7.0中为了提高私有文件的安全性,面向 Android N 或更高版本的应用私有目录将被限制访问。对于这个权限的更改开发者需要留意一下改变:
- 私有文件的文件权限不在放权给所有的应用,使用 MODE_WORLD_READABLE 或MODE_WORLD_WRITEABLE 进行的操作将触发 SecurityException。
应对策略:这项权限的变更将意味着你无法通过File API访问手机存储上的数据了,基于File API的一些文件浏览器等也将受到很大的影响,看到这大家是不是惊呆了呢,不过迄今为止,这种限制尚不能完全执行。 应用仍可能使用原生 API 或 File API 来修改它们的私有目录权限。 但是,Android官方强烈反对放宽私有目录的权限。可以看出收起对私有文件的访问权限是Android将来发展的趋势。
- 给其他应用传递 file:// URI 类型的Uri,可能会导致接受者无法访问该路径。 因此,在Android7.0中尝试传递 file:// URI 会触发 FileUriExposedException。
下面讲述如何适配7.0:首先在AndroidManifest.xml中添加一下代码
- <!--此处适配android 7.0-->
- <provider
- android:name="android.support.v4.content.FileProvider"
- android:authorities="${applicationId}.fileprovider"
- android:exported="false"
- android:grantUriPermissions="true">
- <meta-data
- android:name="android.support.FILE_PROVIDER_PATHS"
- <span style="color:#cc0000;">android:resource="@xml/file_paths"</span>/>
- </provider>
其中红色代码部分是引用xml文件,文件名为:file_paths。然后我们如果在res下没有xml文件夹的话就新建一个xml文件夹,在xml文件夹下新建file_paths的xml资源文件。里面添加如下代码
- <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
- <paths>
- <external-path
- name="files_root"
- path="Android/data/你的包名/" />
- <external-path
- name="external_storage_root"
- path="." />
- </paths></span>
- <span style="font-size:14px;">Intent i = new Intent(Intent.ACTION_VIEW);
- if (Build.VERSION.SDK_INT >= 24) { //适配安卓7.0
- i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_ACTIVITY_NEW_TASK);
- Uri apkFileUri = FileProvider.getUriForFile(mContext.getApplicationContext(),
- mContext.getPackageName()+".fileprovider", apkfile);
- i.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
- } else {
- i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
- "application/vnd.android.package-archive");// File.toString()会返回路径信息
- }
- mContext.startActivity(i);</span>