我尝试使用共享 Intent 从我的应用中导出位图,而不为临时位置保存文件。我发现的所有例子都是两步的 1) 保存到 SD 卡并为该文件创建 Uri 2) 以此 Uri 开始 Intent
是否可以在不需要 WRITE_EXTERNAL_STORAGE 权限的情况下保存文件 [然后将其删除]?如何寻址没有外部存储的设备?
最佳答案
我遇到了同样的问题。我不想要求读取和写入外部存储权限。此外,当手机没有 SD 卡或卡被卸载时,有时会出现问题。
以下方法使用 ContentProvider调用FileProvider .从技术上讲,您仍然在共享之前保存位图(在内部存储中),但您不需要请求任何权限。此外,每次您共享位图时,图像文件都会被覆盖。并且由于它在内部缓存中,当用户卸载应用程序时它会被删除。所以在我看来,这与不保存图像一样好。这种方法也比将其保存到外部存储更安全。
文档非常好(请参阅下面的进一步阅读),但有些部分有点棘手。这是对我有用的摘要。
在 Manifest 中设置 FileProvider
<manifest>
...
<application>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
...
</application>
</manifest>
将 com.example.myapp
替换为您的应用程序包名称。
创建 res/xml/filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="shared_images" path="images/"/>
</paths>
这告诉 FileProvider 从哪里获取要共享的文件(在这种情况下使用缓存目录)。
将图像保存到内部存储
// save bitmap to cache directory
try {
File cachePath = new File(context.getCacheDir(), "images");
cachePath.mkdirs(); // don't forget to make the directory
FileOutputStream stream = new FileOutputStream(cachePath + "/image.png"); // overwrites this image every time
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
分享图片
File imagePath = new File(context.getCacheDir(), "images");
File newFile = new File(imagePath, "image.png");
Uri contentUri = FileProvider.getUriForFile(context, "com.example.myapp.fileprovider", newFile);
if (contentUri != null) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // temp permission for receiving app to read this file
shareIntent.setDataAndType(contentUri, getContentResolver().getType(contentUri));
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
startActivity(Intent.createChooser(shareIntent, "Choose an app"));
}
进一步阅读
关于位图的 Android 共享 Intent - 是否可以在共享之前不保存它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9049143/