Determinar si se ejecuta en un dispositivo rooteado
Mi aplicación tiene una determinada funcionalidad que solo funcionará en un dispositivo donde la raíz esté disponible. En lugar de que esta función falle cuando se usa (y luego mostrar un mensaje de error apropiado al usuario), preferiría poder verificar silenciosamente si la raíz está disponible primero y, si no, ocultar las opciones respectivas en primer lugar. .
¿Hay alguna forma de hacer esto?
Aceptado
Aquí hay una clase que verificará la raíz de una de tres maneras.
/** @author Kevin Kowalewski */
public class RootUtil {
public static boolean isDeviceRooted() {
return checkRootMethod1() || checkRootMethod2() || checkRootMethod3();
}
private static boolean checkRootMethod1() {
String buildTags = android.os.Build.TAGS;
return buildTags != null && buildTags.contains("test-keys");
}
private static boolean checkRootMethod2() {
String[] paths = { "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su",
"/system/bin/failsafe/su", "/data/local/su", "/su/bin/su"};
for (String path : paths) {
if (new File(path).exists()) return true;
}
return false;
}
private static boolean checkRootMethod3() {
Process process = null;
try {
process = Runtime.getRuntime().exec(new String[] { "/system/xbin/which", "su" });
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
if (in.readLine() != null) return true;
return false;
} catch (Throwable t) {
return false;
} finally {
if (process != null) process.destroy();
}
}
}
Si ya está utilizando Fabric/Firebase Crashlytics, puede llamar
CommonUtils.isRooted(context)
Esta es la implementación actual de ese método:
public static boolean isRooted(Context context) {
boolean isEmulator = isEmulator(context);
String buildTags = Build.TAGS;
if (!isEmulator && buildTags != null && buildTags.contains("test-keys")) {
return true;
} else {
File file = new File("/system/app/Superuser.apk");
if (file.exists()) {
return true;
} else {
file = new File("/system/xbin/su");
return !isEmulator && file.exists();
}
}
}
public static boolean isEmulator(Context context) {
String androidId = Secure.getString(context.getContentResolver(), "android_id");
return "sdk".equals(Build.PRODUCT) || "google_sdk".equals(Build.PRODUCT) || androidId == null;
}