android7.0 files目录,Android 7.0 FileProvider

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

Android N也已经发布了将近一年了,各大手机厂商陆陆续续也开始更新N了,刚好最近工作中又遇到了需要拍照和选取本地图片的功能,之前写的东西在同事新买的手机上完全不好使,没有办法,也就借机研究了下7.0上的适配问题。

一、问题的发现

虽然很早就知道Android在7.0版本后对文件共享方面有所修改,但一直也没有进行深入的研究,刚好最近自己的产品在同事7.0的手机上拍照和图片选取都有问题。拿过来打出log一看,发现一直报的问题是文件找不到和FileUriExposedException的错误。

那么为什么会出现这类问题呢,Android7.0为了提高私有文件的安全性,启用了一些新的策略机制,使得file://uri类型的文件不能被访问,因此如果还采用以前的文件机制,将会报FileURIExposedException错误。

解决方法

针对此类问题,就需要通过FileProvider来解决了。本文主要来通过调用相机和选取本地图片及裁剪在7.0上的适配,顺便来介绍FileProvider的使用。

官方链接:https://developer.android.com/reference/android/support/v4/content/FileProvider.html

二、FileProvider的使用

1、 在Androidmanifest中声明FileProvider1

2

3

4

5

6

7

8

9

10

11

12

13

14

...

...

android:name="android.support.v4.content.FileProvider"

android:authorities="com.mydomain.fileprovider"

android:exported="false"

android:grantUriPermissions="true">

...

...

name:可以使用系统提供的android.support.v4.content.FileProvider,或者使用自己定义的类的路径。

authorities:所属者,此处无过多限制,最好使用当前包名,或者相关名称即可。在FileProvider使用的过程中会用到。

exported:是否公有(也就是外部能否访问)。

grantUriPermissions:设置为true,你才有权操作文件

2、指定可用文件

FileProvider只能针对预先声明的目录文件生成URI,需要在res/xml建立对应路径文件,并添加paths节点。必须包含一个或者多个如下节点:1

2

3

4

5* 对应Context.getFilesDir()下的路径

* 对应getCacheDir()下的路径

* 对应Environment.getExternalStorageDirectory()下的路径

* 对应Context.getExternalFilesDir(String) Context.getExternalFilesDir(null)下的路径

* 对应Context.getExternalCacheDir()下的路径

属性:name=”name” URI路径。为了提高安全性,name用来隐藏你共享的子目录的名称。

属性:path=”path” 分享对应的子目录的名称。

添加完成后,为声明的FileProvider添加属性1

2

3

4

5

6

7

8

9

android:name="android.support.v4.content.FileProvider"

android:authorities="com.mydomain.fileprovider"

android:exported="false"

android:grantUriPermissions="true">

android:name="android.support.FILE_PROVIDER_PATHS"

android:resource="@xml/file_paths" />

3、生成对应文件路径的URI

为了在不同的APP之间共享文件,我们需要针对文件生成一个URI,可以通过getUriForFile()来实现。1

2

3File imagePath = new File(Context.getFilesDir(), "images");

File newFile = new File(imagePath, "default_image.jpg");

Uri contentUri = getUriForFile(getContext(), "com.mydomain.fileprovider", newFile);

4、给生成的URI赋予临时权限

为了使URI访问不受限制,我们需要针对URI赋予临时权限,否则还会报错,方法如下1

2intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION

| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

官方文档给出的是setFlags(),不过个人建议使用addFlags(),内容包含FLAG_GRANT_READ_URI_PERMISSION(读)或者FLAG_GRANT_WRITE_URI_PERMISSION(写)。

5、完成为另一个APP一共URI

三、拍照保存

URI生成方法1

2

3

4

5

6

7

8

9

10//当然为了适应所有版本,我们做出如下修改

public static Uri getUriForFile(Context context, File file) {

Uri uri;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

uri = FileProvider.getUriForFile(context.getApplicationContext(), "com.mydomain.fileprovider", file);

} else {

uri = Uri.fromFile(file);

}

return uri;

}

相机调取1

2

3

4

5

6

7

8

9

10

11

12

13

14

15/**

* 拍照

*

* @param outputFileUri //照片保存路径

* @param requestCode

* @param activity

*/

public static void takePhoto(File outputFileUri, int requestCode, Activity activity) {

if (activity == null) {

return;

}

Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE")

.putExtra(MediaStore.EXTRA_OUTPUT, getUriForFile(activity, outputFileUri));

activity.startActivityForResult(getImageByCamera, requestCode);//拍照

}

图片裁剪1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21/**

* 裁剪图片

*

* @param orgFile //文件原路径

* @param cropImage //裁剪保存路径

* @param requestCode

* @param activity

*/

public static void cropImage(File orgFile, File cropImage, int requestCode, Activity activity) {

Intent intent = new Intent("com.android.camera.action.CROP");

intent.setDataAndType(getUriForFile(activity, orgFile), "image/*");

intent.putExtra("crop", "true");

intent.putExtra("aspectX", 1);

intent.putExtra("aspectY", 1);

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cropImage));

intent.putExtra("return-data", false);

intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());

//设置权限

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

activity.startActivityForResult(intent, requestCode);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值