Noa*_*ram 14 android deprecated android-api-levels
在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");
}
});
}
Run Code Online (Sandbox Code Playgroud)
有什么替代方法呢?
小智 31
对于 Android Q,您可以添加android:requestLegacyExternalStorage="true"到清单中的元素。这将使您选择使用旧存储模型,并且您现有的外部存储代码将起作用。
<manifest ... >
<!-- This attribute is "false" by default on apps targeting
Android 10 or higher. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)
从技术上讲,你只需要在你更新targetSdkVersion到 29后才需要这个。具有较低targetSdkVersion值的应用程序默认选择使用旧存储,并且需要android:requestLegacyExternalStorage="false"选择退出。
Com*_*are 16
使用getExternalFilesDir(),getExternalCacheDir()或getExternalMediaDir()(方法Context)代替Environment.getExternalStorageDirectory()。
或者,修改mPhotoEditor为可以使用Uri,然后:
使用ACTION_CREATE_DOCUMENT获得Uri用户的选择的位置,或
使用MediaStore,ContentResolver和insert()获取Uri特定媒体类型(例如图像)的-请参阅此示例应用程序,该示例演示了如何从网站下载MP4视频
另外,请注意,您的Uri.fromFilewith ACTION_MEDIA_SCANNER_SCAN_FILE会在Android 7.0+上使用崩溃FileUriExposedException。在Android Q上,只有MediaStore/ insert()选项会MediaStore快速将您的内容编入索引。
有关Android Q如何影响外部存储的更多信息,请参见此博客文章。
Har*_*ara 11
请使用getExternalFilesDir(),getExternalCacheDir()而不是Environment.getExternalStorageDirectory()在 Android 10 中创建文件时。
请参阅以下行:
val file = File(this.externalCacheDir!!.absolutePath, "/your_file_name")
Run Code Online (Sandbox Code Playgroud)
这对我有用
在manifest文件的应用程序标签中添加这一行
android:requestLegacyExternalStorage="true"
Run Code Online (Sandbox Code Playgroud)
例子
<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>
Run Code Online (Sandbox Code Playgroud)
目标 SDK 为 29
defaultConfig {
minSdkVersion 16
targetSdkVersion 29
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Run Code Online (Sandbox Code Playgroud)
小智 7
destPath使用新的API调用获取:
String destPath = mContext.getExternalFilesDir(null).getAbsolutePath();
Run Code Online (Sandbox Code Playgroud)
这是一个小示例,如果您想使用默认相机拍照并将其存储在 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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
并获取 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
)
}
Run Code Online (Sandbox Code Playgroud)
不要忘记 pre 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
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
要获取内部存储目录而无需硬编码,
权限(适用于所有 Android 版本)。不要忘记获得用户的权限。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
Run Code Online (Sandbox Code Playgroud)
Android 10 的旧权限(将其添加到 AndroidManifest.xml > 应用程序标记)。
android:requestLegacyExternalStorage="true"
Run Code Online (Sandbox Code Playgroud)
获取内部存储目录路径:
public static String getInternalStorageDirectoryPath(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
return storageManager.getPrimaryStorageVolume().getDirectory().getAbsolutePath();
} else {
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6338 次 |
| 最近记录: |