How to open files (from SD-Card) in gallery - android

I save paths of different jpg. files in a database. These images are partly in the internal memory and partly in the external memory (SD-card).
Now I want to open the pictures in the gallery.
To open images from the internal memory I use the FileProvider, I proceed as follows:
String path = "/storage/emulated/0/Pictures/Meetings/IMG_Testmeeting20180809_225414.jpg";
File image = new File(path);
Uri uri = FileProvider.getUriForFile(getContext(), "com.meetings.martin.provider",image);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "image/*");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
getContext().startActivity(intent);
This is my FileProvider in the AndroidManifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.meetings.martin.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths">
</meta-data>
</provider>
This is content of the file_paths.xml:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
</paths>
This works perfectly..
..but , if I want to open an image, which is located on the SD card, I get the following error message:
Failed to find configured root that contains <path>
I've often read that the FileProvider can not access files on the SD card. But how can I then turn the path into a Uri and open it in the gallery?

I solved it.
I added following line to the path file:
<root-path name="external_files" path="/storage/" />

Related

How do I programmatically open an external folder in Android?

My app downloads an epub file to /external/downloads/{MyFolder}/. I can normally auto-open the file in an e-reader like Play Books. As a fall back, however, in case of no installed e-reader, I want to open the device's default File Browser to MyFolder. On my device, that browser program is called "My Files".
I'm getting an ActivityNotFoundException. How do I programmatically open that File Browser? Ideally to the {MyFolder} location.
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
File file = new File(fileUri.getPath());
File folder = new File(file.getParent());
Uri folderUri = Uri.fromFile(folder);
intent.setDataAndType(folderUri, "resource/folder");
getContext().startActivity(intent);
} catch (Exception e1) {
Toast.makeText(getContext(), "Ebook saving to " + fileUri.getPath(), Toast.LENGTH_LONG).show();
}
For the record, fileUri.toString() for the epub file is "content://media/external/downloads/16143".
.startActivity(intent) throws the exception:
No Activity found to handle Intent { act=android.intent.action.VIEW dat=content://com.{mydomain}.app.provider/root/external/downloads typ=resource/folder flg=0x1 }
I've also attempted to change folderUri declaration to the following, and get similar errors.
final ContentValues v = new ContentValues();
v.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + "/{MyFolder}/");
final ContentResolver r = getContext().getContentResolver();
Uri folderUri = r.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, v);
My AndroidManifest.xml has
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.{mydomain}.app.provider"
android:exported="false"
android:grantUriPermissions="true">
<!-- resource file to create -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
And my file_paths.xml has
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external" path="." />
<external-files-path name="external_files" path="." />
<root-path name="root" path="." />
</paths>
I've also attempted with the paths being "./", and with no root-path element, and it makes no difference.
If you want directly browse the Camera folder in public DCIM folder with the Files app:
String scheme = "content://com.android.externalstorage.documents/document/primary%3ADCIM%2FCamera";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(scheme), "vnd.android.document/root");
startActivity(intent );
I assume you can easily change that for Download/MyFolder.
I think this only works for Android 11+ devices. Please try out.

Unable to sharing image file with other app using FileProvider

I have image list and I want to share image that selected.To do, I have used FileProvider. I'm running app on Android 10. Also I have tried without shareIntent(Intent.EXTRA_STREAM,uri), then app opening only share via dialogs.After not sharing anything just returning the app.
in AndroidManifest.xml;
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_paths" />
</provider>
in paths;
<paths>
<files-path
name="files"
path="/" />
<cache-path
name="cache"
path="/" />
here is the how I used and start intent,
int pos = getAdapterPosition();
File imageFile = new File(imageQuotes.get(pos).getPath());
Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", imageFile);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setDataAndType(uri,"image/*");
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
mContext.startActivity(shareIntent);
When run the app,after I have choosed WhatsApp for ie. My image file sent as a BIN file and not has image preview on whatsapp.
uri is not null and is content://com.scoto.partestestapplication.provider/files/SavedImageQuotes/Partes_1601815401590

How to share Videos to any app using Intent?

Issue: What happens is after sharing the video when i launch the app to check the shared video it shows me error of "Unable to import" and "The video is no longer available".
Android Version: Oreo(8.0)
Code: I am trying with the following code to share videos with other apps using intent:
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("video/*");
share.putExtra(Intent.EXTRA_SUBJECT, "abc");
share.putExtra(Intent.EXTRA_TITLE, "abcd");
File imageFileToShare = new File(Environment.getExternalStorageDirectory() + "/mygallery/" + "airp.mp4");
Uri uri = FileProvider.getUriForFile(Main2Activity.this, "abc.dcf.fileprovider", imageFileToShare);
share.putExtra(Intent.EXTRA_STREAM, uri);
share.setPackage("com.abc.in");
startActivity(Intent.createChooser(share, "Message"));
The above code is working fine to share Images but its not working to share videos.
What i have tried: I have tried by sharing various file types like 3gp, mkv, mp4 but nothing is working out and I have also went through various similar questions but no solution is working in case of videos.
Please help me with this issue and also if there is any alternate way to do so?
You can add this to your OnCreate
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
If that doesn't work for you,
Add Provider to Manifest by doing this
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
Remember to use android:name="androidx.core.content.FileProvider" if you're using androidx
Create a file in xml directory (res/xml) and name provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
Replace
Uri uri = FileProvider.getUriForFile(Main2Activity.this, "abc.dcf.fileprovider", imageFileToShare);
with this
Uri uri = FileProvider.getUriForFile(Main2Activity.this, BuildConfig.APPLICATION_ID + ".provider",imageFileToShare);

android getUriForFile fails for external_files_path

* NEW INFO *
Singlestepping into the FileProvider code, I see that external-files-path is not actually rooted at /storage/emulated/0/ but at /storage/emulated/0/Android/data/com.perinote.perinote/files/. So, I ask the question, how do I share a file in external storage /DCIM?
I'm passing an "external" file to an Intent and getting an "IllegalArgumentException: Failed to find configured root that contains ..." error.
Not sure what's missing. Doing something similar with a "cache" file works.
Here's my provider part of my manifest:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.perinote.image_access"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepaths" />
</provider>
The "filepaths.xml" file:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
path="DCIM/Perinote/" name="images" /> <!-- must be same as ImageData.getPerinoteDirectory -->
</paths>
And the snip of code, where "file" is the file name (without path) in question:
Intent intent = new Intent (Intent.ACTION_SEND);
intent.setType ("plain/text");
intent.putExtra (Intent.EXTRA_EMAIL, new String[] {address});
intent.putExtra (Intent.EXTRA_SUBJECT, subject);
intent.putExtra (Intent.EXTRA_TEXT, body);
Uri uri = FileProvider.getUriForFile (getContext (), "com.perinote.image_access", file);
intent.putExtra (Intent.EXTRA_STREAM, uri);
intent.addFlags (Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags (Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult (intent, ACTIVITY_REQUEST_SEND_EMAIL);
It's failing in getUriForFile().
When I use a file manager app on the device, the file is definitely there, under DCIM/Perinote/
For example, using the debugger, file is "IMG_20171130_204015.jpg".
And opening an explorer window on Windows shows the path
This PC\Moto G (4)\Internal shared storage\DCIM\Perinote
and the file appears in the list below.
You should start with changing <external-files-path to <external-path..

Android: Cannot share image from SD card

I try to share a picture from my SD card.
Class MainActivity.java
Intent shareIntent = new Intent(Intent.ACTION_SEND);
File baseDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
String fileName = "/cats.jpg";
File file = new File(baseDir + fileName);
Uri uri = Uri.fromFile(file);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(shareIntent.createChooser(shareIntent, "Send Picture"));
I add to my Manifest.xml:
uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
The image "cats" is in
MySmartphone\Card\DCIM\cats.jpg
When I start my App, I can choose an application to share my picture. But when I open one, it cannot send or open the image.I got often a toast "not supported" or "error to share picture". I think my uri or file is wrong, but I cannot find my mistake. I have no problem to send text.
My uri:
file:///data/user/0/com.example.jana.showpicture/files/cats.jpg
My file: /storage/emulated/0/cats.jpg
Probably you are building for Android API 24 and above. Since API 24 a new kind of security was added. See:
https://developer.android.com/about/versions/nougat/android-7.0-changes.html#perm
You now need to do a bit more, add this in your AndroidManifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.jana.showpicture.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
/res/xml/provider_paths.xml:
<paths>
<external-path
name="external_files"
path="." />
</paths>
And Java:
Uri uri = FileProvider.getUriForFile(activity,"com.example.jana.showpicture.provider",
file);
shareIntent .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY |
Intent.FLAG_GRANT_READ_URI_PERMISSION);

Categories

Resources