Partition storage sandbox mechanism of Android Q

To give users more control over their own files, Android Q changed the way the application to access external storage space in the file. Android Q replaced with more granular media specific permission READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permission and without specific permission, applications can access your files in external storage devices.

1, isolated storage for the application sandbox private files

For each application, Android Q will create an "isolated storage sandbox" to restrict access to other applications in external storage devices in this application. Common external storage device is / sdcard. This definition has two advantages:

①, the permissions needed less.  Application sandbox file is a private file your application. Therefore, you do not need any permissions to access and save their files in an external storage device;

②, relative to other applications on the device, privacy stronger.  Any other application can not directly access files stored isolation sandbox in your application. With this access restriction, your application can more easily maintain privacy sandbox documents;

The best place to store files in an external storage device is Context.getExternalFilesDir () returns the file is located, so the behavior of this location are consistent across all Android versions. When using this method, you need to pass files corresponding to the type we want to create or open in the media environment . For example, to save or access applications private pictures, please call Context.getExternalFilesDir (Environment.DIRECTORY_PICTURES).

2, a collection of shared media files

If our application created a file belonging to the user and want to keep this user uninstall the application, these files will be saved in a universal media collections (shared collection) in. Shared collections including: photographs, audio, video and downloads .

3, view other application documents required permissions

Our application without asking any permission, you can create and modify their own files in the shared collection. However, our application to create or modify files in other applications that have been created, you must request the appropriate permissions:

①, access to photos and video while other applications to share files collection, need  READ_MEDIA_IMAGES or  READ_MEDIA_VIDEO authority (depending on the file type your application needs to access);

②, access music shared set of files in other applications, you need  READ_MEDIA_AUDIO permission;

4, access to a shared collection

After requesting the necessary permissions, our application can use MediaStore API access to these collections:

①, for photos and videos shared collection, use  MediaStore.Images or MediaStore.Video;

②, for music shared collection, use MediaStore.Audio;

③, for downloading content shared collection, use MediaStore.Downloads;

To access the media files in native code, use or kotlin based MediaStore Java code to retrieve the file, and then pass the corresponding file descriptor to native code. Please refer to access media files from native code section.

5, a reservation application in file-sharing collections

By default, when a user uninstall the application, Android Q will clean up files saved in the sandbox. To keep these files when uninstalling applications, use memory access framework for storage access framework , or save the file in the shared collection. To preserve file sharing collections, the new line is inserted in the relevant MediaStore collection, and use the following method:

①, should be at least  DISPLAY_NAME and  MIME_TYPE provides a value column;

②, (optional) You can use  PRIMARY_DIRECTORY and  SECONDARY_DIRECTORY columns to influence the location of a file stored on disk;

③, retention  DATA column is not defined. As a result, the platform will have the flexibility to keep the file outside the sandbox;

After inserting this line, we can use ContentResolver.openFileDescriptor () This API reading or writing data to the file.

6, location information access photos

Some photos include location information in the Exif metadata so that users see the location where a photograph. Because this position is very sensitive information, by default, Android Q that location information will be hidden. If our application needs access to the photo location information, call the following method:

①, the new  ACCESS_MEDIA_LOCATION add permissions to the list in your application;

②, in MediaStore object, calls  setRequireOriginal() and incoming photos URI;

Example Java code is as follows:

Uri photoUri = Uri.withAppendedPath(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            cursor.getString(idColumnIndex));

    final double[] latLong;
    if (BuildCompat.isAtLeastQ()) {
        // When running Android Q, get location data from `ExifInterface`.
        photoUri = MediaStore.setRequireOriginal(photoUri);
        InputStream stream = getContentResolver().openInputStream(photoUri);
        if (stream != null) {
            ExifInterface exifInterface = new ExifInterface(stream);
            double[] returnedLatLong = exifInterface.getLatLong();

            // If lat/long is null, fall back to the coordinates (0, 0).
            latLong = returnedLatLong != null ? returnedLatLong : new double[2];

            // Don't reuse the stream associated with {@code ExifInterface}.
            stream.close();
        } else {
            // Failed to load the stream, so return the coordinates (0, 0).
            latLong = new double[2];
        }
    } else {
        // On devices running Android 9 (API level 28) and lower, use the
        // media store columns.
        latLong = new double[]{
                cursor.getFloat(latitudeColumnIndex),
                cursor.getFloat(longitudeColumnIndex)
        };
    }

kotlin following sample code:

val latLong = if (BuildCompat.isAtLeastQ()) {
        // When running Android Q, get location data from `ExifInterface`.
        photoUri = MediaStore.setRequireOriginal(photoUri)
        contentResolver.openInputStream(photoUri).use { stream ->
            ExifInterface(stream).run {
                // If lat/long is null, fall back to the coordinates (0, 0).
                latLong ?: doubleArrayOf(0.0, 0.0)
            }
        }
    } else {
        // On devices running Android 9 (API level 28) and lower, use the
        // media store columns.
        doubleArrayOf(
            cursor.getFloat(latitudeColumnIndex).toDouble(),
            cursor.getFloat(longitudeColumnIndex).toDouble()
        )
    }

7, access to files created by other applications

To access other applications media files saved in an external storage device, you need the following steps:

①, according to the share that contains files you want to access the necessary collection request permission;

②, use  ContentResolver objects to find and open the file;

8, write data to files created by other applications

By Save the file in a shared collection, our application becomes the owner of the file. Under normal circumstances, only when the owner of a file shared collections, our application can write data to a file. However, if our application is the user's default application, we can write to files in other applications:

①, if your application is the user's default photo manager application, you can modify other applications to save photos and videos shared collection of image files;

②, if your application is the user's default music application, you can modify other applications to save the music audio file sharing in the collection;

To modify other applications stored in the media file storage device, you need to use ContentResolver locate the file to modify.

9, an external storage device to identify a particular

In Android 9 and below, all files on all storage devices show a single "external" volume name. Android Q while providing a unique name for each roll an external storage device. This naming system can help us to efficiently organize content and index it can also control the position of the stored content. To uniquely identify a specific file external storage devices, we need to use the volume name and ID. For example, primary storage device is a file content: // media / external / images / media / 12, and the auxiliary storage device named FA23-3E92 is the corresponding file content: // media / FA23-3E92 / images / media / 12.

10, get a list of external storage

To get a list of all currently available volumes of names, call  MediaStore.getAllVolumeNames(), as shown in the following code snippet:

Set<String> volumeNames = MediaStore.getAllVolumeNames(context);

 

Published 63 original articles · won praise 179 · views 180 000 +

Guess you like

Origin blog.csdn.net/u011686167/article/details/90107612