My current code :
Just focus on the fileOpener variable. The SafeFiles class is a self declared variable which has the file's extensions and such. Don't worry too much about it.
fileOpener = { file: File ->
val uri: Uri = Uri.fromFile(file).normalizeScheme()
val mime = MimeTypeMap
.getSingleton()
.getMimeTypeFromExtension(safeFile.extension.substring(1))
Log.d(TAG, "mime = $mime")
val intent = Intent(Intent.ACTION_VIEW)
intent.data = uri
intent.type = mime
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
Log.d(
TAG, "data received:"
"uri = $uri\n"
"extension = ${safeFile.extension.substring(1)}\n"
"path = ${file.absolutePath}\n"
"size = ${file.totalSpace} "
)
CoroutineScope(Dispatchers.Main).launch {
context!!.startActivity(intent)
}
}
Logs -
2022-07-30 16:41:41.005 19233-19285/com.example.cryptile D/SafeViewerFragment: mime = image/png
2022-07-30 16:41:41.005 19233-19285/com.example.cryptile D/SafeViewerFragment: data received:uri = file:///storage/emulated/0/Cryptile/CRYPTILE_2022_07_30/.CACHE/aa854c7e-9fa4-4313-9750-cf58fde467b8.png
extension = png
path = /storage/emulated/0/Cryptile/CRYPTILE_2022_07_30/.CACHE/aa854c7e-9fa4-4313-9750-cf58fde467b8.png
size = 119640424448
Clearly, the size not being zero means the file exists. I have also opened the mentioned file from the device's file explorer and everything seems to work fine. the only conclusion I came to is this might be some issue with the file provider. So, here's the manifest -
Manifest -
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cryptile">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<application
android:name=".app_data.AppApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.CRYPTILE">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.cryptile.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
</application>
</manifest>
And the filepaths.xml -
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="/storage/emulated/0"
path="." />
</paths>
CodePudding user response:
the only conclusion I came to is this might be some issue with the file provider
You are not using FileProvider. You are using Uri.fromFile(), which has been all but banned for six years.
Replace:
val uri: Uri = Uri.fromFile(file).normalizeScheme()
with:
val uri: Uri = FileProvider.getUriForFile(context!!, "com.example.cryptile.fileProvider", file)
(and then rewrite your code to avoid the !!)
CodePudding user response:
Adding this might have helped -
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
My final code is -
fileOpener = { file: File ->
val uri: Uri = FileProvider.getUriForFile(
requireContext(),
"com.example.cryptile.fileProvider",
file
)
val mime = MimeTypeMap
.getSingleton()
.getMimeTypeFromExtension(safeFile.extension.substring(1))
Log.d(TAG, "mime = $mime")
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.action = Intent.ACTION_VIEW
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
intent.setDataAndType(uri, mime)
Log.d(
TAG, "data received:"
"uri = $uri\n"
"extension = ${safeFile.extension.substring(1)}\n"
"path = ${file.absolutePath}\n"
"size = ${file.totalSpace} "
)
CoroutineScope(Dispatchers.Main).launch {
context!!.startActivity(intent)
}
}
Didn't make any changes anywhere else outside this lambda. Just make sure to compare the intent code because it is a little different compared to the question's code.
