Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Wait for external storage to ready

I'm currently developing a live wallpaper that reads from external storage. When the device is booting up, I assume it's possible for the live wallpaper to be launched before the storage is ready. Especially if its doing the periodic error check. Others are reporting issues and I think this is the reason. I can't seem to test this, because the external storage seems to mount instantly on my device, and I'm not sure how to force it to do the error check. So my first question is, does the system actually way for the BOOT_COMPLETED intent before it launches the live wallpaper.

If not, what is the proper way to wait for the external storage to be ready. I'm thinking of calling something like this in the beginning of the app

public void waitForExternalStorage()
{
    while(Environment.getExternalStorageState().equals(Environment.MEDIA_CHECKING))
    {
        try { Thread.sleep(1000L); }
        catch(InterruptedException e) { e.printStackTrace(); }
    }
}

Do I have to check for other cases, in case it goes MEDIA_REMOVED -> MEDIA_UNMOUNTED -> MEDIA_CHECKING(optional) -> MEDIA_READY on boot?

like image 977
terryhau Avatar asked Oct 05 '12 14:10

terryhau


3 Answers

You can register a BroadcastReceiver to listen to changes in the external storage state:

BroadcastReceiver externalStorageStateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        updateExternalStorageState();
    }
};

IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
registerReceiver(mExternalStorageReceiver, filter);
updateExternalStorageState(); // You can initialize the state here, before any change happens

And in updateExternalStorageState() you can check the actual state after the change:

protected void updateExternalStorageState() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        // SD card is mounted and ready for use
    } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        // SD card is mounted, but it is read only
    } else {
        // SD card is unavailable
    }
}
like image 171
Adam Monos Avatar answered Sep 24 '22 13:09

Adam Monos


use broadcast receiver, listen for Intent.ACTION_MEDIA_MOUNTED : Broadcast Action: External media is present and mounted at its mount point.

like image 20
Buda Gavril Avatar answered Sep 22 '22 13:09

Buda Gavril


I needed exactly that. I am reading a configuration file from the SD card and my on-boot running app simply cannot run without reading it. A simple solution is to wait a maximum of 15-30 seconds for the SD card to be automatically mounted by the Android OS. If not, throw an exception. Here's the code. Just increase the max count limit to increase the wait time. The ExternalStorageNotReadyException is a custom exception.

public void awaitExternalStorageInitialization()
        throws ExternalStorageNotReadyException {
    boolean mExternalStorageAvailable = false;
    boolean mExternalStorageWriteable = false;
    int count = 0;

    do {
        String state = Environment.getExternalStorageState();
        if(count > 0) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                Log.e(Constants.LOG_TAG, e.getMessage(), e);
            }
        }
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            // We can read and write the media
            mExternalStorageAvailable = mExternalStorageWriteable = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            // We can only read the media
            mExternalStorageAvailable = true;
            mExternalStorageWriteable = false;
        } else {
            // Something else is wrong. It may be one of many other states,
            // but all we need
            // to know is we can neither read nor write
            mExternalStorageAvailable = mExternalStorageWriteable = false;
        }
        count++;
    } while ((!mExternalStorageAvailable) && (!mExternalStorageWriteable) && (count < 5));
    if(!mExternalStorageWriteable)
        throw new ExternalStorageNotReadyException("External storage device (SD Card) not yet ready");
}
like image 45
Srikanth Avatar answered Sep 24 '22 13:09

Srikanth