I'm trying to share file via intent for instagram , but i realized that on API 24++, i can't just share the URI to other app without giving it permission.
Following this https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en tutorial, i have set the provider and provide path like this :
Manifest
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="myapplication.file_provider"
android:exported="false"
android:grantUriPermissions="true"
tools:node="replace">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
Note: there is `tools:node=replace" to override provider from library RxPaparazzo.
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="files/"/>
</paths>
Code to save bitmap and get uri
public static Uri savePicture(Context context, Bitmap bitmap) {
int cropHeight;
if (bitmap.getHeight() > bitmap.getWidth()) cropHeight = bitmap.getWidth();
else cropHeight = bitmap.getHeight();
bitmap = ThumbnailUtils.extractThumbnail(bitmap, cropHeight, cropHeight, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
context.getString(R.string.app_name)
);
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile = new File(
mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"
);
// Saving the bitmap
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
FileOutputStream stream = new FileOutputStream(mediaFile);
stream.write(out.toByteArray());
stream.close();
} catch (IOException exception) {
exception.printStackTrace();
}
// Mediascanner need to scan for the image saved
Intent mediaScannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri fileContentUri = Uri.fromFile(mediaFile);
mediaScannerIntent.setData(fileContentUri);
context.sendBroadcast(mediaScannerIntent);
return fileContentUri;
}
Composing File Provider Uri
Uri savedBitmap = ImageUtility.savePicture(getContext(), shareBitmap);
File media = new File(savedBitmap.getPath());
Uri contentUri = FileProvider.getUriForFile(getContext(), "myapplication.file_provider", media);
Log Error :
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Pictures/Polfaced/IMG_20170203_155130.jpg
Tried using commonware's StreamProvider but i think the library have different purpose (fixing another type of issue), tried saving file to getFileDirs
instead of Environment.getExternalStoragePublicDirectory
but the image is not saved and getting similiar error/
Change
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="files/"/>
</paths>
to
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="."/>
</paths>
as described in the link you shared above.
The provider below:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="files/"/>
</paths>
will address paths that look like
/storage/emulated/0/files/
but the paths that you are sharing
/storage/emulated/0/Pictures/Polfaced/IMG_20170203_155130.jpg
does not include or starts with:
/storage/emulated/0/files/
To understand what
path="."
does, read the link you shared in detail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With