AS 中有一个关于 的 lint 警告android.permission.WRITE_EXTERNAL_STORAGE。该警告表示,当面向 Android 10 及更高版本时,该权限将不再提供写入访问权限。删除上述权限仍然可以写入内部存储文件夹Pictures/MY_APP_NAME以保存图像,但它仅适用于 Android 10 (SDK 29) 和/或更高版本(尚未在 Android R 上测试)。当我在 Android M (SDK 23) 等低版本上再次测试时,保存图像停止工作,所以我决定返回android.permission.WRITE_EXTERNAL_STORAGE因此警告再次出现。lint 是否可能只是误报,在不同情况下错误地诊断了问题?因为目前我的支持 SDK 从 21 开始到最新的 30,但 lint 仅指出在针对 Android 10 (SDK 29) 时不再需要它,并且没有考虑回顾项目的最低 SDK 支持。
我正在开发一个应用程序。我将不同的文件类型(例如 docx、pdf、zip)上传到 WAMP 服务器。以下是我的内部存储的文件路径。
/storage/emulated/0/WhatsApp/Media/WhatsApp Documents/api.txt
我已在清单文件中添加并允许存储权限,并在运行时读取文件。但是,没有可用的内部存储权限请求。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)
对于 Android 10 我也使用了这个属性
android:requestLegacyExternalStorage="true"
Run Code Online (Sandbox Code Playgroud)
但当我从内部存储读取文件进行上传时,我在三星 Galaxy 上的 Android 11 操作系统(又名 Android R)上收到此错误。
java.io.FileNotFoundException:/storage/emulated/0/WhatsApp/Media/WhatsApp Documents/api.txt:打开失败:EACCES(权限被拒绝)
我刚刚将我的源代码迁移到了 Androidx,因为我这样做了我的共享功能来共享声音不再工作。Logcat 说:
Failed to save file: /storage/emulated/0/appfolder/testsound.mp3 (Permission denied)
Run Code Online (Sandbox Code Playgroud)
这是它保存声音的部分:
final String fileName = soundObject.getItemName() + ".mp3";
File storage = Environment.getExternalStorageDirectory();
File directory = new File(storage.getAbsolutePath() + "/appfolder/");
directory.mkdirs();
final File file = new File(directory, fileName);
InputStream in = view.getContext().getResources().openRawResource(soundObject.getItemID());
try{
Log.i(LOG_TAG, "Saving sound " + soundObject.getItemName());
OutputStream out = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer, 0, buffer.length)) != -1){
out.write(buffer, 0 , len);
}
in.close();
out.close();
} catch (IOException e){
Log.e(LOG_TAG, …Run Code Online (Sandbox Code Playgroud) 我试图从外部存储器获取文件,然后我必须使用意图将该文件发送到pdf阅读器.以前下面的代码工作正常,但安装Android 6(Marshmallow更新)后,我的代码无法正常工作并获取Toast消息
" 无法访问此文件检查位置或网络,然后重试."
(这是由于新的Android运行时权限).我刚尝试了所有的解决方案(内容提供商等,但没有工作)任何解决方案?
File file = new File(getFilesDir(), "myfile.pdf");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intentChooser = Intent.createChooser(intent, "Choose Pdf Application");
try {
startActivity(intentChooser);
} catch (ActivityNotFoundException e) {
//com.adobe.reader
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.adobe.reader")));
}
Run Code Online (Sandbox Code Playgroud) 我编写了一个插件,用于通过Dart访问Android上的ExternalStorageDirectory。
插件的android特定代码:
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("getUserDataDirectory")) {
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
result.success(path);
} else {
result.notImplemented();
}
}
Run Code Online (Sandbox Code Playgroud)
返回的路径是正确的storage/emulated/0。但是现在,如果我尝试迭代抛出目录,我将获得一个权限被拒绝。
错误日志
[ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter ( 3381): FileSystemException: Directory listing failed, path = '/storage/emulated/0/' (OS Error: Permission denied, errno = 13)
E/flutter ( 3381): #0 _Directory._fillWithDirectoryListing (dart:io-patch/directory_patch.dart:32)
E/flutter ( 3381): #1 _Directory.listSync (directory_impl.dart:214)
E/flutter ( 3381): #2 _MyAppState.initPathRequest (/data/user/0/com.yourcompany.userdatadirectoryexample/cache/exampleIAKNFP/example/lib/main.dart:34:25)
Run Code Online (Sandbox Code Playgroud)
主镖
path = await Userdatadirectory.getUserDataDirectory;
var dir = new Directory(path);
List contents = dir.listSync(); …Run Code Online (Sandbox Code Playgroud) 我很难简单地重命名由应用程序创建但已放入文档文件夹中的文件。
编辑:
碰巧这些视频不是由应用程序创建的,但预计会由应用程序重命名。用户在开始时手动将视频放入文档文件夹中。我的错。
这是我的代码:
public static boolean renameVideoFile(Context c, File from, File to) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
try {
Uri fromUri = FileProvider.getUriForFile(c, c.getPackageName() + ".provider", new File(FileUtils.getVideosDir(), from.getName()));
ContentResolver contentResolver = c.getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 1);
contentResolver.update(fromUri, contentValues, null, null);
contentValues.clear();
contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, to.getName());
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0);
contentResolver.update(fromUri, contentValues, null, null);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
} else {
if (from.renameTo(to)) {
removeMedia(c, from);
addMedia(c, to);
return true;
} else …Run Code Online (Sandbox Code Playgroud) Mkdirs() 函数在 Android 11 上不起作用。在 Android 10 及更低版本上一切正常。
代码:
***String path =Environment.getExternalStorageDirectory().getAbsolutePath() + "/My_directory/";
File temp_file = new File(path);
if (!temp_file.exists()){
Boolean can_create= temp_file.mkdir();
}***
Run Code Online (Sandbox Code Playgroud)
如果 Android 10 或更低版本,以上代码将返回 true。但在 Android 11 中返回 false。清单权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)
请注意,运行时权限被视为相同(READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE)。
清单应用:
<application
android:requestLegacyExternalStorage="true"
Run Code Online (Sandbox Code Playgroud)
我能够在外部存储中写入的唯一方法是使用,getExternalFilesDir()但这不是根目录。
根据这个开发者网站,我们不能再在根目录中创建文件夹了!
检查后到目前为止的问题:
1-是否确认在Android 11中我们无法在根目录上创建任何文件夹?有解决办法吗?
2-如果是,将数据保存在外部存储中的方法是什么,不包括getExternalFilesDir()?
3-为什么android:requestLegacyExternalStorage="true"不工作?