I'm trying to save a file as PNG of a canvas where the user can draw something and then call an Intent.ACTION_SEND
so that the user can share it's drawing with other apps.
The code is able to save the file without any problems, but when I try to use the MediaScannerConnection.scanFile()
, the Uri
returned by the function is null
. I'm using the absolute path of the file created, so I can't understand why this is happening.
My class, called BitmapAsyncTask
inherits from AsyncTask
(yes, I know it's deprecated). Here's the important code:
Writing the file to memory:
override fun doInBackground(vararg p0: Any?): String {
var result = ""
try {
val bytes = ByteArrayOutputStream()
mBitmap.compress(Bitmap.CompressFormat.PNG, 95, bytes)
val file = File(externalCacheDir!!.absoluteFile.toString()
+ File.separator + "KidsDrawingApp_"
+ System.currentTimeMillis() / 1000 + ".png")
val fileOutput = FileOutputStream(file)
fileOutput.write(bytes.toByteArray())
fileOutput.close()
result = file.absolutePath
} catch (e: Exception) {
e.printStackTrace()
}
Log.d("File", result)
return result
}
** The mBitmap
variable is just the Bitmap generated from the canvas.
Here, the Log.d
returns, for instance:
D/File: /storage/emulated/0/Android/data/com.example.kidsdrawingapp/cache/KidsDrawingApp_1599992654.png
I can access the file just fine if I open the Files
app and search for it.
But when I run the MediaScannerConnection
on onPostExecute()
, the function doesn't return an uri based on the absolute path at all. Here's the code:
MediaScannerConnection.scanFile(this@MainActivity, arrayOf(result), null) {
path, uri -> val shareIntent = Intent()
Log.d("Path", path)
Log.d("Uri", uri.toString())
shareIntent.action = Intent.ACTION_SEND
shareIntent.putExtra(Intent.EXTRA_STREAM, uri)
shareIntent.type = "image/png"
startActivity(
Intent.createChooser(
shareIntent, "Share image"
)
)
}
Once again, the Log.d("Path", path)
returns the same file as the previous Log.d()
, but when I try to convert the Uri
to string, it crashes because it's null.
I tried adding "file://" + file.absolutePath"
like I saw in some other answers but it still didn't work, the uri
returned by the scanFile()
was still null.
I'm using API 21.
File Provider Code
AndroidManifest.xml
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.kidsdrawingapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/path" />
</provider>
@xml/path.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="captured" path="Android/data/com.example.kidsdrawingapp/files" />
</paths>
tried adding "file://" + file.absolutePath" like I saw in some other answers but it still didn't work.
And why not? You should tell why. – Babbienull
is an expected value for theUri
-- see the documentation. It means that the scan failed. "I'm using API 21" -- what precisely do you mean by this? Do you mean that you are running the app on an Android 5.0 device? – FlagstadLog
output showed the full path. – Courtesyand the path is a valid one
That path is an app specific path and the media store does not want to know about such paths. Hence the null. – BabbieAndroid/data/com.example.kidsdrawingapp/files
should I just use.
? – Courtesy