Android Q (10) partition storage perfect adaptation method
preface
Recently, I have been doing the adaptation of Android Q. as of today, the adaptation of Android Q partition storage has been completed, and there have been many pits. At present, most of the online Posts summarize the change content. The next few posts summarize the actual experience code of partition storage and pit filling experience. I hereby record it and provide help for you.
This article is mainly about the specific implementation of Android Q (10) partition storage adaptation
Note here: when adapting Android Q, you should also be compatible with Q system version or below, and use SDK_ Version differentiation
background
Storage permissions
Android Q still uses read_ EXTERNAL_ Storage and write_ EXTERNAL_ Storage is used as storage related runtime permissions, but even if these permissions are obtained, access to external storage is limited, and only files in its own directory and public internal files can be accessed.
Division of external storage structure
Public directories: downloads, documents, pictures, DCIM, movies, music, ringtones, etc
Address: / storage / emulated / 0 / downloads (pictures), etc
The files in the public directory will not be deleted with app uninstallation.
App private directory
Address: / storage / emulated / 0 / Android / data / package name / files
The private directory stores the private files of the app, which will be deleted with the uninstall of the app.
Adaptation guidance
Content resolver is used in Android Q to add, delete, modify and query files
1. Get (create) the folder under its own directory
Get and create. If there is no corresponding folder in the phone, it will be automatically generated
//在自身目录下创建apk文件夹 File apkFile = context.getExternalFilesDir("apk");
2. Create files in your own directory
Generate the path to download, and read and write through the input / output stream
String apkFilePath = context.getExternalFilesDir("apk").getAbsolutePath(); File newFile = new File(apkFilePath + File.separator + "temp.apk"); OutputStream os = null; try { os = new FileOutputStream(newFile); if (os != null) { os.write("file is created".getBytes(StandardCharsets.UTF_8)); os.flush(); } } catch (IOException e) { } finally { try { if (os != null) { os.close(); } } catch (IOException e1) { } }
3. Create a folder in a public directory
Write via mediastore.insert
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { return null; } ContentResolver resolver = context.getContentResolver(); ContentValues values = new ContentValues(); values.put(MediaStore.Downloads.DISPLAY_NAME,fileName); values.put(MediaStore.Downloads.DESCRIPTION,fileName); //设置文件类型 values.put(MediaStore.Downloads.MIME_TYPE,"application/vnd.android.package-archive"); //注意MediaStore.Downloads.RELATIVE_PATH需要targetVersion=29,//故该方法只可在Android10的手机上执行 values.put(MediaStore.Downloads.RELATIVE_PATH,"Download" + File.separator + "apk"); Uri external = MediaStore.Downloads.EXTERNAL_CONTENT_URI; Uri insertUri = resolver.insert(external,values); return insertUri;
4. Create a file in the specified folder under the public directory
Combined with the above code, we mainly create files or folders in the public directory and get the local path URI. Different URIs can be saved to different public directories. Next, you can write to the file using the input / output stream
Important: Android Q does not support file: / /, which can only be accessed through URI
ContentResolver resolver = context.getContentResolver(); Uri insertUri = resolver.insert(external,values); if(insertUri == null) { return; } String mFilePath = insertUri.toString(); InputStream is = null; OutputStream os = null; try { os = resolver.openOutputStream(insertUri); if(os == null){ return; } int read; File sourceFile = new File(sourcePath); if (sourceFile.exists()) { // 文件存在时 is = new FileInputStream(sourceFile); // 读入原文件 byte[] buffer = new byte[1024]; while ((read = is.read(buffer)) != -1) { os.write(buffer,read); } } } catch (Exception e) { e.printStackTrace(); }finally { try { if (is != null) { is.close(); } if (os != null) { os.close(); } } catch (IOException e) { e.printStackTrace(); } }
5. Read files in public directory through mediastore
ParcelFileDescriptor parcelFileDescriptor = null; FileDescriptor fileDescriptor = null; Bitmap tagBitmap = null; try { parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri,"r"); if (parcelFileDescriptor != null && parcelFileDescriptor.getFileDescriptor() != null) { fileDescriptor = parcelFileDescriptor.getFileDescriptor(); //转换uri为bitmap类型 tagBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (parcelFileDescriptor != null) { parcelFileDescriptor.close(); } } catch (IOException e) { } }
6. Deleting files using mediastore
context.getContentResolver().delete(fileUri,null,null);
7. Permissions required for app to access files through mediastore
The specific functions of Android Q storage will be introduced later. Welcome to pay attention~
The above is the whole content of this article. I hope it will help you in your study, and I hope you will support us a lot.