LoginSignup
1
1

More than 1 year has passed since last update.

[Android] MediaStoreにメディアファイルを保存する

Posted at

未だに何回実装しても覚えられないし、毎回調べてるので使う部分のコードだけメモ
(なんか説明がごちゃごちゃしすぎじゃない?)
細かいAPIの説明はネットに十分にあるので割愛。

コードは画像例(動画などの場合はMIME_TYPEやMediaURIなどを合わせて実装)
エラーハンドリングは各自でお願いします。

パターン1 ByteArrayで書き込む

SaveMedia.kt
    private fun savedImageMediaStoreFile(imageUri: Uri, data: ByteArray, fileName: String){
                                        
        val collection = if (Build.VERSION.SDK_INT >= 29) {
            MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
        } else {
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        }

        val contentValues = ContentValues().apply {
            put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
            put(MediaStore.Images.Media.MIME_TYPE, "image/png")
            if (Build.VERSION.SDK_INT >= 29) {
                put(MediaStore.Images.Media.IS_PENDING, true)
            }

//      //※1 専用直下フォルダを作成したい場合
//            put(
//                MediaStore.Images.ImageColumns.RELATIVE_PATH,
//                Environment.DIRECTORY_PICTURES + "/MY_DIRECTORY/"
//            )
        }

        val contentResolver = applicationContext.contentResolver
        val contentUri = contentResolver.insert(collection, contentValues)

        //※2 ファイルを書き込む
        contentResolver.openFileDescriptor(contentUri!!, "w", null).use {
            FileOutputStream(it!!.fileDescriptor).use { output ->
                output.write(data)
            }
        }

        contentValues.clear()
        if (Build.VERSION.SDK_INT >= 29) {
            contentResolver.update(contentUri, contentValues.apply {
                put(MediaStore.Images.Media.IS_PENDING, false)
            }, null, null)
        } else {
            contentResolver.update(contentUri, contentValues, null, null)
        }
    }

※1
自分で指定したフォルダを作成して、その直下に保存してくれます。
ない場合はPictures/xxxxxx.pngだが、
/MY_DIRECTORY/を指定することによってPictures/MY_DIRECTORY/xxxxxx.png
に保存してくれる。

Uriで書き込む

SaveMedia.kt
        //※2の部分のみ
        contentResolver.openInputStream(imageUri).use { input ->
            val output = contentResolver.openOutputStream(contentUri, "w")!!
            input!!.copyTo(output)
        }

感想

byteArrayで書き込むサンプルとUriで書き込むサンプルが混同してるので余計混乱していたように感じる。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1