我试图传递位于我的应用的res/raw
目录中的图片以及共享意图。
我按照FileProvider docs中描述的流程进行操作,这是我的代码:
AndroidManifest.xml
<application ...>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.myapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/paths" />
</provider>
</application>
res/xml/paths.xml
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="shared" path="./"/>
</paths>
我的活动中的代码:
String shareToPackage = ...
File imageFile = new File(context.getFilesDir().getPath() + "/image");
if (!imageFile.exists()) { // image isn't in the files dir, copy from the res/raw
final InputStream inputStream = context.getResources().openRawResource(R.raw.my_image);
final FileOutputStream outputStream = context.openFileOutput("image", Context.MODE_PRIVATE);
byte buf[] = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
outputStream.close();
inputStream.close();
imageFile = new File(context.getFilesDir().getPath() + "/image");
}
if (!imageFile.exists()) {
throw new IOException("couldn't find file");
}
final Uri uri = Uri.fromFile(imageFile);
context.grantUriPermission(shareToPackage, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
final Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/png");
intent.putExtra(Intent.EXTRA_TEXT, "here's the image");
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setPackage(shareToPackage);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
以上版本不起作用,因为我在其他应用中获得的文件无法访问:
java.io.FileNotFoundException:FILE_PATH:open failed:EACCES (许可被拒绝)
知道我在这里做错了吗? 感谢。
答案 0 :(得分:2)
删除path
中的<files-path>
属性,因为此处不需要getFilesDir()
。
创建File
对象时不要使用字符串连接。替换:
new File(context.getFilesDir().getPath() + "/image.png");
使用:
new File(context.getFilesDir().getPath(), "image.png");
最重要的是,请勿使用Uri.fromFile()
。 Use FileProvider.getUriForFile()
。目前,您正在完成所有这些工作以设置FileProvider
,然后您不会使用FileProvider
将内容提供给其他应用。
或者,摆脱所有这些,以及use my StreamProvider
,它可以直接为原始资源提供服务。
或者,直接编写自己的ContentProvider
服务原始资源。
答案 1 :(得分:0)
@ nitzan-tomer,见https://stackoverflow.com/a/33031091/966789
什么是运行时权限?
借助Android 6.0 Marshmallow,Google引入了一种新的权限模型,允许用户更好地理解应用程序可能要求特定权限的原因。现在,系统会提示用户在应用程序使用期间必要时接受权限,而不是用户在安装时盲目接受所有权限。