This is my first article on getting started

1. The background

The Android sandbox mechanism has been around for a long time, but the application hasn’t adapted to it, and recently received a prompt from Google, which has put adaptation on the agenda and started a new round of mining. Starting August 2021, new apps will be required to target API level 30 (Android 11) and use the Android App Bundle publishing format. Starting November 2021, all app updates will be required to target API level 30 (Android 11). Apps with a download size of more than 150 MB are now supported by Play Asset Delivery and Play Feature Delivery.

2. The adaptation

  1. Change the target version and build version to 30, and buildTools can be modified as needed
compileSdkVersion 30
buildToolsVersion "30.0.3"
targetSdkVersion 30
Copy the code

2. Change the saving path

public static String createJpgFilePath(Context context, String name) {
        return context == null ? "" : new StringBuilder(
                context.getExternalCacheDir().getAbsolutePath())
                .append(File.separator).append(name).append(".jpg").toString();
    }
Copy the code

PS:

Through getExternalFilesDir () method to get the directory for the sdcard/Android/data/packageName/files /, general storage saved data for a long time.

Through getExternalCacheDir () method to get the directory for the sdcard/Android/data/packageName/cache /, general store temporary cache data

Use the above methods to obtain path and use, when applied after uninstalled, sdcard/Android/data/packageName/all the files in this directory will be deleted.

3. Call the camera

private void takePhoto(a) {
        mPhotoFile = new File(CommonUtil.createJpgFilePath(getContext(),
                TOKEN_PHOTO_NAME));

        if (mPhotoFile.exists()) {
            mPhotoFile.delete();
        }
        try {
            mPhotoFile.createNewFile();
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
            intent.putExtra(MediaStore.EXTRA_OUTPUT,
                    CommonUtil.getFileUri(getContext(), mPhotoFile));
            startActivityForResult(intent, REQ_CODE_CAMERA);
        } catch(Exception e) { e.printStackTrace(); }}Copy the code

Android7.0 or above requires converting File to Uri

public static Uri getFileUri(Context context, File file) {
      Uri uri = null;
      if(file ! =null) {
          if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
              // If the API is larger than the Android API23, replace the file Uri
              // Replace the value of the second argument, authority, with the value in the project.
              // Android 7.0 FileProvider is available online
              if(context ! =null) {
                  uri = FileProvider.getUriForFile(context,
                          context.getPackageName() + ".fileProvider", file); }}else{ uri = Uri.fromFile(file); }}return uri;
  }
Copy the code

Then accept the photo after shooting in onActivityResult, so the photo is taken, and then the cropping function

3. Invoke the system tailoring function

 private void cropPhoto(Uri uri) {
        mCroppedFile = new File(CommonUtil.createJpgFilePath(
                getContext(), CROPPED_PHOTO_NAME));

        if (mCroppedFile.exists()) {
            mCroppedFile.delete();
        }
        try {
            Intent intent = new Intent("com.android.camera.action.CROP");

            intent.setDataAndType(uri, "image/*");
            intent.putExtra("crop"."true");
            intent.putExtra("aspectX", mAspectX);
            intent.putExtra("aspectY", mAspectY);
            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCroppedFile));
            startActivityForResult(intent, REQ_CODE_CROP);
        } catch(Exception e) { e.printStackTrace(); }}Copy the code

The normal invocation prompt cannot be modifiedAfter verification foundSDK>=30 The system trims the private path that cannot access the AppIf you want to use the clipping function normally, there are two implementations

  1. Write your own cropping function
  2. Change the save path to a private path and change it to a public path (if you store it to a public path, you need to apply for the storage permission dynamically. Taking an avatar can be solved only in a private cache path. I hope there can be a compatible solution)

Opening the sandbox to migrate data will lead to a write-up over time