Mi aplicación tiene una cierta funcionalidad que solo funcionará en un dispositivo donde la raíz esté disponible. En lugar de que esta característica falle cuando se usa (y luego muestra un mensaje de error apropiado al usuario), preferiría una capacidad de 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?
Respuestas:
Aquí hay una clase que verificará para Root una de tres maneras.
fuente
su
binario mientras no están rooteados.Si ya está utilizando Fabric / Firebase Crashlytics, puede llamar
Esta es la implementación actual de ese método:
fuente
La biblioteca RootTools ofrece métodos simples para verificar la raíz:
Referencia
fuente
En mi aplicación estaba comprobando si el dispositivo está rooteado o no ejecutando el comando "su". Pero hoy he eliminado esta parte de mi código. ¿Por qué?
Porque mi aplicación se convirtió en un asesino de la memoria. ¿Cómo? Déjame contarte mi historia.
Hubo algunas quejas de que mi aplicación estaba ralentizando dispositivos (por supuesto, pensé que eso no puede ser cierto). Traté de entender por qué. Así que utilicé MAT para obtener volcados del montón y analizar, y todo parecía perfecto. Pero después de reiniciar mi aplicación muchas veces, me di cuenta de que el dispositivo realmente se está volviendo más lento y detener mi aplicación no lo hizo más rápido (a menos que reinicie el dispositivo). Analicé los archivos de volcado nuevamente mientras el dispositivo es muy lento. Pero todo seguía siendo perfecto para el archivo de volcado. Luego hice lo que debía hacerse al principio. Enumeré los procesos.
Sorpresa; hubo muchos procesos para mi aplicación (con la etiqueta de proceso de mi aplicación en el manifiesto). Algunos de ellos eran zombis, otros no.
Con una aplicación de muestra que tiene una sola Actividad y ejecuta solo el comando "su", me di cuenta de que se está creando un proceso zombie en cada lanzamiento de la aplicación. Al principio, estos zombis asignan 0 KB pero luego sucede algo y los procesos de zombis contienen casi los mismos KB que el proceso principal de mi aplicación y se convirtieron en procesos estándar.
Hay un informe de error para el mismo problema en bugs.sun.com: http://bugs.sun.com/view_bug.do?bug_id=6474073 esto explica si no se encuentra el comando, se crearán zombis con el método exec () . Pero todavía no entiendo por qué y cómo pueden convertirse en procesos estándar y tener KB significativos. (Esto no sucede todo el tiempo)
Puede probar si lo desea con el ejemplo de código a continuación;
Método de ejecución de comando simple;
Para resumir; No tengo consejos para determinar si el dispositivo está rooteado o no. Pero si fuera usted, no usaría Runtime.getRuntime (). Exec ().
Por cierto; RootTools.isRootAvailable () causa el mismo problema.
fuente
Muchas de las respuestas enumeradas aquí tienen problemas inherentes:
La biblioteca RootTools de Stericson parece estar buscando la raíz de manera más legítima. También tiene muchas herramientas y utilidades adicionales, así que lo recomiendo encarecidamente. Sin embargo, no hay una explicación de cómo verifica específicamente la raíz, y puede ser un poco más pesado de lo que la mayoría de las aplicaciones realmente necesitan.
He hecho un par de métodos de utilidad que se basan libremente en la biblioteca RootTools. Si simplemente desea verificar si el ejecutable "su" está en el dispositivo, puede usar el siguiente método:
Este método simplemente recorre los directorios listados en la variable de entorno "PATH" y verifica si existe un archivo "su" en uno de ellos.
Para verificar verdaderamente el acceso a la raíz, el comando "su" debe ejecutarse realmente. Si se instala una aplicación como SuperUser, en este punto puede solicitar acceso a la raíz, o si ya se le ha otorgado / denegado, se puede mostrar un brindis que indica si el acceso fue otorgado / denegado. Un buen comando para ejecutar es "id" para que pueda verificar que el ID de usuario es de hecho 0 (root).
Aquí hay un método de muestra para determinar si se ha otorgado acceso root:
Es importante probar realmente ejecutar el comando "su" porque algunos emuladores tienen el ejecutable "su" preinstalado, pero solo permiten que ciertos usuarios accedan a él como el shell adb.
También es importante verificar la existencia del ejecutable "su" antes de intentar ejecutarlo, ya que se sabe que Android no elimina correctamente los procesos que intentan ejecutar comandos faltantes. Estos procesos fantasmas pueden aumentar el consumo de memoria con el tiempo.
fuente
Actualización 2017
Puede hacerlo ahora con la API de Google Safetynet . SafetyNet API proporciona API de certificación que le ayuda a evaluar la seguridad y la compatibilidad de los entornos de Android en los que se ejecutan sus aplicaciones.
Esta certificación puede ayudar a determinar si el dispositivo en particular ha sido manipulado o modificado de otra manera.
La API de certificación devuelve una respuesta JWS como esta
Analizar esta respuesta puede ayudarlo a determinar si el dispositivo está rooteado o no
Puede hacerlo en el lado del cliente, pero se recomienda analizar la respuesta en el lado del servidor. Una arquitectura básica de servidor cliente con API de red de seguridad se verá así:
fuente
La verificación de raíz a nivel de Java no es una solución segura. Si su aplicación tiene problemas de seguridad para ejecutarse en un dispositivo rooteado, utilice esta solución.
La respuesta de Kevin funciona a menos que el teléfono también tenga una aplicación como RootCloak. Dichas aplicaciones tienen una API Handle over Java una vez que el teléfono está rooteado y se burlan de estas API para que el teléfono no esté rooteado.
He escrito un código de nivel nativo basado en la respuesta de Kevin, ¡funciona incluso con RootCloak! Además, no causa problemas de pérdida de memoria.
En su código Java, debe crear RootUtils de clase de contenedor para realizar las llamadas nativas
fuente
http://code.google.com/p/roottools/
Si no desea utilizar el archivo jar, simplemente use el código:
El programa intentará encontrar su carpeta:
Ejemplo:
fuente
checkRootMethod4()
con la respuesta de Kevin .== true
a un booleano, no agrega nada y no se ve bien.if (isRooted())
marque en lugar de escribir explícitamente verdadero. Es mejor seguir los patrones de escritura de códigoEn lugar de usar isRootAvailable (), puede usar isAccessGiven (). Directo del wiki de RootTools :
Referencia
fuente
Algunas compilaciones modificadas se utilizan para establecer la propiedad del sistema
ro.modversion
para este propósito. Las cosas parecen haber seguido adelante; mi versión de TheDude hace unos meses tiene esto:El emulador del SDK 1.5, por otro lado, que ejecuta la imagen 1.5, también tiene root, es probablemente similar al Android Dev Phone 1 (que presumiblemente desea permitir) y tiene esto:
En cuanto a las compilaciones minoristas, no tengo una a mano, pero varias búsquedas a continuación
site:xda-developers.com
son informativas. Aquí hay un G1 en los Países Bajos , puede ver quero.build.tags
no tienetest-keys
, y creo que esa es probablemente la propiedad más confiable para usar.fuente
RootBeer es una biblioteca de Android que verifica la raíz de Scott y Matthew. Utiliza varias comprobaciones para indicar si el dispositivo está rooteado o no.
fuente
Sugiero usar código nativo para la detección de raíz. Aquí hay un ejemplo de trabajo completo .
Envoltura de JAVA :
JNI wrapper (native-lib.c) :
constantes:
detecciones de raíz del código nativo:
fuente
Aquí está mi código basado en algunas respuestas aquí:
fuente
Además de la respuesta de @Kevins, recientemente descubrí que mientras usaba su sistema, el Nexus 7.1 regresaba
false
para los tres métodos: sinwhich
comando, notest-keys
ySuperSU
no estaba instalado/system/app
.Agregué esto:
Esto es un poco menos útil en algunas situaciones (si necesita acceso root garantizado), ya que es completamente posible que SuperSU se instale en dispositivos que no tienen acceso SU.
Sin embargo, dado que es posible tener SuperSU instalado y funcionando pero no en el
/system/app
directorio, este caso adicional eliminará (jaja) tales casos.fuente
fuente
Dos ideas adicionales, si desea verificar si un dispositivo es capaz de rootear desde su aplicación:
Runtime.getRuntime().exec()
/system/app/Superuser.apk
ubicaciónfuente
Usar C ++ con el ndk es el mejor enfoque para detectar root incluso si el usuario está usando aplicaciones que ocultan su root, como RootCloak. Probé este código con RootCloak y pude detectar la raíz incluso si el usuario está tratando de ocultarlo. Entonces su archivo cpp quisiera:
Y llamará a la función desde su código java de la siguiente manera
fuente
fuente
Existe la API Safety Net Attestation de los servicios de Google Play mediante la cual podemos evaluar el dispositivo y determinar si está rooteado / manipulado.
Consulte mi respuesta para tratar con dispositivos rooteados:
https://stackoverflow.com/a/58304556/3908895
fuente
Olvídate de todo lo que detecta aplicaciones raíz y binarios su. Verifique el proceso del demonio raíz. Esto se puede hacer desde el terminal y puede ejecutar comandos de terminal dentro de una aplicación. Prueba este one-liner.
Tampoco necesita permiso de root para lograr esto.
fuente
De hecho, es una pregunta interesante y hasta ahora nadie ha merecido un premio. Yo uso el siguiente código:
El código ciertamente no es a prueba de balas, porque la red puede no estar disponible, por lo que obtendrá una excepción. Si este método devuelve verdadero, entonces el 99% puede estar seguro, de lo contrario solo el 50% no. El permiso de red también puede estropear la solución.
fuente
Usar mi biblioteca en rootbox es bastante fácil. Verifique el código requerido a continuación:
fuente