8

Tôi đang viết một ứng dụng Android lưu trữ nhiều tệp phương tiện. Chúng không phải là loại (và quá nhiều) để làm lộn xộn thông báo người dùng hoặc các thư mục phương tiện khác, nhưng chúng cũng phải được người dùng cập nhật, vì vậy tôi không thể đặt chúng vào tài nguyên. Tôi có thể sử dụng getExternalFilesDir để có được một con đường trên sdcard, nhưng tôi chỉ muốn làm điều đó nếu bản thân ứng dụng được cài đặt trên sdcard. Nếu ứng dụng được cài đặt trong nội bộ, tôi muốn đặt phương tiện vào bộ nhớ trong.Android 2.2 - Làm cách nào để phát hiện xem tôi có được cài đặt trên SDCard hay không?

Vậy làm cách nào để xác định xem ứng dụng của tôi có đang chạy trong bộ nhớ trong hay bộ nhớ ngoài không?

Trả lời

9

Bạn có thể sử dụng PackageManager để lấy ApplicationInfo và từ đó kiểm tra "cờ" cho FLAG_EXTERNAL_STORAGE.

Dưới đây là một ví dụ nhanh tôi đã thực hiện để chứng minh:

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

Tuy nhiên, tùy thuộc vào tình hình của bạn (hay không, bạn có tất cả các "phương tiện truyền thông" lên phía trước, hoặc người dùng bị/tạo ra nó khi họ sử dụng ứng dụng), bạn có thể muốn đặt nó trên bộ nhớ ngoài bất kể. Một ứng dụng nội bộ kích thước lớn được nhiều người dùng cau mày (và rất nhiều phương tiện truyền thông nội bộ có thể sẽ làm cho nó trở nên rất lớn).

3

Đây là mã của tôi để kiểm tra nếu ứng dụng được cài đặt trên thẻ 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. Kiểm tra '/mnt' và '/ sdcard' có vẻ như hacky - tại sao bạn không sử dụng các thư mục từ lớp' Environment'? 2. Tôi chưa thử nó, không phải là thư mục tập tin luôn luôn lưu trữ nội bộ? Điểm kiểm tra thứ hai là gì? Pre-Froyo không thể cài đặt vào thẻ SD. Hoặc bạn đã thêm rằng để xử lý các trường hợp của ROM như CyanogenMod đã thực hiện app2sd của riêng mình? – EboMike

+0

1. Bạn đúng, sử dụng Environment.EXTERNAL_STORAGE_DIRECTORY là tốt hơn. 2. Tôi nghĩ không nếu ứng dụng được cài đặt trên SD. Và có, kiểm tra thứ hai là cho ROMS sửa đổi. – peceps

0

Để Kiểm tra ứng dụng được cài đặt trong thẻ nhớ SD hay không, chỉ cần làm điều này:

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

Nó có thể được cài đặt như ứng dụng hệ thống. Bạn cần kiểm tra '.startsWith ("/system/")' trong trường hợp này. – Enyby

Các vấn đề liên quan