package org.commcare.utils;
import android.os.Environment;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author wspride
*/
public class ReflectionUtil {
private static Method mExternalStorageEmulated;
static {
initCompatibility();
}
private static void initCompatibility() {
try {
mExternalStorageEmulated =
Environment.class.getMethod("isExternalStorageEmulated");
/* success, this is a newer device */
} catch (NoSuchMethodException nsme) {
/* failure, must be older device */
}
}
/**
* @return true if the external storage is being emulated, false otherwise.
* Uses reflection since the isExternalStorageEmulated won't exist on
* Android APIs 10 or below
*/
private static boolean mIsExternalStorageEmulated() throws IOException {
try {
Object obj = mExternalStorageEmulated.invoke(null);
return (Boolean)obj;
} catch (InvocationTargetException ite) {
/* unpack original exception when possible */
Throwable cause = ite.getCause();
if (cause instanceof IOException) {
throw (IOException)cause;
} else if (cause instanceof RuntimeException) {
throw (RuntimeException)cause;
} else if (cause instanceof Error) {
throw (Error)cause;
} else {
/* unexpected checked exception; wrap and re-throw */
throw new RuntimeException(ite);
}
} catch (IllegalAccessException | ClassCastException ie) {
System.err.println("unexpected " + ie);
throw new RuntimeException(ie);
}
}
/**
* Helper method for mIsExternalStorageEmulated that checks to see if the
* method exists; if it does not, then we return false because emulation is
* not possible in this case. If it is not null, then the storage is
* potentially emulated, and we check whether it actually is being emualted
* or not. If we run into problems calling this method, we play it safe
* and return true so that we don't make any unsafe assumptions
*/
public static boolean mIsExternalStorageEmulatedHelper() {
if (mExternalStorageEmulated != null) {
/* feature is supported */
try {
return mIsExternalStorageEmulated();
} catch (RuntimeException e) {
return true;
} catch (IOException ie) {
return true;
}
} else {
/* external SD emulation not possible, return false */
return false;
}
}
}