猿问

如何在 Android 10 (Android Q) 中访问外部存储?

我刚刚将源代码迁移到 Androidx,因为我这样做了,共享声音的共享功能不再起作用。Logcat 说:


Failed to save file: /storage/emulated/0/appfolder/testsound.mp3 (Permission denied)

这是保存声音的部分:


            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, "Failed to save file: " + e.getMessage());

            }

这是共享声音的代码:


try{

                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1){



                                if (ActivityCompat.checkSelfPermission(view.getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){

                                    ActivityCompat.requestPermissions((Activity) view.getContext(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);


                                }


我需要改变什么?如何让每个人无论使用哪个 Android 版本(minSdkVersion 16)都可以下载和分享声音?


互换的青春
浏览 113回答 2
2回答

繁星点点滴滴

如果您的目标平台为 Android 10 或更高版本,请在应用的清单文件中将 requestLegacyExternalStorage 的值设置为 true:<manifest ... >&nbsp; <!-- This attribute is "false" by default on apps targeting&nbsp; &nbsp; &nbsp; &nbsp;Android 10 or higher. -->&nbsp; <application android:requestLegacyExternalStorage="true" ... >&nbsp; &nbsp; ...&nbsp; </application></manifest>访问文件(以下两个代码块来自developer.android.com文档。)要加载媒体文件,请从ContentResolver调用以下方法之一。&nbsp;Uri contentUri = ContentUris.withAppendedId(&nbsp; &nbsp; &nbsp; &nbsp; MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,&nbsp; &nbsp; &nbsp; &nbsp; cursor.getLong(Integer.parseInt(BaseColumns._ID)));String fileOpenMode = "r";ParcelFileDescriptor parcelFd = resolver.openFileDescriptor(uri, fileOpenMode);if (parcelFd != null) {&nbsp; &nbsp; int fd = parcelFd.detachFd();&nbsp; &nbsp; // Pass the integer value "fd" into your native code. Remember to call&nbsp; &nbsp; // close(2) on the file descriptor when you're done using it.}在运行 Android 10(API 级别 29)及更高版本的设备上,您的应用可以使用 IS_PENDING 标志在将媒体文件写入磁盘时获得对媒体文件的独占访问权限。ContentValues values = new ContentValues();values.put(MediaStore.Images.Media.DISPLAY_NAME, "IMG1024.JPG");values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");values.put(MediaStore.Images.Media.IS_PENDING, 1);ContentResolver resolver = context.getContentResolver();Uri collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);Uri item = resolver.insert(collection, values);try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(item, "w", null)) {&nbsp; &nbsp; // Write data into the pending image.} catch (IOException e) {&nbsp; &nbsp; e.printStackTrace();}// Now that we're finished, release the "pending" status, and allow other apps// to view the image.values.clear();values.put(MediaStore.Images.Media.IS_PENDING, 0);resolver.update(item, values, null, null);

慕运维8079593

我被困了很长时间,这对我来说效果很好&nbsp;&nbsp;StrictMode.VmPolicy.Builder&nbsp;builder&nbsp;=&nbsp;new&nbsp;StrictMode.VmPolicy.Builder(); &nbsp;&nbsp;&nbsp;&nbsp;StrictMode.setVmPolicy(builder.build()); &nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;=&nbsp;new&nbsp;File(filepath);并且不要忘记在清单文件中请求旧存储。&nbsp;&nbsp;<application&nbsp;android:requestLegacyExternalStorage="true"&nbsp;>
随时随地看视频慕课网APP

相关分类

Java
我要回答