8

Piszę aplikację na Androida, która przechowuje wiele plików multimedialnych. Nie są typem (i są o wiele za dużo), aby zaśmiecać powiadomienia użytkowników lub inne katalogi multimedialne, ale muszą też być aktualizowane przez użytkownika, więc nie mogę ich umieścić w zasobach. Mogę użyć getExternalFilesDir, aby uzyskać ścieżkę na sdcard, ale chcę to zrobić tylko, jeśli sama aplikacja jest zainstalowana na sdcard. Jeśli aplikacja jest zainstalowana wewnętrznie, chcę umieścić media w pamięci wewnętrznej.Android 2.2 - Jak wykryć, czy jestem zainstalowany na karcie SD, czy nie?

Jak mogę sprawdzić, czy moja aplikacja działa w pamięci wewnętrznej czy zewnętrznej?

Odpowiedz

9

Możesz użyć programu PackageManager, aby pobrać ApplicationInfo, a następnie sprawdzić "flagi" dla FLAG_EXTERNAL_STORAGE.

Oto krótki przykład zrobiłem wykazać:

@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 
    } 
} 

Mimo to, w zależności od sytuacji (czy masz wszystkie „media” z góry, czy użytkownik pobiera/tworzy go jak korzystać aplikacja), niezależnie od tego można go umieścić w pamięci zewnętrznej. Wewnętrzna aplikacja o dużych rozmiarach jest mile widziana przez wielu użytkowników (a wiele wewnętrznych multimediów prawdopodobnie sprawiłoby, że byłaby ona olbrzymia).

3

Oto mój kod do sprawdzania, czy aplikacja jest zainstalowana na karcie SD:

/** 
    * 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; 
    } 
+0

1. Sprawdzenie '/mnt' i '/ sdcard' wydaje się być hacky - dlaczego nie używasz katalogów z klasy' Środowisko'? 2. Nie próbowałem tego sam, czy katalog plików nie zawsze znajduje się w pamięci wewnętrznej? Jaki jest sens drugiego czeku? Pre-Froyo i tak nie można zainstalować na karcie SD. Czy dodałeś to do obsługi przypadku ROM-ów, takich jak CyanogenMod, które miały własną implementację app2sd? – EboMike

+0

1. Masz rację, używając Environment.EXTERNAL_STORAGE_DIRECTORY jest lepiej. 2. Myślę, że nie, jeśli aplikacja jest zainstalowana na SD. I tak, druga kontrola dotyczy zmodyfikowanych ROM-ów. – peceps

0

Aby sprawdzić aplikacja jest zainstalowana na karcie SD lub nie, po prostu to zrobić:

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) 

} 
+0

Może być zainstalowany jako aplikacja systemowa. Musisz w tym przypadku sprawdzić '.startsWith ("/system/")'. – Enyby