val bd: BitmapDrawable = drawable as BitmapDrawable
val bitmap = bd.bitmap
FilesUtils.getInstance().saveBitmap(bitmap, "naixiao-1122.jpg")
val filePath = FilesUtils.getInstance().sdpath + "naixiao-1122.jpg"
YYLogUtils.w("文件原始路径:$filePath")
val uri = FileProvider.getUriForFile(commContext(), "com.guadou.kt_demo.fileprovider", File(filePath))
YYLogUtils.w("打印Uri:$uri")
//到系统中找打开对应的文件
openFile(filePath, uri)
}
private fun openFile(path: String, uri: Uri) {
//取得文件扩展名
val extension: String = path.substring(path.lastIndexOf(“.”) + 1)
//通过扩展名找到mimeType
val mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
YYLogUtils.w("mimeType: $mimeType")
try {
//构造Intent,启动意图,交由系统处理
startActivity(Intent().apply {
//临时赋予读写权限
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
//表示用其它应用打开
action = Intent.ACTION_VIEW
//给Intent 赋值
setDataAndType(uri, mimeType)
})
} catch (e: Exception) {
e.printStackTrace()
YYLogUtils.e("不能打开这种类型的文件")
}
}
很简单的一个例子,我们把drawable中的一个图片,保存到我们私有沙盒目录中,目录为
文件原始路径:/storage/emulated/0/Android/data/com.guadou.kt\_demo/cache/pos/naixiao-1122.jpg
我们通过 FileProvider 拿到 content://开头的uri路径。然后通过Intent匹配找到对于的第三方App来接收。
那么打印就如下:
打印Uri:content://com.guadou.kt\_demo.fileprovider/external\_app\_cache/pos/naixiao-1122.jpg
content 是 scheme。
com.guadou.kt\_demo.fileprovider 即为我们在清单文件中定义的 authorities,即是我们的FileProvider的唯一表示,在接收的时候作为host。
这样封装之后,当其他的App收到这个Uri就无法从这些信息得知我们的文件的真实路径,相对有安全保障。
其他场景中,比如沙盒中的Apk文件想要安装,也是一样的流程,我们需要赋予读写权限,然后设置DataAndType即可。代码的注释很详细,大家可以参考参考。
此时我们都是发送了一个Intent,让系统自己去匹配符合条件的Activity。那有没有可能我们自己做一个App去匹配它。
这… 好像还真行。
### 二、能不能自定义接收文件?
其实我们仿造系统的App的做法,我们在自定义的Activity中加入指定Filter即可,比如这里我需要接收图片,那么我定义如下的 intent-filter:
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ReceiveImageActivity"
android:exported="true">
<intent-filter>
<action android:name=