Issue
I'm completely new to sharing content between apps, in my app i have images that the user would be able to share, they are stored in drawable for a start but when sharing i write a separate file for the desired image and share it and use fileprovider in the process (i don't even understand what that is). i keep getting all kinds of permession erros like:
java.io.FileNotFoundException: /storage/emulated/0/Documents/image.png: open failed: EACCES (Permission denied)
or
java.io.FileNotFoundException: /storage/emulated/0/image.png: open failed: EPERM (Operation not permitted)
for android 13+ requesting read/write external storage permissions is useless and requesting manage external storage might keep your app off google play store.
so how am i supposed to do this exactly? what's the way?
my current code
val varName = "p_$muhImage"
val resourceId: Int =context.getResources().getIdentifier(varName, "drawable", context.packageName)
val bitmap =BitmapFactory.decodeResource(context.resources, resourceId)
val path= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).toString() + "/image.png"
try {
FileOutputStream(path).use { out ->
bitmap.compress(
Bitmap.CompressFormat.PNG,
100,
out
)
}
} catch (e: IOException) {
e.printStackTrace()
}
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
shareIntent.type = "image/*"
val imageUri = FileProvider.getUriForFile(
context,
context.getPackageName() + ".fileprovider",
File(path)
)
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri)
shareIntent.putExtra(Intent.EXTRA_TITLE, "share")
shareIntent.putExtra(Intent.EXTRA_TEXT, "share")
val chooserIntent = Intent.createChooser(shareIntent, "share")
chooserIntent.putExtra(Intent.EXTRA_TITLE, "share")
chooserIntent.putExtra(Intent.EXTRA_TEXT, "share")
chooserIntent.putExtra(Intent.EXTRA_CONTENT_QUERY, "image/*")
context.startActivity(
Intent.createChooser(
shareIntent,
"share too"
)
);
File(path).deleteOnExit();
manifest permissions
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
manifest provider
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider"/>
</provider>
provider 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>
Solution
Generally speaking, if you want to share content, you do not need to put it on external storage. Internal storage, especially a cache directory like getCacheDir()
on Context
, will suffice, when paired with FileProvider
.
So, I recommend that you:
- Switch to
getCacheDir()
onContext
for where to put your file - Update the
FileProvider
XML metadata to match that - Use
image/png
for the MIME type (the actual MIME type of the content), instead ofimage/*
Answered By - CommonsWare
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.