Android Java、最近更新されたSDK、APIレベル29に更新中です。
Environment.getExternalStorageDirectory()
はAPIレベル29で廃止されました
私のコードは
private void saveImage() {
if (requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
final String folderPath = Environment.getExternalStorageDirectory() + "/PhotoEditors";
File folder = new File(folderPath);
if (!folder.exists()) {
File wallpaperDirectory = new File(folderPath);
wallpaperDirectory.mkdirs();
}
showLoading("Saving...");
final String filepath=folderPath
+ File.separator + ""
+ System.currentTimeMillis() + ".png";
File file = new File(filepath);
try {
file.createNewFile();
SaveSettings saveSettings = new SaveSettings.Builder()
.setClearViewsEnabled(true)
.setTransparencyEnabled(true)
.build();
if(isStoragePermissionGranted() ) {
mPhotoEditor.saveAsFile(file.getAbsolutePath(), saveSettings, new PhotoEditor.OnSaveListener() {
@Override
public void onSuccess(@NonNull String imagePath) {
hideLoading();
showSnackbar("Image Saved Successfully");
mPhotoEditorView.getSource().setImageURI(Uri.fromFile(new File(imagePath)));
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,Uri.fromFile(new File(filepath))));
Intent intent = new Intent(EditImageActivity.this, StartActivity.class);
startActivity(intent);
finish();
}
@Override
public void onFailure(@NonNull Exception exception) {
hideLoading();
showSnackbar("Failed to save Image");
}
});
}
これの代わりは何でしょうか?
getExternalFilesDir()
の代わりにgetExternalCacheDir()
、getExternalMediaDir()
、またはEnvironment.getExternalStorageDirectory()
(Context
のメソッド)を使用します。
または、mPhotoEditor
を変更してUri
を操作できるようにし、次のようにします。
_ACTION_CREATE_DOCUMENT
_を使用してUri
をユーザーが選択した場所に取得する、または
MediaStore
、ContentResolver
、およびinsert()
を使用して、特定の種類のメディア(たとえば、画像)のUri
を取得します— このサンプルアプリ を参照してください。ウェブサイト
また、_Uri.fromFile
_付きの_ACTION_MEDIA_SCANNER_SCAN_FILE
_は、Android 7.0以降でFileUriExposedException
付きでクラッシュするはずです。 Android Qでは、MediaStore
/insert()
オプションのみがMediaStore
によってコンテンツのインデックスをすばやく取得します。
Android Qが外部ストレージにどのように影響したかについての詳細は このブログ投稿 を参照してください。
新しいAPI呼び出しでdestPath
を取得します。
String destPath = mContext.getExternalFilesDir(null).getAbsolutePath();
これは、デフォルトのカメラを使用して写真を撮り、それをDCIMフォルダー(DCIM/app_name/filename.jpg)に保存する場合に、ファイルのURIを取得する小さな例です。
カメラを開く(カメラの権限について覚えておいてください):
private var photoURI: Uri? = null
private fun openCamera() {
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
photoURI = getPhotoFileUri()
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
takePictureIntent.resolveActivity(requireActivity().packageManager)?.also {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
}
}
}
そしてURIを取得します:
private fun getPhotoFileUri(): Uri {
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val fileName = "IMG_${timeStamp}.jpg"
var uri: Uri? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val resolver = requireContext().contentResolver
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/app_name/")
}
uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
}
return uri ?: getUriForPreQ(fileName)
}
private fun getUriForPreQ(fileName: String): Uri {
val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
val photoFile = File(dir, "/app_name/$fileName")
if (photoFile.parentFile?.exists() == false) photoFile.parentFile?.mkdir()
return FileProvider.getUriForFile(
requireContext(),
"ru.app_name.fileprovider",
photoFile
)
}
Qより前のWRITE_EXTERNAL_STORAGE権限について忘れずに、FileProviderをAndroidManifest.xmlに追加してください。
そして結果を得る:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_IMAGE_CAPTURE -> {
photoURI?.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val thumbnail: Bitmap =
requireContext().contentResolver.loadThumbnail(
it, Size(640, 480), null
)
} else {
// pre Q actions
}
}
}
}
}