Can't Get File Uri from Intent Onactivityresult

Can't get file uri from intent onActivityResult

I would like to receive normal file path from onActivityResult like this:

My guess is that you are using ACTION_OPEN_DOCUMENT, or perhaps ACTION_GET_CONTENT. You are getting a content Uri, which is exactly what those Intent actions are documented to return. Such a Uri might be backed by:

  • A local file on external storage, which you probably cannot access on Android 10+
  • A local file on internal storage for the other app
  • A local file on removable storage
  • A local file that is encrypted and needs to be decrypted on the fly
  • A stream of bytes held in a BLOB column in a database
  • A piece of content on the Internet that needs to be downloaded by the other app first
  • Content that is generated on the fly
  • ...and so on

this exception comes from method which converts my file to string

I assume that by "converts my file to string", you mean read the file contents in as a String. In that case:

  • Get a ContentResolver by calling getContentResolver() on a Context, such as your Activity
  • Call openInputStream() on the ContentResolver, passing in your Uri, to get an InputStream on the content identified by the Uri
  • Call reader().readText() on the InputStream to get a String representing the file contents

Combined, that should be something like:

val string = data.data?.let { contentResolver.openInputStream(it).use { it.reader().readText() } }

onActivityResult's intent.getPath() doesn't give me the correct filename

I am trying to fetch a file

Not with that code. That code is asking the user to pick a piece of content. This may or may not be a file.

According to many threads I'm supposed to fetch the file name from the intent with data.getData().getPath()

That was never correct, though it tended to work on older versions of Android.

So what to do?

Well, that depends.

If you wish to only accept files, integrate a file chooser library instead of using ACTION_GET_CONTENT. (UPDATE 2019-04-06: since Android Q is banning most filesystem access, this solution is no longer practical)

If you are willing to allow the user to pick a piece of content using ACTION_GET_CONTENT, please understand that it does not have to be a file and it does not have to have something that resembles a filename. The closest that you will get:

  • If getScheme() of the Uri returns file, your original algorithm will work

  • If getScheme() of the Uri returns content, use DocumentFile.fromSingleUri() to create a DocumentFile, then call getName() on that DocumentFile — this should return a "display name" which should be recognizable to the user

onActivityResult Uri - create subfolder and get DocumentUri of new subfolder

DocumentFile subfolderDf = DocumentFile.fromTreeUri(this,uri);
subfolderDf.createDirectory("TestFolder");

Change to:

            DocumentFile folder = DocumentFile.fromTreeUri(this, uri);
DocumentFile subfolder = folder.createDirectory("TestFolder");

if ( subfolder == null )
{
Toast.makeText(context, "Sorry, could not create a subfolder with name TestFolder", Toast.LENGTH_LONG).show();

return;
}

Toast.makeText(context, "Created a subfolder with name TestFolder: " + subfolder.getUri().toString(), Toast.LENGTH_LONG).show();

Android: Converting a URI to File

I would simply like to take the file from the app's internal storage and save it to whatever directory the user selected

The user didn't select a directory. The user is creating a document, where the Uri points to that document.

How do I convert the returned Uri into a File so I can write data more easily?

You don't, any more than you convert an HTTPS URL into a File so you can write data more easily.

Use ContentResolver and openOutputStream() to open an OutputStream on the (empty) document created by ACTION_CREATE_DOCUMENT and identified by the returned Uri. Then, use standard Java I/O to copy the bytes from your file (e.g., via a FileInputStream) to the OutputStream.

Get PDF from MediaStore after receiving content:// Uri in onActivityResult?

This is how I'm getting pdf as file :

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
type = "application/pdf"
addCategory(Intent.CATEGORY_OPENABLE)
flags = flags or Intent.FLAG_GRANT_READ_URI_PERMISSION
}
startActivityForResult(intent, 111)

Inside your OnActivityResult(requestCode:Int,resultCode:Int,data:Intent?)

if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
// 101 -> {
// data?.data?.also { uri ->
// Log.i(TAG, "Uri: $uri")
// baseAdapter?.add(ImageArray(null, null, uri.toString()))
// }
// }
111 -> {
data?.data?.also { documentUri ->
baseActivity.contentResolver?.takePersistableUriPermission(
documentUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
val file = DocumentUtils.getFile(baseActivity,documentUri)//use pdf as file
}
}
}

}

Singleton class to covert Uri to file:

object DocumentUtils {
fun getFile(mContext: BaseActivity?, documentUri: Uri): File {
val inputStream = mContext?.contentResolver?.openInputStream(documentUri)
var file = File("")
inputStream.use { input ->
file =
File(mContext?.cacheDir, System.currentTimeMillis().toString()+".pdf")
FileOutputStream(file).use { output ->
val buffer =
ByteArray(4 * 1024) // or other buffer size
var read: Int = -1
while (input?.read(buffer).also {
if (it != null) {
read = it
}
} != -1) {
output.write(buffer, 0, read)
}
output.flush()
}
}
return file
}
}

P.S: Do not forget to ask permission at runtime

Manifest.permission.WRITE_EXTERNAL_STORAGE
Manifest.permission.READ_EXTERNAL_STORAGE


Related Topics



Leave a reply



Submit