Android ha due tipi di API che non sono accessibili tramite SDK.
Il primo si trova nel pacchetto com.android.internal
. Il secondo tipo di API è una raccolta di classi e metodi contrassegnati con l' attributo @hide Javadoc .
A partire da Android 9 (livello API 28), Google introduce nuove restrizioni sull'utilizzo di interfacce non SDK , sia direttamente, tramite reflection, sia tramite JNI. Queste restrizioni vengono applicate ogni volta che un'app fa riferimento a un'interfaccia non SDK o tenta di ottenere il relativo handle utilizzando la reflection o JNI.
Ma prima del livello API 28, era ancora possibile accedere ai metodi nascosti tramite la riflessione Java. L' @hide
attributo è solo una parte di Javadoc (anche droiddoc), quindi @hide
significa semplicemente che il metodo / classe / campo è escluso dai documenti dell'API.
Ad esempio, il checkUidPermission()
metodo in ActivityManager.java
utilizza @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;
}
Tuttavia, possiamo chiamarlo per riflessione:
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});