
1首先,需要在清单文件中声明一个provider,如下:
<provider
android:name="androidsupportv4contentFileProvider"
android:authorities="comandroiddemofileProvider" // 名字,这个可以自行设置,通常都设置为包名fileProvider
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="androidsupportFILE_PROVIDER_PATHS"
android:resource="@xml/camera_path" /> // 在res下创建xml文件夹
</provider>
之所以需要声明,是因为FileProvider是身为Android四大组件之一的ContentProvider的子类,因此需要在清单文件中声明。
2刚才的声明的最后一行,看到了一个xml文件。这个文件的作用是为FileProvider提供可以暴露的路径,一旦一个路径在文件中被声明,那么就可以被FileProvider提供。下面看一下这个xml文件中的内容:
<xml version="10" encoding="utf-8"><paths>
<external-path path="Demo/" name="Camera" /> // 外部存储,本文案例用的就是这个,注意这里的path就是共享的路径(我前面设置的文件路径就是外部存储下的Demo文件夹),name代表使用这个字段去访问真实的文件路径
// 以下是path可以设置的其他根节点路径 <root-path/> // 设备根目录,等同于直接new File("/") <files-path/> // 内部存储空间应用私有目录下的files/ 目录,等同于ContextgetFilesDir() 所获取的目录路径 <cache-path/> // 内部存储空间应用私有目录下的cache/ 目录,等同于ContextgetCacheDir() 所获取的目录路径 <external-files-path> // 外部存储空间应用私有目录下的files/ 目录,等同于ContextgetExternalFilesDir(null) 所获取的目录路径 <external-cache-path> // 外部存储空间应用私有目录下的cache/ 目录,等同于ContextgetExternalCacheDir()</paths>
应该很多朋友好奇为什么要将路径写到这么一个xml文件里。因为我们现在使用FileProvider来提供这个文件,而FileProvider是ContentProvider的子类,它用content:// Uri 代替了 file:/// Uri。因此需要通过path以及name一起来供FileProvider来找到文件的位置。这样也更加安全的向第三方程序提供文件内容了。
3接下来,就来看看FileProvider类是如何帮助我们来调用系统相机的:
private void takePhoto7() {
Intent intent = new Intent(MediaStoreACTION_IMAGE_CAPTURE);
if (intentresolveActivity(thisgetPackageManager()) != null) {
File file = new File(getCameraSavePath());
Uri uri = FileProvidergetUriForFile(this, "comandroiddemofileProvider", file); // 主要就是这行代码,通过FileProvider获取文件的uri
intentputExtra(MediaStoreEXTRA_OUTPUT, uri);
thisstartActivityForResult(intent, 1000);
}
}
getUriFromFile方法中的第二个参数就是我们在清单文件中声明的provider的authorities。(一定要一样)
4在70的手机上运行后,就会发现成功的调用了系统的相机并实现了拍照。同时,可以打印出uri。我这个案例中的uri为:
content://comandroiddemofileProvider/Camera/Camerapng
目前实现一键分享功能的方式有两种:
1需要集成第三方官方SDK包,在获得官方授权后调用其API来完成一键分享功能,例如使用友盟分享等
优点:无缝集成,功能多
缺点:需要集成官方的SDK包并通过申请官方的授权才可进行开发
2不需要使用任何第三方SDK包,可以直接调起实现了分享功能的应用的activity来进行分享
优点:不需要使用任何第三方SDK包和申请官方授权
缺点:需要手机安装你需要分享的应用(这一点非常重要,一开始测试的时候一直不成功,提示“没有应用可执行此 *** 作”,后来找了很久才发现是我手机没有安装相对应的应用,这也是不好方便的地方)
Data URL 早在 1995 年就被提出,那个时候有很多个版本的 Data URL Schema 定义陆续出现在 VRML 之中,随后不久,其中的一个版本被提上了议案——将它做个一个嵌入式的资源放置在 HTML 语言之中。从 RFC 文档定稿的时间来看(1998年),它是一个很受欢迎的发明。
Data URIs 定义的内容可以作为小文件被插入到其他文档之中。URI 是 uniform resource identifier 的缩写,它定义了接受内容的协议以及附带的相关内容,如果附带的相关内容是一个地址,那么此时的 URI 也是一个 URL (uniform resource locator),如:
ftp://101110/path/to/filenameext
>
首先你获取到路径的字符串,然后分割就行了。
String a = "/test/aaaa/bbbtxt";
String b = asubstring(alastIndexOf("/") + 1, alength());
Systemoutprintln(b);
这样之后,b字符串就是你所需要的。
这样可以把sd卡中全部显示出来,但是我想只把其中某个文件夹里面的照片显示出来。 Uri uri = MediaStoreImagesMediaEXTERNAL_CONTENT_URI; 额,有点想不明白的是,你既然已经知道文件夹的路径了,直接拼接就行了呀
GitHub 项目地址:LocalShare-master
直接上图,这是一个典型的调用系统原生分享场景下的界面,相信大家应该都很熟悉。
那下面说一下遇到的一些问题,特别针对是 70 以后的系统,以及兼容一些主流 app 时遇到的坑。
前面说到分享文件时需要知道文件的类型,不然的指定类型为 / ,这样分享到某些 App 会因为无法判断文件类型而导致失败,所以最好先根据文件路径获取其文件类型。
使用这种方法获取文件类型,一定要注意 ContentResolver 获取返回为 null 的情况,不然空指针异常的崩溃率可能会让你笑不出来。实际测试中,发现在某些国产机型下,这个方法可以说直接是不可用,查询返回一直都是空,所以单纯依赖这一个方法会很不可靠。具体问题原因请看: What causes Android's ContentResolverquery() to return null
下面按照第二条思路,按照文件头信息简单实现一个获取文件类型的例子:
// 获取文件Uri
要向在 MediaStore 中查询到文件,要不就是通知媒体库更新查询或则往里面插入一条新记录(会比较耗时)
可以参考我的另外一篇文章: Android 系统原生 API 实现分享功能(2)
参考: >
URI是统一资源标识符(Uniform Resource Identifier) 的意思,它的作用是根据这个URI找到某个资源文件,基本格式如: file:///sdcard/tempjpg(就是根据你提供的例子生成的一个路径)
ContentProvider是程序间共享数据的,它也需要生成URI供别的程序调用,格式如:
content:///StudentDB/student/name,以后你在别的程序想访问另一个程序里的数据库,就可以用这个URI去访问了,而不用进行数据库连接的 *** 作,非常方便
URL显得很宏观,是网络资源定位的,而URI是应用程序内部或之间定位
以上就是关于android 如何保证fileprovider一致全部的内容,包括:android 如何保证fileprovider一致、Android分享图片和视频失败,怎么办、怎样用前端查看工具才能找到网页里某部分内容的uri等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)