Android tiene dos tipos de API a las que no se puede acceder a través del SDK.
El primero se encuentra en el paquete com.android.internal
. El segundo tipo de API es una colección de clases y métodos que están marcados con el atributo @hide Javadoc .
A partir de Android 9 (nivel de API 28), Google introduce nuevas restricciones sobre el uso de interfaces que no pertenecen al SDK , ya sea directamente, mediante reflexión o mediante JNI. Estas restricciones se aplican cada vez que una aplicación hace referencia a una interfaz que no es SDK o intenta obtener su identificador mediante la reflexión o JNI.
Pero antes del nivel de API 28, todavía se podía acceder a los métodos ocultos a través de la reflexión de Java. El @hide
atributo es solo parte de Javadoc (droiddoc también), por lo que @hide
simplemente significa que el método / clase / campo está excluido de los documentos API.
Por ejemplo, el checkUidPermission()
método en ActivityManager.java
usos @hide
:
/** @hide */
public static int checkUidPermission(String permission, int uid) {
try {
return AppGlobals.getPackageManager()
.checkUidPermission(permission, uid);
} catch (RemoteException e) {
// Should never happen, but if it does... deny!
Slog.e(TAG, "PackageManager is dead?!?", e);
}
return PackageManager.PERMISSION_DENIED;
}
Sin embargo, podemos llamarlo por reflexión:
Class c;
c = Class.forName("android.app.ActivityManager");
Method m = c.getMethod("checkUidPermission", new Class[] {String.class, int.class});
Object o = m.invoke(null, new Object[]{"android.permission.READ_CONTACTS", 10010});