Android: How to share an Uri returned from SAF?

Viewed 8

I meet some problems when I'm trying to share some files among apps. In app A, one can choose to open an existing file via openDocument():

val launcher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.OpenDocument()
    ) {
        // In short, preserve returned uri
        uri = it
    }
...
onClick = {
    launcher.launch(arrayOf("text/plain"))
},

Then, app A can share the uri to other apps by:

val shareIntent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_STREAM, uri)
    type = "text/plain"
}

context.startActivity(Intent.createChooser(shareIntent, "Share test"))

Since Uri returned from SAF just starts with "content://", FileProvider is not used here.

Then something weired happened. For some apps, it works just fine; however for others, I always receive a message saying the file does not exist, or it cannot be shared properly. For example, I get an uri like: content://com.android.providers.downloads.documents/document/442

Let's say its correct file name is some.txt, But in app B which accepts the shared file, the file name is mistaken as 442 with no extension name.

I wonder what causes this problem. Is it my code's, SAF's, or those other apps' fault? And how can I correct it?

My SDK version is 32, and I'm using jetpack compose for app A.

1 Answers

however for others, I always receive a message saying the file does not exist, or it cannot be shared properly

You are not doing anything to grant permission to other apps to be able to read the content identified by that Uri. The best approach is to use ShareCompat.IntentBuilder to create your Intent. Alternatively, use addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION). See this blog post for more.

Is it my code's, SAF's, or those other apps' fault?

In terms of "a message saying the file does not exist", that is because of the aforementioned permission problem.

In terms of "the file name is mistaken as 442 with no extension name", if that does not clear up once you fix the permission problem, the bug is in the other app.

Related