MediaStoreを使ってDCIMディレクトリに画像を保存する
事の発端
Environment.getExternalStorageDirectory()がDeprecated!!!
頼むぜ,google・・・。
それ今から辞めたら影響度でかくない?
API level 1のときからだぜ?
今,30とか31だぜ?APIがYO!!!
ここに書いてある通りなんだけど・・・
qiita.com
アプリ内データはgetExternalFilesDir()とかで代替できるんだけども,今まで普通にアクセスしてた写真フォルダとかにはアクセスできなくなってくるわけなんですよ。
というわけで四苦八苦しながら解決いたしました。
MainActivity.java
package jp.co.hogehoge.mediastoretest; import android.content.ContentResolver; import android.content.ContentValues; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Bitmap bmp; Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView imageView = findViewById(R.id.imageView); bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic); button = findViewById(R.id.button); button.setOnClickListener(this); } @Override public void onClick(View view) { if (view == button) { ContentValues contentValues = new ContentValues(); // ファイル名 contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, "sample2.jpg"); // MIMETYPEの設定 contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); // 書込み用にロックする contentValues.put(MediaStore.Images.Media.IS_PENDING, 1); //保存フォルダ ->DCIMディレクトリのtestに格納される(フォルダも自動で作ってくれる) //Environment.DIRECTORY_DCIMをEnvironment.DIRECTORY_PICTURESにすればPicturesディレクトに保存される contentValues.put(MediaStore.Images.ImageColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM+"/test/"); ContentResolver resolver = getApplicationContext().getContentResolver(); Uri collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); Uri item = resolver.insert(collection, contentValues); try { OutputStream outPutStream = getContentResolver().openOutputStream(item); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); //ByteArrayOutputStreamに変換する bmp.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream); //ストリームからバイトにして byte[] bytes = byteArrayOutputStream.toByteArray(); // OutPutStreamに流し込む outPutStream.write(bytes); outPutStream.close(); } catch (IOException e) { e.printStackTrace(); } contentValues.clear(); // ロックの開放 contentValues.put(MediaStore.Images.Media.IS_PENDING, 0); resolver.update(item, contentValues, null, null); } } }
AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" android:background="@drawable/ic"/> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="128dp" android:text="Button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
BUTTONを押すと・・・。
DCIMのテストディレクトリに保存されました!
参考