英文:
Storage sharing with standard apps concept
问题
简要来说:
我的应用程序应该允许用户使用标准应用程序拍摄和显示照片。
这些照片不应该显示在相册中。
在卸载应用程序时,这些照片应该被删除。
我目前的进展是:
因为我想要使用设备的默认相机应用程序,所以我需要使用一个可共享的文件位置来存储文件。
我尝试使用带有调用意图中构建的“Manifest/xml/provider”的“ExternalFilesDir”。
似乎这在与相机应用程序一起使用时有效:
private String mImagePath;
private void takePhoto(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) == null) return;
String filename = "Image" + System.currentTimeMillis();
File dir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File file = null;
try {
file = File.createTempFile(filename, ".jpg", dir);
} catch (Exception ex) {
ex.printStackTrace();
}
if (file == null) return;
mImagePath = file.getAbsolutePath();
Uri uri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, requestcode);
}
这部分似乎有效(由于我的“能力”,我无法检查文件夹,因为Android Studio的“设备文件浏览器”不允许我这样做,真烦!)。
但是,当我尝试显示图片时,所有标准应用程序(画廊、照片等)都会抛出“访问被拒绝”错误消息。
private void displayPhoto{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri contentUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", new File(mImagePath));
intent.setDataAndType(contentUri, "image/*");
startActivity(intent);
}
我的问题是:
- 为什么相机应用程序可以将文件存储在ExternalFilesDir中,但显示应用程序无法从那里读取它?
或者
- 我的代码有什么问题吗?
- 我的应用程序是否可以以某种方式授予显示应用程序访问权限?
- 我还能使用哪些其他方法来实现我的目标?
- 如何在Android Studio或其他工具中浏览ExternalFilesDir的内容?
我不想编写自己的显示代码,因为用户熟悉标准应用程序。
我需要使用minSDKVersion 22。
谢谢您在这里的帮助!
英文:
In short:
My app should let the user take and display photos using the standard apps.
The photos should not show up in the Gallery.
The photos should be removed when the app is de-installed.
What I got so far:
Since I want to use the device's default camera app, I need to use a shareable place for the files.
I tried using 'ExternalFilesDir' with a 'Manifest/xml/provider' contructed Uri in the calling
intent. This seams to work with the camera app:
private String mImagePath;
private void takePhoto(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) == null) return;
String filename="Image" + System.currentTimeMillis();
File dir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File file =null;
try{
file = File.createTempFile(filename,".jpg", dir);
}catch(Exception ex){
ex.printStackTrace();
}
if (file == null) return;
mImagePath =file.getAbsolutePath();
Uri uri = FileProvider.getUriForFile(this,getApplicationContext().getPackageName()+".provider", file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, requestcode);
}
This part seams to work (due to my 'competence' I cannot check the folder since the Android Studio's Device File Eplorer does not let me, grrh!).
But when I try to display the images, all the standard apps (Gallery, Foto etc.) throw an 'access denied' error message.
private void displayPhoto{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri contentUri = FileProvider.getUriForFile(this,getApplicationContext().getPackageName()+".provider", new File(mImagePath));
intent.setDataAndType(contentUri, "image/*");
startActivity(intent);
}
My questions are:
- Why can the camera app store a file in ExternalFilesDir but the
displaying app cannot read it from there?
-or-
- Is there something wrong with my code?
- Can my app somehow grant access to the displaying app?
- What other concept could I use to achieve my targets?
- How can I browse the content of ExternalFilesDir within Android
Studio or another tool?
I do not want to write my own displaying code since the user is familliar with the standard app.
I need to use minSDKVersion 22.
Thanks for helping me here!
答案1
得分: 1
与此同时,经过数小时的努力,我找到了Gallery或其他应用程序显示“访问被拒绝”错误的原因:
除了uri之外,调用方应用程序还必须在调用意图中设置“FLAG_GRANT_READ_URI_PERMISSION”标志。像这样:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(mycontenturi, "image/*");
intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
另外,我发现在fileprovider的XML中只有以下条目起作用:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="Pictures/" />
<external-files-path name="my_images" path="." />
<external-files-path name="camera_image" path="."/>
<external-files-path name="camera_image" path="Pictures/"/>
</paths>
有趣的是:当路径为“.”时,它会创建一个Pictures子目录,而当路径为“Pictures/”时,则不会创建。
英文:
Meanwhile, after hours and hours, I found the reason why Gallery or other apps show the 'access denied' error:
Im addition to the uri the caller app has to set the 'FLAG_GRANT_READ_URI_PERMISSION' flag in the calling intent. Like this:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(mycontenturi, "image/*");
intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
Also I found that the only entries in the fileprovider xml which work are:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="Pictures/" />
<external-files-path name="my_images" path="." />
<external-files-path name="camera_image" path="."/>
<external-files-path name="camera_image" path="Pictures/"/>
</paths>
Funny enough: when path is "." it creates a Pictures subdir and when it says "Pictures/" it doesn't.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论