Public APIs for ID-specific Uris, misc items.
We have getContentUri() for entire collections of items, but we only have ID-specific overloads for some of the MediaStore classes; let's get them all added for consistency. Remove primary/secondary directory logic, which was replaced by new RELATIVE_PATH column before Q launched. Bug: 137890034 Test: atest --test-mapping packages/providers/MediaProvider Exempt-From-Owner-Approval: trivial API refactoring Change-Id: Iae4e7fe57adff071c35af459e31223a1fd05fef2
This commit is contained in:
@@ -9348,6 +9348,7 @@ package android.content {
|
||||
field public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
|
||||
field public static final String MIMETYPE_TEXT_PLAIN = "text/plain";
|
||||
field public static final String MIMETYPE_TEXT_URILIST = "text/uri-list";
|
||||
field public static final String MIMETYPE_UNKNOWN = "application/octet-stream";
|
||||
}
|
||||
|
||||
public class ClipboardManager extends android.text.ClipboardManager {
|
||||
@@ -9695,6 +9696,7 @@ package android.content {
|
||||
method public Long getAsLong(String);
|
||||
method public Short getAsShort(String);
|
||||
method public String getAsString(String);
|
||||
method public boolean isEmpty();
|
||||
method public java.util.Set<java.lang.String> keySet();
|
||||
method public void put(String, String);
|
||||
method public void put(String, Byte);
|
||||
@@ -34530,6 +34532,7 @@ package android.os {
|
||||
method public static String getExternalStorageState();
|
||||
method public static String getExternalStorageState(java.io.File);
|
||||
method @NonNull public static java.io.File getRootDirectory();
|
||||
method @NonNull public static java.io.File getStorageDirectory();
|
||||
method @Deprecated public static String getStorageState(java.io.File);
|
||||
method public static boolean isExternalStorageEmulated();
|
||||
method public static boolean isExternalStorageEmulated(@NonNull java.io.File);
|
||||
@@ -38353,8 +38356,10 @@ package android.provider {
|
||||
ctor public MediaStore();
|
||||
method @Nullable public static android.net.Uri getDocumentUri(@NonNull android.content.Context, @NonNull android.net.Uri);
|
||||
method @NonNull public static java.util.Set<java.lang.String> getExternalVolumeNames(@NonNull android.content.Context);
|
||||
method public static boolean getIncludePending(@NonNull android.net.Uri);
|
||||
method public static android.net.Uri getMediaScannerUri();
|
||||
method @Nullable public static android.net.Uri getMediaUri(@NonNull android.content.Context, @NonNull android.net.Uri);
|
||||
method public static boolean getRequireOriginal(@NonNull android.net.Uri);
|
||||
method @NonNull public static String getVersion(@NonNull android.content.Context);
|
||||
method @NonNull public static String getVersion(@NonNull android.content.Context, @NonNull String);
|
||||
method @NonNull public static String getVolumeName(@NonNull android.net.Uri);
|
||||
@@ -38497,6 +38502,7 @@ package android.provider {
|
||||
public static final class MediaStore.Audio.Media implements android.provider.MediaStore.Audio.AudioColumns {
|
||||
ctor public MediaStore.Audio.Media();
|
||||
method public static android.net.Uri getContentUri(String);
|
||||
method @NonNull public static android.net.Uri getContentUri(@NonNull String, long);
|
||||
method @Deprecated @Nullable public static android.net.Uri getContentUriForPath(@NonNull String);
|
||||
field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/audio";
|
||||
field public static final String DEFAULT_SORT_ORDER = "title_key";
|
||||
@@ -38547,6 +38553,7 @@ package android.provider {
|
||||
|
||||
public static final class MediaStore.Downloads implements android.provider.MediaStore.DownloadColumns {
|
||||
method @NonNull public static android.net.Uri getContentUri(@NonNull String);
|
||||
method @NonNull public static android.net.Uri getContentUri(@NonNull String, long);
|
||||
field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/download";
|
||||
field @NonNull public static final android.net.Uri EXTERNAL_CONTENT_URI;
|
||||
field @NonNull public static final android.net.Uri INTERNAL_CONTENT_URI;
|
||||
@@ -38587,6 +38594,7 @@ package android.provider {
|
||||
ctor public MediaStore.Images.Media();
|
||||
method @Deprecated public static android.graphics.Bitmap getBitmap(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException, java.io.IOException;
|
||||
method public static android.net.Uri getContentUri(String);
|
||||
method @NonNull public static android.net.Uri getContentUri(@NonNull String, long);
|
||||
method @Deprecated public static String insertImage(android.content.ContentResolver, String, String, String) throws java.io.FileNotFoundException;
|
||||
method @Deprecated public static String insertImage(android.content.ContentResolver, android.graphics.Bitmap, String, String);
|
||||
method @Deprecated public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[]);
|
||||
@@ -38656,6 +38664,7 @@ package android.provider {
|
||||
public static final class MediaStore.Video.Media implements android.provider.MediaStore.Video.VideoColumns {
|
||||
ctor public MediaStore.Video.Media();
|
||||
method public static android.net.Uri getContentUri(String);
|
||||
method @NonNull public static android.net.Uri getContentUri(@NonNull String, long);
|
||||
field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/video";
|
||||
field public static final String DEFAULT_SORT_ORDER = "title";
|
||||
field public static final android.net.Uri EXTERNAL_CONTENT_URI;
|
||||
|
||||
@@ -481,9 +481,8 @@ package android.provider {
|
||||
@Deprecated public static class MediaStore.PendingParams {
|
||||
ctor public MediaStore.PendingParams(@NonNull android.net.Uri, @NonNull String, @NonNull String);
|
||||
method public void setDownloadUri(@Nullable android.net.Uri);
|
||||
method public void setPrimaryDirectory(@Nullable String);
|
||||
method public void setRefererUri(@Nullable android.net.Uri);
|
||||
method public void setSecondaryDirectory(@Nullable String);
|
||||
method public void setRelativePath(@Nullable String);
|
||||
}
|
||||
|
||||
@Deprecated public static class MediaStore.PendingSession implements java.lang.AutoCloseable {
|
||||
|
||||
@@ -1736,7 +1736,6 @@ package android.os {
|
||||
public class Environment {
|
||||
method public static java.io.File buildPath(java.io.File, java.lang.String...);
|
||||
method @NonNull public static java.io.File getProductDirectory();
|
||||
method @NonNull public static java.io.File getStorageDirectory();
|
||||
}
|
||||
|
||||
public final class FileUtils {
|
||||
|
||||
@@ -63,6 +63,16 @@ public class ClipDescription implements Parcelable {
|
||||
*/
|
||||
public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
|
||||
|
||||
/**
|
||||
* The MIME type for data whose type is otherwise unknown.
|
||||
* <p>
|
||||
* Per RFC 2046, the "application" media type is to be used for discrete
|
||||
* data which do not fit in any of the other categories, and the
|
||||
* "octet-stream" subtype is used to indicate that a body contains arbitrary
|
||||
* binary data.
|
||||
*/
|
||||
public static final String MIMETYPE_UNKNOWN = "application/octet-stream";
|
||||
|
||||
/**
|
||||
* The name of the extra used to define a component name when copying/dragging
|
||||
* an app icon from Launcher.
|
||||
|
||||
@@ -475,11 +475,9 @@ public abstract class ContentResolver implements ContentInterface {
|
||||
*/
|
||||
public static final String ANY_CURSOR_ITEM_TYPE = "vnd.android.cursor.item/*";
|
||||
|
||||
/**
|
||||
* Default MIME type for files whose type is otherwise unknown.
|
||||
* @hide
|
||||
*/
|
||||
public static final String MIME_TYPE_DEFAULT = "application/octet-stream";
|
||||
/** {@hide} */
|
||||
@Deprecated
|
||||
public static final String MIME_TYPE_DEFAULT = ClipDescription.MIMETYPE_UNKNOWN;
|
||||
|
||||
/** @hide */
|
||||
@UnsupportedAppUsage
|
||||
|
||||
@@ -259,8 +259,6 @@ public final class ContentValues implements Parcelable {
|
||||
* Indicates whether this collection is empty.
|
||||
*
|
||||
* @return true iff size == 0
|
||||
* {@hide}
|
||||
* TODO: consider exposing this new method publicly
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return mMap.isEmpty();
|
||||
|
||||
@@ -168,8 +168,11 @@ public class Environment {
|
||||
return DIR_ANDROID_ROOT;
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
@TestApi
|
||||
/**
|
||||
* Return root directory where all external storage devices will be mounted.
|
||||
* For example, {@link #getExternalStorageDirectory()} will appear under
|
||||
* this location.
|
||||
*/
|
||||
public static @NonNull File getStorageDirectory() {
|
||||
return DIR_ANDROID_STORAGE;
|
||||
}
|
||||
|
||||
@@ -553,7 +553,7 @@ public final class MediaStore {
|
||||
* By default no pending items are returned.
|
||||
*
|
||||
* @see MediaColumns#IS_PENDING
|
||||
* @see MediaStore#setIncludePending(Uri)
|
||||
* @see MediaStore#getIncludePending(Uri)
|
||||
*/
|
||||
public static @NonNull Uri setIncludePending(@NonNull Uri uri) {
|
||||
return setIncludePending(uri.buildUpon()).build();
|
||||
@@ -564,6 +564,17 @@ public final class MediaStore {
|
||||
return uriBuilder.appendQueryParameter(PARAM_INCLUDE_PENDING, "1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if any pending media items should be included in calls such as
|
||||
* {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
|
||||
*
|
||||
* @see MediaColumns#IS_PENDING
|
||||
* @see MediaStore#setIncludePending(Uri)
|
||||
*/
|
||||
public static boolean getIncludePending(@NonNull Uri uri) {
|
||||
return parseBoolean(uri.getQueryParameter(MediaStore.PARAM_INCLUDE_PENDING));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the given {@link Uri} to also include any trashed media items from
|
||||
* calls such as
|
||||
@@ -594,11 +605,23 @@ public final class MediaStore {
|
||||
* {@link UnsupportedOperationException} will be thrown when the returned
|
||||
* {@link Uri} is used, such as when the caller doesn't hold
|
||||
* {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}.
|
||||
*
|
||||
* @see MediaStore#getRequireOriginal(Uri)
|
||||
*/
|
||||
public static @NonNull Uri setRequireOriginal(@NonNull Uri uri) {
|
||||
return uri.buildUpon().appendQueryParameter(PARAM_REQUIRE_ORIGINAL, "1").build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the caller requires the original file contents when calling
|
||||
* {@link ContentResolver#openFileDescriptor(Uri, String)}.
|
||||
*
|
||||
* @see MediaStore#setRequireOriginal(Uri)
|
||||
*/
|
||||
public static boolean getRequireOriginal(@NonNull Uri uri) {
|
||||
return parseBoolean(uri.getQueryParameter(MediaStore.PARAM_REQUIRE_ORIGINAL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new pending media item using the given parameters. Pending items
|
||||
* are expected to have a short lifetime, and owners should either
|
||||
@@ -666,45 +689,11 @@ public final class MediaStore {
|
||||
(System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS) / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally set the primary directory under which this pending item
|
||||
* should be persisted. Only specific well-defined directories from
|
||||
* {@link Environment} are allowed based on the media type being
|
||||
* inserted.
|
||||
* <p>
|
||||
* For example, when creating pending {@link MediaStore.Images.Media}
|
||||
* items, only {@link Environment#DIRECTORY_PICTURES} or
|
||||
* {@link Environment#DIRECTORY_DCIM} are allowed.
|
||||
* <p>
|
||||
* You may leave this value undefined to store the media in a default
|
||||
* location. For example, when this value is left undefined, pending
|
||||
* {@link MediaStore.Audio.Media} items are stored under
|
||||
* {@link Environment#DIRECTORY_MUSIC}.
|
||||
*
|
||||
* @see MediaColumns#PRIMARY_DIRECTORY
|
||||
*/
|
||||
public void setPrimaryDirectory(@Nullable String primaryDirectory) {
|
||||
if (primaryDirectory == null) {
|
||||
this.insertValues.remove(MediaColumns.PRIMARY_DIRECTORY);
|
||||
public void setRelativePath(@Nullable String relativePath) {
|
||||
if (relativePath == null) {
|
||||
this.insertValues.remove(MediaColumns.RELATIVE_PATH);
|
||||
} else {
|
||||
this.insertValues.put(MediaColumns.PRIMARY_DIRECTORY, primaryDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally set the secondary directory under which this pending item
|
||||
* should be persisted. Any valid directory name is allowed.
|
||||
* <p>
|
||||
* You may leave this value undefined to store the media as a direct
|
||||
* descendant of the {@link #setPrimaryDirectory(String)} location.
|
||||
*
|
||||
* @see MediaColumns#SECONDARY_DIRECTORY
|
||||
*/
|
||||
public void setSecondaryDirectory(@Nullable String secondaryDirectory) {
|
||||
if (secondaryDirectory == null) {
|
||||
this.insertValues.remove(MediaColumns.SECONDARY_DIRECTORY);
|
||||
} else {
|
||||
this.insertValues.put(MediaColumns.SECONDARY_DIRECTORY, secondaryDirectory);
|
||||
this.insertValues.put(MediaColumns.RELATIVE_PATH, relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1470,7 +1459,14 @@ public final class MediaStore {
|
||||
.appendPath("downloads").build();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Get the content:// style URI for a single row in the downloads table
|
||||
* on the given volume.
|
||||
*
|
||||
* @param volumeName the name of the volume to get the URI for
|
||||
* @param id the download to get the URI for
|
||||
* @return the URI to the downloads table on the given volume
|
||||
*/
|
||||
public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
|
||||
return ContentUris.withAppendedId(getContentUri(volumeName), id);
|
||||
}
|
||||
@@ -1795,7 +1791,14 @@ public final class MediaStore {
|
||||
.appendPath("media").build();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Get the content:// style URI for a single row in the images table
|
||||
* on the given volume.
|
||||
*
|
||||
* @param volumeName the name of the volume to get the URI for
|
||||
* @param id the image to get the URI for
|
||||
* @return the URI to the images table on the given volume
|
||||
*/
|
||||
public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
|
||||
return ContentUris.withAppendedId(getContentUri(volumeName), id);
|
||||
}
|
||||
@@ -2282,7 +2285,14 @@ public final class MediaStore {
|
||||
.appendPath("media").build();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Get the content:// style URI for a single row in the audio table
|
||||
* on the given volume.
|
||||
*
|
||||
* @param volumeName the name of the volume to get the URI for
|
||||
* @param id the audio to get the URI for
|
||||
* @return the URI to the audio table on the given volume
|
||||
*/
|
||||
public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
|
||||
return ContentUris.withAppendedId(getContentUri(volumeName), id);
|
||||
}
|
||||
@@ -3031,7 +3041,14 @@ public final class MediaStore {
|
||||
.appendPath("media").build();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* Get the content:// style URI for a single row in the videos table
|
||||
* on the given volume.
|
||||
*
|
||||
* @param volumeName the name of the volume to get the URI for
|
||||
* @param id the video to get the URI for
|
||||
* @return the URI to the videos table on the given volume
|
||||
*/
|
||||
public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) {
|
||||
return ContentUris.withAppendedId(getContentUri(volumeName), id);
|
||||
}
|
||||
@@ -3296,6 +3313,13 @@ public final class MediaStore {
|
||||
return volumeName;
|
||||
}
|
||||
|
||||
private static boolean parseBoolean(@Nullable String value) {
|
||||
if (value == null) return false;
|
||||
if ("1".equals(value)) return true;
|
||||
if ("true".equalsIgnoreCase(value)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return path where the given specific volume is mounted. Not valid for
|
||||
* {@link #VOLUME_INTERNAL} or {@link #VOLUME_EXTERNAL}, since those are
|
||||
|
||||
@@ -87,6 +87,7 @@ import com.android.systemui.util.NotificationChannels;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.text.DateFormat;
|
||||
@@ -254,8 +255,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
|
||||
// Save the screenshot to the MediaStore
|
||||
final MediaStore.PendingParams params = new MediaStore.PendingParams(
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mImageFileName, "image/png");
|
||||
params.setPrimaryDirectory(Environment.DIRECTORY_PICTURES);
|
||||
params.setSecondaryDirectory(Environment.DIRECTORY_SCREENSHOTS);
|
||||
params.setRelativePath(Environment.DIRECTORY_PICTURES + File.separator
|
||||
+ Environment.DIRECTORY_SCREENSHOTS);
|
||||
|
||||
final Uri uri = MediaStore.createPending(context, params);
|
||||
final MediaStore.PendingSession session = MediaStore.openPending(context, uri);
|
||||
|
||||
Reference in New Issue
Block a user