8

Ich schreibe eine Android App, die viele Mediendateien speichert. Sie sind nicht der Typ (und sind viel zu viele), um die Benutzerbenachrichtigung oder andere Medienverzeichnisse zu überladen, aber sie müssen auch vom Benutzer aktualisierbar sein, so dass ich sie nicht in die Ressourcen einfügen kann. Ich kann getExternalFilesDir verwenden, um einen Pfad auf der SD-Karte zu bekommen, aber ich möchte das nur tun, wenn die App selbst auf der SD-Karte installiert ist. Wenn die App intern installiert ist, möchte ich das Medium in den internen Speicher legen.Android 2.2 - Wie erkenne ich, ob ich auf der SD-Karte installiert bin oder nicht?

Wie kann ich feststellen, ob meine App im internen oder externen Speicher ausgeführt wird?

Antwort

9

Sie können PackageManager verwenden, um die ApplicationInfo abzurufen, und von dort aus überprüfen Sie die "Flags" für .

Hier ist ein kurzes Beispiel zeige ich gemacht:

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

Dennoch je nach Ihrer Situation (ob Sie alle „Medien“ vorne haben, oder der Benutzer erhält/schafft es, wie sie verwenden die App), möchten Sie es trotzdem auf den externen Speicher legen. Eine große interne App ist von vielen Nutzern verpönt (und viele interne Medien würden es wahrscheinlich riesig machen).

3

Hier ist mein Code zu überprüfen, ob App auf SD-Karte installiert ist:

/** 
    * 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. Checking '/mnt' und '/ sdcard' scheint hacky - warum benutzen Sie nicht die Verzeichnisse aus der' Environment' Klasse? 2. Ich habe es selbst nicht ausprobiert, ist das Dateiverzeichnis nicht immer im internen Speicher? Was ist der Sinn des zweiten Checks? Pre-Froyo kann sowieso nicht auf SD-Karte installiert werden. Oder haben Sie das hinzugefügt, um den Fall von ROMs wie CyanogenMod zu behandeln, die ihre eigene app2sd-Implementierung hatten? – EboMike

+0

1. Sie haben Recht, mit Environment.EXTERNAL_STORAGE_DIRECTORY ist besser. 2. Ich denke nicht, wenn die App auf SD installiert ist. Und ja, die zweite Überprüfung ist für modifizierte ROMS. – peceps

0

Anwendung überprüfen in SD-Karte installiert ist oder nicht, tun gerade dies:

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

Es kann als System-App installiert werden. Sie müssen '.startsWith ("/system/")' in diesem Fall überprüfen. – Enyby