From 2ee3c1e189819cc6efb4d7de24f1438bdb824087 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Fri, 30 May 2014 15:38:35 -0700 Subject: Per-app media directories on external storage. This change defines per-app directories on external storage that will be scanned and included in MediaStore. This gives apps a way to write content to secondary shared storage in a way that can easily be surfaced to other apps. Bug: 14382377 Change-Id: I4cb367c870509e76f0c2c598f01e2f699780030a --- core/java/android/app/ContextImpl.java | 14 +++++++++++ core/java/android/content/Context.java | 35 +++++++++++++++++++++++++++ core/java/android/content/ContextWrapper.java | 5 ++++ core/java/android/os/Environment.java | 4 +++ 4 files changed, 58 insertions(+) (limited to 'core') diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index ff8688d..8ffa6fe 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -249,6 +249,8 @@ class ContextImpl extends Context { private File[] mExternalFilesDirs; @GuardedBy("mSync") private File[] mExternalCacheDirs; + @GuardedBy("mSync") + private File[] mExternalMediaDirs; private static final String[] EMPTY_FILE_LIST = {}; @@ -1032,6 +1034,18 @@ class ContextImpl extends Context { } @Override + public File[] getExternalMediaDirs() { + synchronized (mSync) { + if (mExternalMediaDirs == null) { + mExternalMediaDirs = Environment.buildExternalStorageAppMediaDirs(getPackageName()); + } + + // Create dirs if needed + return ensureDirsExistOrFilter(mExternalMediaDirs); + } + } + + @Override public File getFileStreamPath(String name) { return makeFilename(getFilesDir(), name); } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 2ff85c6..d3a979c 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -40,6 +40,7 @@ import android.os.Looper; import android.os.StatFs; import android.os.UserHandle; import android.os.UserManager; +import android.provider.MediaStore; import android.util.AttributeSet; import android.view.DisplayAdjustments; import android.view.Display; @@ -929,6 +930,40 @@ public abstract class Context { public abstract File[] getExternalCacheDirs(); /** + * Returns absolute paths to application-specific directories on all + * external storage devices where the application can place media files. + * These files are scanned and made available to other apps through + * {@link MediaStore}. + *

+ * This is like {@link #getExternalFilesDirs} in that these files will be + * deleted when the application is uninstalled, however there are some + * important differences: + *

+ *

+ * External storage devices returned here are considered a permanent part of + * the device, including both emulated external storage and physical media + * slots, such as SD cards in a battery compartment. The returned paths do + * not include transient devices, such as USB flash drives. + *

+ * An application may store data on any or all of the returned devices. For + * example, an app may choose to store large files on the device with the + * most available space, as measured by {@link StatFs}. + *

+ * No permissions are required to read or write to the returned paths; they + * are always accessible to the calling app. Write access outside of these + * paths on secondary external storage devices is not available. + *

+ * Returned paths may be {@code null} if a storage device is unavailable. + * + * @see Environment#getExternalStorageState(File) + */ + public abstract File[] getExternalMediaDirs(); + + /** * Returns an array of strings naming the private files associated with * this Context's application package. * diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index c66355b..dbf9122 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -237,6 +237,11 @@ public class ContextWrapper extends Context { } @Override + public File[] getExternalMediaDirs() { + return mBase.getExternalMediaDirs(); + } + + @Override public File getDir(String name, int mode) { return mBase.getDir(name, mode); } diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index e98a26b..e84b695 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -191,6 +191,10 @@ public class Environment { return buildPaths(mExternalDirsForApp, DIR_ANDROID, DIR_MEDIA, packageName); } + public File[] buildExternalStorageAppMediaDirsForVold(String packageName) { + return buildPaths(mExternalDirsForVold, DIR_ANDROID, DIR_MEDIA, packageName); + } + public File[] buildExternalStorageAppObbDirs(String packageName) { return buildPaths(mExternalDirsForApp, DIR_ANDROID, DIR_OBB, packageName); } -- cgit v1.1