I try to copy the file from the external memory of the phone to the Internal storage. I launch the Activity with Intent (Intent.ACTION_GET_CONTENT)
I choose a file to copy. When trying to copy

kotlin.io.NoSuchFileException: /document/C2D6-5EC6:Documents/скриншот.jpg: The source file doesn't exist.

If I understood correctly: The problem is not in the copy function, but in the wrong path to the source file ( /document/C2D6-5EC6:Documents/screenshot.jpg ), which came in intent

How to make a copy? Use getBaseContext().getContentResolver().openInputStream(myuri) ?

Or is there some more interesting option?

minSdkVersion 21
targetSdkVersion 24

(Kotlin)

 import android.app.Activity import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.util.Log import android.view.View import com.lfom.modbuster.R import java.io.File class ConfigFileFinder : AppCompatActivity() { private val TAG = this.javaClass.simpleName override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_config_file_finder) } private val FIND_FILE: Int = 0xA public fun onFindFile(view: View) { val intent = Intent(Intent.ACTION_GET_CONTENT) intent.type = "*/*" intent.addCategory(Intent.CATEGORY_OPENABLE) startActivityForResult(intent, FIND_FILE) } public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if (requestCode == FIND_FILE && resultCode == Activity.RESULT_OK) { Log.w(TAG, data?.data?.path ) val inpFile = File(data?.data?.path ?: return) if (!inpFile.canRead()) { Log.e(TAG, "Can't read file ${inpFile.absolutePath}") } try { val newFile = inpFile.copyTo(File(filesDir.path, inpFile.name), false) } catch (e: Exception) { Log.e(TAG, e.toString()) } } else { super.onActivityResult(requestCode, resultCode, data) } } 

UPD

While I stopped at this option (code on kotlin):

 public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if (requestCode == FIND_FILE && resultCode == Activity.RESULT_OK) { if (data == null) { Log.w(TAG, "Empty Intent for file copy") return } try { val inpFileStream = baseContext.contentResolver.openInputStream(data.data) val outFileStream = openFileOutput("default.prj", Context.MODE_PRIVATE) inpFileStream.use { input -> outFileStream.use { output -> input.copyTo(output) } } } catch (e: Exception) { Log.e(TAG, e.toString()) } } else { super.onActivityResult(requestCode, resultCode, data) } } 
  • 2
    I personally spent 3 hours today. In addition to getBaseContext().getContentResolver().openInputStream(myuri) nothing works. - YurySPb

1 answer 1

The problem with the code is that you are trying to copy File , but you have to copy the content of Uri

By and large, except for openInputStream() nothing else will work, since Uri can point to anything: an external drive, an SD card, a network device, or even an address on a network, on a cloud, etc., in any way possibility of converting Uri to File not guaranteed

In this particular case, when Uri contains a Document you can try this:

 DocumentFile documentFile=DocumentFile.fromSingleri(context, uri); if(documentFile.isFile()) { File file=new File(URI.create(documentFile.getUri().toString()); } 

But even this does not guarantee tripping. DocumentFile can be a virtual file pointing to a BLOB in SQLite