Пишу небольшое приложение в Android Studio, как и многие столкнулся с типовой задачей — диалог выбора файла и его загрузка.
Ясно, что устройство уже имеет какой то файловый менеджер, и писать свой диалог — хоть и интересно, но является и тратой времени, а в будущем еще и доп. компонентом, требующим поддержки.
Используем Activity Result APIs для вызова существующего файл менеджера, и допустим, что в нашем activity (MainActivity) есть какая то кнопка запускающая этот диалог.
Тогда код может выглядеть следующим образом:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class MainActivity : AppCompatActivity() {     val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {             result: ActivityResult ->         if (result.resultCode == Activity.RESULT_OK) {             // открываем поток на чтение по полученному URI             val intent = result.data             val myFile = getContentResolver().openInputStream(intent?.data!!)             if (myFile != null) {                 // читаем данные                 val content = myFile.bufferedReader().readText()                 // демонстрируем имя файла и объем прочитанных данных                 Toast                     .makeText(this, "File %s, Length %d bytes".format(intent?.data!!.path, content.length), Toast.LENGTH_LONG)                     .show()             }         }     }     fun onActionClick(view: View) {         // настраиваем фильтры intent         val intent = Intent()            .setType("*/*")            .setAction(Intent.ACTION_GET_CONTENT)         // запускаем контракт         startForResult.launch(intent)     } } | 
В начале вы создаёте и регистрируете т.н. контракт, а при нажатии кнопки вызываете его с нужным intent фильтром.
В обработчике результата я открываю поток на чтение, используя переданный URI. Всё содержимое файла я читаю в переменную content.
