Не удается получить URI файла из намерения onActivityResult - PullRequest
0 голосов
/ 25 января 2020

Я хотел бы получить нормальный путь к файлу от onActivityResult, например:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK) {
            Log.i("m", data!!.dataString!!)
            convertFileToString(data.dataString!!)

        }
    }

, но я получаю такую ​​ошибку:

java.io.FileNotFoundException: File 'content:/com.android.providers.media.documents/document/image%3A18' does not exist

это исключение происходит из метода, который преобразует мои файл в строку. Эта ошибка указывает на эту строку:

try {
val data = FileUtils.readFileToByteArray(file) // this line

} catch (e: IOException) {
e.printStackTrace()
}

Этот файл также существует, но я не могу его получить. Я видел здесь несколько вопросов, которые предлагают получить REAL путь, подобный этому:

fun getPath(context:Context, uri:Uri):String {
  val result:String = null
  val proj = arrayOf<String>(MediaStore.Images.Media.DATA)
  val cursor = context.getContentResolver().query(uri, proj, null, null, null)
  if (cursor != null)
  {
    if (cursor.moveToFirst())
    {
      val column_index = cursor.getColumnIndexOrThrow(proj[0])
      result = cursor.getString(column_index)
    }
    cursor.close()
  }
  if (result == null)
  {
    result = "Not found"
  }
  return result
}

, но этот метод возвращает такое исключение:

java.io.FileNotFoundException: File 'Not found' does not exist

Итак, что я получаю здесь data!!.dataString!! :

content://com.android.providers.media.documents/document/image%3A18

и что я здесь получаю Log.i("m",uri.path.toString()):

/document/image:18

, поскольку я вижу, что это не настоящий путь, по которому был сохранен этот пикт. Может кто знает, где я допустил ошибки?)

ОБНОВЛЕНИЕ

Как преобразовать файл в строку:

fun convertFileToString(path: String) {
        //dialog.dismiss()
        val file = File(path)

        for (i in 0 until sn.array!!.size()) {
            val jsonObj = sn.array!![i].asJsonObject
            val nFile = jsonObj.get("filename").asString

            if (file.name == nFile) {
                Toast.makeText(this, R.string.message_about_attached__file, Toast.LENGTH_SHORT).show()
                return
            }
        }

        try {
            val data = FileUtils.readFileToByteArray(file)
            uploadFiles(File(path).name, Base64.encodeToString(data, Base64.NO_WRAP))
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

1 Ответ

1 голос
/ 25 января 2020

Я хотел бы получить нормальный путь к файлу от onActivityResult следующим образом:

Я предполагаю, что вы используете ACTION_OPEN_DOCUMENT или, возможно, ACTION_GET_CONTENT. Вы получаете content Uri, который является именно тем, что задокументировано для этих Intent действий. Такой Uri может быть поддержан:

  • Локальным файлом на внешнем хранилище, к которому вы, вероятно, не сможете получить доступ Android 10 +
  • Локальным файлом на внутреннем хранилище для другое приложение
  • Локальный файл на съемном носителе
  • Локальный файл, который зашифрован и требует расшифровки на лету
  • Поток байтов, хранящийся в BLOB столбец в базе данных
  • Часть содержимого в Inte rnet, которая должна быть сначала загружена другим приложением
  • Содержимое, создаваемое на лету
  • ... и так далее

это исключение происходит от метода, который преобразует мой файл в строку

Я предполагаю, что "преобразует мой файл в строку", Вы имеете в виду читать содержимое файла как String. В этом случае:

  • Получите ContentResolver, позвонив getContentResolver() на Context, например, Activity
  • Позвоните openInputStream() на ContentResolver , передав ваш Uri, чтобы получить InputStream для контента, обозначенного Uri
  • Вызовите reader().readText() на InputStream, чтобы получить String, представляющий содержимое файла

В сочетании это должно быть что-то вроде:

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