Productivity app for Android I wrote a productivity app for Android. It lets you switch system settings, like Bluetooth, wife, screen brightness, volumes, ringtones, mobile data, airplane mode, etc. Unfortunately I have discovered that device manufacturers modify the OS in every possible way, disabling functionality, requesting additional permissions, or making it available only to system apps. I.e. switching WiFi on stock Android requires android.permission.CHANGE_WIFI_STATE permission, but most Samsung devices also require android.permission.ACCESS_WIFI_STATE. Switching mobile data is simply disabled on many devices.

This makes it impossible to predict how my code will work on a particular device, or on a future version of OS. But at the same time, I definitely don't want my app to crash, because there's really nothing worse that an app can do. So in order to be safe, I've been using what is sometimes called a "Pokemon exception handling" (Gotta catch 'em all!):

try {
    //Do stuff
} catch (Exception e) {
    //Log an error, send crash report, etc.
}
//Keep calm and carry on


I know that this is generally considered a bad practice, but I just can't find a better way to handle this situation. I simply can't predict all possibilities of what could go wrong. Most of my methods for executing actions look something like this:

private boolean switchWiFi(boolean state) {
    try {
        WifiManager wm = (WifiManager)getSystemService(WIFI_SERVICE);
        wm.setWifiEnabled(state);
        return true; //Executed successfully
    } 
    catch (Exception e){
        //Give user a notification about an error, rather than crash
        showErrorNotification("Couldn't switch WiFi.");
        if(BuildConfig.DEBUG){Log.getStackTraceString(e);}//Log exception stack trace
        return false; //Execution failed
    }
}


Is there a better way to handle exceptions?
When the called API throws unknown exceptions I don't think that there is other way than catching all exceptions (sometimes Throwables too). +1 Jeroen Vannevel's comment too.

Anyway, a common interface might be able to improve the code a little bit:

public interface Command {

    run() throws Exception;

    String getName();

}


Then, you can have implementations, like WifiSwitcher, and call them one after the other:

final List&lt;String&gt; errors = new ArrayList&lt;String&gt;();
for (final Command command: commands) {
    try {
        command.run();
    } catch (final Exception e) {
        errors.add("Could not perform command: " + command.getName());
        if (BuildConfig.DEBUG) {
            Log.getStackTraceString(e);
        }
    }
}

if (errors.isEmpty()) {
    return true;
}
showErrorNotification(errors);
return false;


(I haven't tested nor compiled the code above.)