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?
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
}
}
use broadcast receiver, listen for Intent.ACTION_MEDIA_MOUNTED
: Broadcast Action: External media is present and mounted at its mount point.
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");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With