Camera changes in Android 11

There have been some changes in the use of Android 11 cameras

It's nearly two years since my last blog. In these two years, I have learned vue, applet and React, and less about Android, so I haven't written much blog. Recently, I changed my job and returned to Android, so I plan to write bloggers and record some pits or new knowledge points I encountered in the project.

When I came to the new company and took over the company's project, I found a hole in using cameras in Android 11. There were no problems in versions below 11, but only in Android 11. No more nonsense. The following text begins

Resultcode obtained by Android 11 camera = = 0

If the camera takes pictures normally and returns, the value of resultCode is resultCode==-1, as shown in the following figure

resultCode==0

Simply find out the reason for this situation. There are probably two situations when resultCode==0

1. The runtime permission is not granted

When Android: targetsdkversion > 23, you need to apply for runtime permission in the project, because the image storage needs Android permission. WRITE_ Settings permission. If there is no such permission, resultCode==0 will occur.
But this will not happen unless you are a novice!!!

2. The directory to store does not exist

Generally, when we take photos with the system camera, we will create our own directory to store photos. Generally, we first specify a directory path to determine whether the file or folder pointed to by this path exists. If it does not exist, we will create it. If it does exist, we will use it directly.
In Android 10, this set of code can be used, and there is no problem with it.

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (activity == null) {
    return;
}
if (intent.resolveActivity(activity.getPackageManager()) == null) {
    return;
}

File dataDirectoryFile = new File(Environment.getExternalStorageDirectory()+ "/img/");
if (!dataDirectoryFile.exists()) {
	dataDirectoryFile.mkdir();
}
File file = new File(dataDirectoryFile, "fileName.jpg");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
    FileProvider.getUriForFile(activity,
        activity.getApplicationContext().getPackageName() + ".provider", file));
activity.startActivityForResult(intent, 10010);

However, if the above code runs on the Android 11 mobile phone, we will encounter the problem mentioned at the beginning, that is, the problem of resultCode==0.
In order to solve the problem, I searched Baidu and Google and found that they simply said the reason and didn't put forward how to solve it.
So I went to Google's official documents and found that the usage recommended by Google's official was not like this, so I modified it according to the official documents and found that the official was indeed right!
OK, this article is over. Please refer to the official documents for development. OK, thank you for watching!!!

To make fun of

The main reason is that Google changed the file storage strategy in Android 10

1. Android Q file storage mechanism has been modified to sandbox mode, which is similar to iOS
2. Applications can only access files and public media files under their own sandbox

Here, the idea should be clear. Android 11 implements a more strict strategy for file storage on the basis of Android 10, so there will be problems when using the original creation storage on the Android 11 version.
So I made a simple change to the existing code

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (activity == null) {
    return;
}
if (intent.resolveActivity(activity.getPackageManager()) == null) {
    return;
}

File photoFile = null;
try {
    photoFile = getTemporaryCameraFile();
	File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
	String imageFileName = "fileName";
	photoFile = File.createTempFile(imageFileName,  ".jpg", storageDir );
} catch (IOException e) {
    e.printStackTrace();
}
if (photoFile != null) {
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            FileProvider.getUriForFile(activity,
                    activity.getApplicationContext().getPackageName() + ".provider", photoFile));
    activity.startActivityForResult(intent, 10010);
}

The above is the modified code. I tested myself and found that there is no problem running on Android 11, Android 10, Android 7 and Android 5.
If a friend finds that the place is wrong, please contact me in time, and I will change it in time to avoid affecting more people. thank you!

Android 11 camera returned Intent==null

One reason for Intent==null is that you passed in the storage address of the file when creating the camera jump Intent, so Intent is not returned when the callback is finished.

intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);

It is because of this line of code that the intent of the callback is null. If you delete this line of code, you can get the photographed file through intent in the callback

if (requestCode == 10010 && resultCode == RESULT_OK) {
    Bundle extras = data.getExtras();
    Bitmap imageBitmap = (Bitmap) extras.get("data");
    imageView.setImageBitmap(imageBitmap);
}

Pictures from this place Official introduction It's a thumbnail. If you want to get a large picture, you need to pass in the storage path you set. The following is the official original words


If you find any mistakes or mistakes in my blog, please contact me in time to avoid affecting more people.
thank you!
Thank you for watching

Attachment: Official documents

Keywords: Android

Added by aswini_1978 on Mon, 31 Jan 2022 09:28:39 +0200