Android 10 (api 29) 中没有这样的文件或目录
No such file or directory in Android 10 (api 29)
我正在开发一个照片编辑器应用程序,我在其中编辑图片后将其保存到本地存储中。它在 android 9 之前工作正常,但在 android 10 上没有。它显示 "No such file or directory found" 在 Android 10 中的异常。经过一些研究,我发现 getExternalFilesDir() 在android问+。但是我在 android10 中找不到任何合适的方法。所以如果有人可以提供教程,那将非常有帮助。
我已经添加并授予了使用权限 android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 以防出现问题,但它没有解决任何问题。
这是我的尝试(使用的 ParcelFileDescriptor):
private void fileAccessForAndroidQ(Uri fileUri){
try {
ParcelFileDescriptor parcelFileDescriptor = this.getContentResolver().openFileDescriptor(fileUri, "r", null);
InputStream inputStream = new FileInputStream(parcelFileDescriptor.getFileDescriptor());
Cursor returnCursor =
getContentResolver().query(fileUri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
returnCursor.moveToFirst();
fileName = returnCursor.getString(nameIndex);
file = new File(this.getFilesDir(), fileName);
OutputStream outputStream = new FileOutputStream(file);
IOUtils.copyStream(inputStream, outputStream);
}catch (Exception e){
Toast.makeText(this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
如有任何帮助,我们将不胜感激。
如果您的目标是 Android 10(API 级别 29)或更高,请在应用的清单文件中将 requestLegacyExternalStorage
的值设置为 true
:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.appname"
android:installLocation="auto">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
这是我能找到的最好的:
https://developer.android.com/training/data-storage/app-specific#external
基本上,您现在为您的文件使用特定于应用程序的目录。例如:
@Nullable
File getAppSpecificAlbumStorageDir(Context context, String albumName) {
// Get the pictures directory that's inside the app-specific directory on
// external storage.
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), albumName);
if (file == null || !file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
我发现这对我有用。我正在尝试列出 ListView
上的所有文件
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
} else {
File s = Environment.getExternalStorageDirectory();
Log.d("Path ",Arrays.toString(s.listFiles()));
File[] s1 = new File[s.listFiles().length];
for(int i=0;i<s.listFiles().length;i++){
s1[i]= new File(s.listFiles()[i].toString().replace("/storage/emulated/0/", ""));
}
ArrayAdapter<File> adapter = new ArrayAdapter<File>(this,R.layout.support_simple_spinner_dropdown_item,s1);
l1.setAdapter(adapter);
}
我正在开发一个照片编辑器应用程序,我在其中编辑图片后将其保存到本地存储中。它在 android 9 之前工作正常,但在 android 10 上没有。它显示 "No such file or directory found" 在 Android 10 中的异常。经过一些研究,我发现 getExternalFilesDir() 在android问+。但是我在 android10 中找不到任何合适的方法。所以如果有人可以提供教程,那将非常有帮助。
我已经添加并授予了使用权限 android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 以防出现问题,但它没有解决任何问题。
这是我的尝试(使用的 ParcelFileDescriptor):
private void fileAccessForAndroidQ(Uri fileUri){
try {
ParcelFileDescriptor parcelFileDescriptor = this.getContentResolver().openFileDescriptor(fileUri, "r", null);
InputStream inputStream = new FileInputStream(parcelFileDescriptor.getFileDescriptor());
Cursor returnCursor =
getContentResolver().query(fileUri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
returnCursor.moveToFirst();
fileName = returnCursor.getString(nameIndex);
file = new File(this.getFilesDir(), fileName);
OutputStream outputStream = new FileOutputStream(file);
IOUtils.copyStream(inputStream, outputStream);
}catch (Exception e){
Toast.makeText(this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
如有任何帮助,我们将不胜感激。
如果您的目标是 Android 10(API 级别 29)或更高,请在应用的清单文件中将 requestLegacyExternalStorage
的值设置为 true
:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.appname"
android:installLocation="auto">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<activity android:name=".activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
这是我能找到的最好的: https://developer.android.com/training/data-storage/app-specific#external
基本上,您现在为您的文件使用特定于应用程序的目录。例如:
@Nullable
File getAppSpecificAlbumStorageDir(Context context, String albumName) {
// Get the pictures directory that's inside the app-specific directory on
// external storage.
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), albumName);
if (file == null || !file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
我发现这对我有用。我正在尝试列出 ListView
上的所有文件if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
} else {
File s = Environment.getExternalStorageDirectory();
Log.d("Path ",Arrays.toString(s.listFiles()));
File[] s1 = new File[s.listFiles().length];
for(int i=0;i<s.listFiles().length;i++){
s1[i]= new File(s.listFiles()[i].toString().replace("/storage/emulated/0/", ""));
}
ArrayAdapter<File> adapter = new ArrayAdapter<File>(this,R.layout.support_simple_spinner_dropdown_item,s1);
l1.setAdapter(adapter);
}