Home > other >  `Intent.ACTION_VIEW` fails with a `no file received` error
`Intent.ACTION_VIEW` fails with a `no file received` error

Time:07-31

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.

  • Related