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.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>