Android N…

Yesterday the project targetSdkVersion was changed to 26. The questions came one after another.

The most serious problem is that the system camera function is called somewhere in the project, and a picture is returned after shooting.

There are two ways to do this. In fact, the principle of both implementations is the same. All hermit Intent starts system camera. Return to the photo you took.

They just return different things.

One that returns the picture directly

A Uri that returns the image that was captured before starting the camera

The first method:


Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                startActivityForResult(intent, TAKE_PHOTO_REQUEST)
Copy the code

We just need to specify the actionI of the Intent to implement it.

The image object can be retrieved via an Intent callback in the onActivityResult callback.

 Bitmap  photo = intent.getParcelableExtra("data")Copy the code

There is no other way to save memory for sending images without specifying them

The second method is also used in the project:

root_dir = Environment.getExternalStorageDirectory().toString() + File.separator + Constant.CACHE_PATH pt_dir = root_dir  + File.separator +"bike_operation.jpg"Copy the code

Specify the path to store the image.

Now let’s talk about what N did before.

All you need is the following:

  val intentFromCapture = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

  intentFromCapture.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(File(pt_dir)))startActivityForResult(intentFromCapture, Constant.PAIZHAO_REQUEST)
Copy the code

Via a Uri. FromFile specifies the Uri corresponding to the image storage path

You can retrieve the Uri again in the onActivityResult callback and parse the Uri to get the corresponding file path. Generate the corresponding Bitmap.

However, because the targetSdkVersion was changed to 26 yesterday, the following error was reported when running this code on the N device

android.os.FileUriExposedException: file:///storage/emulated/0/mangoebike_operation_cache/bike_damage.jpg exposed beyond app through ClipData.Item.getUri()
Copy the code

7.0 adds a stricter mechanism for sharing file data between processes

The WAY urIs are retrieved can no longer be retrieved as usual. Here’s what you need to do

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.whxxcy.mango_operation.fileProvider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
Copy the code

Specify the provider property under the Manifest Application node. The authorities attribute is optional. But remember that you’re going to need it in your code. Here we specify the package name plus the.fileProvider. Field.

The other thing we need to specify is this resource property. Create an XML folder in the RES file directory and create the File_paths file in that folder.

<? xml version="1.0" encoding="utf-8"? > <resources> <paths> <external-path name="bike_operation"
            path="mangoebike_operation_cache" />
    </paths>
</resources>

Copy the code

The path attribute in my understanding is used to concatenate urIs because if you don’t write it will look for the file in the root directory.

The name attribute must be specified. Do not specify compile fails. As I understand it, the name attribute is actually the name of the file that you generated when you took a photo in your code.

After specifying these two attributes, look at the code:

val intentFromCapture = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intentFromCapture.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    val contentUri = FileProvider.getUriForFile(this@OperationActivity, packageName + ".fileProvider", the File (pt_dir)) intentFromCapture. PutExtra (MediaStore. EXTRA_OUTPUT contentUri) / / will take the photos saved to the specified URI}else {
    intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(File(pt_dir)))
}
startActivityForResult(intentFromCapture, Constant.PAIZHAO_REQUEST)Copy the code

If the current SDK version is greater than or equal to 24Uri

= FileProvider.getUriForFile(this@OperationActivity, packageName + ".fileProvider", File(pt_dir))Copy the code

Parameter 1: context. Parameter 2: is the authitrites specified in the provider. Parameter 3: The path specified at the beginning of the File object to store the photo taken

Then parse the Uri in the onActivityResult callback to get the Bitmap… Any inaccuracies in the description will be corrected later…