Bekerja pada android Java, SDK baru-baru ini diupdate ke API level 29, sekarang ada peringatan yang menunjukkan bahwa
Environment.getExternalStorageDirectory()
tidak lagi digunakan di API level 29
Kode saya adalah
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");
}
});
}
Apa alternatif untuk ini?
sumber
getExternalMediaDir
masukContext
, lihat sendiri: developer.android.com/reference/android/content/Context DangetExternalMediaDirs
sudah usang, lihat juga: developer.android.com/reference/android/content/… KeduanyagetExternalFilesDir()
dangetExternalCacheDir()
dihapus setelah aplikasi di-uninstal ( lihat URL yang sama). Jadi, tidak ada hal di atas yang bisa menggantikanEnvironment.getExternalStorageDirectory()
.Dapatkan
destPath
dengan panggilan API baru:String destPath = mContext.getExternalFilesDir(null).getAbsolutePath();
sumber
Untuk Android Q, Anda dapat menambahkan
android:requestLegacyExternalStorage="true"
elemen Anda di manifes. Ini memilih Anda untuk menggunakan model penyimpanan lama, dan kode penyimpanan eksternal Anda yang ada akan berfungsi.<manifest ... > <!-- This attribute is "false" by default on apps targeting Android 10 or higher. --> <application android:requestLegacyExternalStorage="true" ... > ... </application> </manifest>
Secara teknis, Anda hanya memerlukan ini setelah memperbarui
targetSdkVersion
ke 29. Aplikasi dengantargetSdkVersion
nilai yang lebih rendah secara default memilih ke penyimpanan lama dan harusandroid:requestLegacyExternalStorage="false"
menyisih.sumber
Silakan gunakan
getExternalFilesDir()
,getExternalCacheDir()
bukanEnvironment.getExternalStorageDirectory()
saat Anda membuat file di Android 10.Lihat baris di bawah ini:
val file = File(this.externalCacheDir!!.absolutePath, "/your_file_name")
sumber
getExternalFilesDir()
jalur kustom untuk menyimpan gambar, saya ingin menggunakan ini untuk mencegah menampilkan gambar ke Galeri? Secara default, ini simpan keAndorid/data/packagename/...
Ini adalah contoh kecil bagaimana mendapatkan URI untuk file jika Anda ingin mengambil foto menggunakan kamera default dan menyimpannya di folder DCIM (DCIM / app_name / namafile.jpg):
Buka kamera (ingat tentang izin CAMERA):
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) } } }
Dan dapatkan 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 ) }
Jangan lupa tentang izin WRITE_EXTERNAL_STORAGE untuk pra Q dan tambahkan FileProvider ke AndroidManifest.xml.
Dan dapatkan hasil:
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 } } } } }
sumber
Ini berhasil untuk saya
Tambahkan baris ini di tag aplikasi
manifest
fileandroid:requestLegacyExternalStorage="true"
Contoh
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:networkSecurityConfig="@xml/network_security_config" android:requestLegacyExternalStorage="true" android:supportsRtl="true" android:theme="@style/AppTheme"> </application>
defaultConfig { minSdkVersion 16 targetSdkVersion 29 multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" }
sumber