9

I am writing an android app that stores a lot of media files. They are not the type (and are far too many) to clutter up the users notification or other media directories, but they also must be user-updatable, so I can't put them in the resources. I can use getExternalFilesDir to get a path on the sdcard, but I only want to do that if the app itself is installed on the sdcard. If the app is installed internally, I want to put the media in the internal memory.

So how can I determine if my app is running in internal or external memory?

ProgrammerTim
  • 91
  • 1
  • 2

3 Answers3

9

You could use PackageManager to get the ApplicationInfo, and from there check the "flags" for FLAG_EXTERNAL_STORAGE.

Here's a quick example I made to demonstrate:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    PackageManager pm = getPackageManager();
    try {
       PackageInfo pi = pm.getPackageInfo("com.totsp.helloworld", 0);
       ApplicationInfo ai = pi.applicationInfo;
       // this only works on API level 8 and higher (check that first)
       Toast
                .makeText(
                         this,
                         "Value of FLAG_EXTERNAL_STORAGE:"
                                  + ((ai.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == ApplicationInfo.FLAG_EXTERNAL_STORAGE),
                         Toast.LENGTH_LONG).show();
    } catch (NameNotFoundException e) {
       // do something
    }
}

Still, depending on your situation (whether or not you have all the "media" up front, or the user gets/creates it as they use the app), you may want to put it on the external storage regardless. A large size internal app is frowned upon by many users (and a lot of internal media would probably make it huge).

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Charlie Collins
  • 8,806
  • 4
  • 32
  • 41
3

Here is my code for checking if app is installed on SD card:

  /**
   * Checks if the application is installed on the SD card.
   * 
   * @return <code>true</code> if the application is installed on the sd card
   */
  public static boolean isInstalledOnSdCard() {

    Context context = MbridgeApp.getContext();
    // check for API level 8 and higher
    if (VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
      PackageManager pm = context.getPackageManager();
      try {
        PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
        ApplicationInfo ai = pi.applicationInfo;
        return (ai.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == ApplicationInfo.FLAG_EXTERNAL_STORAGE;
      } catch (NameNotFoundException e) {
        // ignore
      }
    }

    // check for API level 7 - check files dir
    try {
      String filesDir = context.getFilesDir().getAbsolutePath();
      if (filesDir.startsWith("/data/")) {
        return false;
      } else if (filesDir.contains("/mnt/") || filesDir.contains("/sdcard/")) {
        return true;
      }
    } catch (Throwable e) {
      // ignore
    }

    return false;
  }
Brais Gabin
  • 5,827
  • 6
  • 57
  • 92
peceps
  • 17,370
  • 11
  • 72
  • 79
  • 1. Checking `/mnt` and `/sdcard` seems hacky - why don't you use the directories from the `Environment` class? 2. I haven't tried it myself, isn't the files directory always on internal storage? What's the point of the second check? Pre-Froyo can't install to SD card anyway. Or did you add that to handle the case of ROMs like CyanogenMod that had their own app2sd implementation? – EboMike Jan 06 '12 at 07:08
  • 1. You are right, using Environment.EXTERNAL_STORAGE_DIRECTORY is better. 2. I think no if the app is installed on SD. And yes, the second check is for modified ROMS. – peceps Jan 09 '12 at 10:09
0

To Check application is installed in SD Card or not, just do this:

ApplicationInfo io = context.getApplicationInfo();

if(io.sourceDir.startsWith("/data/")) {

//application is installed in internal memory

} else if(io.sourceDir.startsWith("/mnt/") || io.sourceDir.startsWith("/sdcard/")) {

//application is installed in sdcard(external memory)

}
E Player Plus
  • 1,836
  • 16
  • 21
  • It can be installed as system app. You need check `.startsWith("/system/")` in this case. – Enyby Mar 12 '16 at 20:31