2022 Jul. 19.
2022 Jul. 18.
// ファイル・ピッカーによるディレクトリ取得 fun myMain() { // ボタンがタップされたら、ファイルピッカーによりディレクトリを取得 buttonSelectDir.setOnClickListener { openFilePicker() } } private fun openFilePicker() { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { addFlags( Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION ) } fileLauncherSelectDir.launch(intent) } /* * ボリューム名文字列とディレクトリパス文字列の取得 * selectedVolumeDirにContentResolverのMediaStore.Files.FileColumns.VOLUME_NAMEに相当する文字列が格納される * selectedRelativeDirにContentResolverのMediaStore.Files.FileColumns.RELATIVE_PATHに相当する文字列が格納される */ private val fileLauncherSelectDir = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> // 結果を受け取るルーチン if (result.resultCode == RESULT_OK) { // succeeded. // get string of directory val selectedDirUri = result.data?.data ?: throw Exception() /* uri冒頭の"content://com.android.externalstorage.documents/tree"を削除し、 エンコードされた /(スラッシュ)を戻す。 ContentPreviderに合わせ、VolumeとRelativeの文字列を取得する。 プライマリ・ストレージ文字列は"/external_primary/"に置き換える。 */ val selectedDirString = selectedDirUri.toString(). replaceFirst("content://com.android.externalstorage.documents/tree", "") selectedVolumeDir = selectedDirString. substring(0, selectedDirString.indexOf("%3A")+3 ) if (selectedVolumeDir.indexOf("/primary%3A") > -1) { // primary volume selectedVolumeDir = selectedVolumeDir.replaceFirst("/primary%3A", "external_primary") } else if (selectedVolumeDir.indexOf("%3A") > -1) { // SD card selectedVolumeDir = selectedVolumeDir.replaceFirst("/", "").replaceFirst("%3A", "") } selectedRelativeDir = selectedDirString. substring( selectedDirString.indexOf("%3A")). replace("%3A", "" ) if (selectedRelativeDir.indexOf("%2F") > -1) { selectedRelativeDir = selectedRelativeDir.replace("%2F", "/") } // Relativeの末尾を"/"にしておく if (selectedRelativeDir.takeLast(1) != "/" ) { selectedRelativeDir = selectedRelativeDir + "/" } } else { // failed } } private fun selectMediaFromContentProvider() { /* * get uri of media in the directory */ val contentResolver = this.contentResolver val proj = arrayOf( MediaStore.Files.FileColumns.MEDIA_TYPE, MediaStore.Files.FileColumns.RELATIVE_PATH, MediaStore.Files.FileColumns.VOLUME_NAME, "_data" ) val selectionClause = "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + " = " + MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO + " OR " + MediaStore.Files.FileColumns.MEDIA_TYPE + " = " + MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO + ")" + " AND " + "(" + MediaStore.Files.FileColumns.VOLUME_NAME + " LIKE ? " + " AND " + MediaStore.Files.FileColumns.RELATIVE_PATH + " LIKE ? " + ")" val selectionArgs = arrayOf(selectedVolumeDir, selectedRelativeDir + "%") val query = contentResolver.query( MediaStore.Files.getContentUri("external"), proj, selectionClause, selectionArgs, null ) val tmpVal2 = query?.count query?.use { cursor -> if (cursor.count > 0) { // とりあえず最初のメディアを取り出してみる cursor.moveToFirst() val medType = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MEDIA_TYPE)) val medPath = cursor.getString(cursor.getColumnIndexOrThrow("_data")) // play media val mediaIntent = Intent() mediaIntent.action = Intent.ACTION_VIEW if (medType == 2) { mediaIntent.setDataAndType(Uri.parse(medPath), "audio/*") startActivity(mediaIntent) } else if (medType == 3) { mediaIntent.setDataAndType(Uri.parse(medPath), "video/*") startActivity(mediaIntent) } } } query?.close() }
参考ページ
android開発 ContentResolver 音声メディア・動画メディアへのクエリによるメディア情報取得 - rokkonet
android開発 ContentResolver query条件書式 ( selectionClause ) - rokkonet