Google hat in Android 9 Einschränkungen eingeführt, welche APIs für Entwickler zugänglich sind. So umgehen Sie diese versteckten API-Einschränkungen.
Bereits 2018 veröffentlichte Google Android Pie. Neben den Änderungen an der Benutzeroberfläche und neuen Funktionen gab es auch einige Änderungen auf Entwicklerseite. Zu diesen Änderungen gehörten neue APIs, Bugfixes für bestehende APIs usw Einschränkungen beim Zugriff auf versteckte APIs.
Glücklicherweise gibt es Möglichkeiten, diese Einschränkungen zu umgehen. Bevor ich darauf eingehe, wie man die Einschränkungen umgeht, sollte ich ein wenig erklären, was versteckte APIs sind, warum sie überhaupt eingeschränkt wurden und warum Sie möglicherweise auf sie zugreifen möchten.
Versteckte APIs sind die APIs in Android, die App-Entwickler normalerweise nicht sehen können. Wenn Sie sich den Code von AOSP ansehen, werden Sie eine ganze Reihe von Klassen, Variablen und Methoden sehen, die über eine verfügen @hide
Anmerkung innerhalb eines Kommentarblocks darüber.
Diese Anmerkung weist das Tool an, das Google beim Kompilieren des SDK verwendet, um das darunter liegende Element auszuschließen. Dieses SDK wird dann innerhalb der über Android Studio heruntergeladenen SDKs an Entwickler verteilt. Sofern Sie kein modifiziertes SDK verwenden, geht Android Studio davon aus, dass eines dieser versteckten Elemente einfach nicht existiert. Wenn Sie versuchen, eines direkt zu verwenden, wird es rot angezeigt und die Kompilierung wird abgelehnt.
Es gibt viele Gründe, warum eine API ausgeblendet sein könnte. Einige Dinge sind nur für die Verwendung durch interne oder System-Apps gedacht und funktionieren nicht, wenn sie von einer Drittanbieter-App verwendet werden. Andere sind experimentell oder instabil und werden möglicherweise in Zukunft entfernt oder geändert. Bei einigen handelt es sich lediglich um APIs, auf die Google den normalen Verfallszyklus nicht anwenden möchte, falls sie jemals entfernt werden.
Während das Standard-Android-SDK über eine verfügt viel Darin reicht es manchmal nicht aus. Manchmal möchten Sie etwas tun, das bereits in Android vorhanden ist, aber nicht öffentlich zugänglich gemacht wird.
Zum Beispiel viele der Apps, die ich mache, darunter SystemUI-Tuner Und Sperrbildschirm-Widgets, nutzen Sie eine Reihe verschiedener versteckter APIs. SystemUI Tuner muss auf einige zugreifen, um Optionen ordnungsgemäß verfolgen, ändern und zurücksetzen zu können. Lockscreen Widgets nutzt einige, um unter anderem das Hintergrundbild darunter anzuzeigen.
Die meisten Entwickler müssen nicht auf versteckte APIs zugreifen, aber manchmal können sie sehr nützlich sein.
Mit der Veröffentlichung von Android 9 (Pie) führte Google die versteckte API-Blacklist ein. Nicht jede versteckte API war enthalten und es gab verschiedene Listenebenen. Auf versteckte APIs auf der Whitelist kann jeder zugreifen. Auf versteckte APIs auf der hellgrauen Liste kann von jeder App zugegriffen werden, in zukünftigen Android-Versionen ist der Zugriff jedoch möglicherweise nicht mehr möglich. Auf alles auf der Dunkelgrauliste konnte nur von Apps zugegriffen werden, die auf API-Ebenen vor Pie (d. h. vor API-Ebene 28) abzielen. Apps, die auf Pie und höher abzielen, wird der Zugriff verweigert. Schließlich konnte auf versteckte APIs auf der Blacklist keine App zugreifen, die nicht zum System gehört (oder nicht auf der Whitelist steht), unabhängig von der Ziel-API.
Android 10 hat die Organisation der Listen geändert und sie leicht vereinfacht, aber die Idee ist dieselbe geblieben. Auf bestimmte versteckte APIs konnten Apps zugreifen, während andere blockiert wurden. Android 11 Die Zugriffserkennung wurde verstärkt Zu eine Umgehung blockieren Wird für Kuchen und 10 verwendet.
In allen Android-Versionen gibt Android jedes Mal, wenn eine Drittanbieter-App versucht, auf eine versteckte API auf der schwarzen Liste zuzugreifen, den entsprechenden „Nicht gefunden“-Fehler aus.
Es gibt tatsächlich eine ganze Reihe von Möglichkeiten, die versteckte API-Blacklist zu umgehen. Abhängig von Ihren Anforderungen können Sie diejenigen auswählen, die für alle Android-Versionen funktionieren, solche, die nur für Android 9 und 10 funktionieren, solche, die nativen C++-Code verwenden, und solche, die vollständig Java-basiert sind. Es gibt sogar eine Problemumgehung nur für die Entwicklung mithilfe von ADB.
ADB-Problemumgehung
Wenn auf Ihrem Gerät Android Pie läuft, führen Sie die folgenden zwei ADB-Befehle aus, um den versteckten API-Zugriff zu aktivieren.
adb shell settings put global hidden_api_policy_pre_p_apps 1
adb shell settings put global hidden_api_policy_p_apps 1
Wenn auf Ihrem Gerät Android 10 oder höher ausgeführt wird, führen Sie den folgenden ADB-Befehl aus, um den versteckten API-Zugriff zu aktivieren.
adb shell settings put global hidden_api_policy 1
Um zum Standardverhalten zurückzukehren, ersetzen Sie einfach put
mit delete
und entfernen Sie die 1
.
Offensichtlich sind diese Befehle für eine Produktions-App nicht gerade nützlich. Ich kann Ihnen aus erster Hand sagen, dass es unglaublich schwierig ist, Benutzer richtig in die Verwendung von ADB einzuweisen. Sie können jedoch nützlich sein, wenn Sie eine alte App aktualisieren müssen, um den neuen Einschränkungen zu entsprechen.
Native/JNI-Problemumgehung
Es gibt zwei Möglichkeiten, die versteckte API-Blacklist mithilfe von JNI in Ihrer Android-App zu umgehen. Eines funktioniert für Android 9 und 10, das andere für Android 9 und höher.
Android 9 und 10
Wenn Sie bereits über einen nativen Teil Ihrer App verfügen, ist dies einfach zu implementieren. Benutzen Sie einfach die JNI_OnLoad()
Funktion.
statische Kunst:: Runtime* runtime = nullptr;
extern "C"jint JNI_OnLoad(JavaVM *vm, void *reserved){
...
runtime = reinterpret_cast<: javavmext>(vm)->GetRuntime();
runtime->SetHiddenApiEnforcementPolicy(art:: hiddenapi:: EnforcementPolicy:: kNoChecks);
...
}
Beachten Sie, dass diese Methode nur auf Android 9 und 10 funktioniert.
Android 9 und höher
Für jede Android-Version haben Sie die Wahl zwischen zwei Bibliotheken, um die versteckte API-Einschränkung zu umgehen: FreeReflection und RestrictionBypass.
Beide sind einfach zu implementieren und zu verwenden.
Um FreeReflection zu implementieren, fügen Sie die Abhängigkeit zu Ihrem build.gradle auf Modulebene hinzu.
implementation 'me.weishu: free_reflection: 3.0.1'
Dann überschreiben attachBaseContext()
in Ihrer Anwendungsklasse.
@Override
protectedvoidattachBaseContext(Context base){
super.attachBaseContext(base);
Reflection.unseal(base);
}
Wenn Sie keine Anwendungsklasse haben, können Sie diese ganz einfach hinzufügen. Erstellen Sie eine neue Klasse, die erweitert wird Application
und zeigen Sie dann in Ihrer AndroidManifest.xml darauf.
Beispiel:
publicclassAppextendsApplication{
...
@Override
protectedvoidattachBaseContext(Context base){
super.attachBaseContext(base);
Reflection.unseal(base);
}
}
<manifest>
...
...
name=".App">
...
application>
manifest>
Um RestrictionBypass zu implementieren, fügen Sie das JitPack-Repository zu Ihrem build.gradle auf Projektebene hinzu.
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Fügen Sie dann die Abhängigkeit zu Ihrem build.gradle auf Modulebene hinzu.
implementation 'com.github.ChickenHook: RestrictionBypass: 2.2'
Und das ist es. Diese Bibliothek entfernt automatisch die Blacklist-Einschränkungen.
Java-Problemumgehung
Obwohl die JNI-Lösungen effektiv sind, kann es vorkommen, dass Sie keinen nativen Code verwenden möchten. Wenn Sie noch nicht in C++ arbeiten, kann dies zu unnötiger Größe und Plattformeinschränkungen für Ihre App führen. Glücklicherweise gibt es Möglichkeiten, die versteckte API-Blacklist nur mit Java zu umgehen.
Android 9 und 10
In Android 9 und 10 können Sie eine sogenannte Doppelreflexion oder Metareflexion verwenden, um die versteckte API-Blacklist zu umgehen. Da das System nur prüft, welche Apps von Drittanbietern aufrufen, wird es durch die Doppelreflexion zu der Annahme verleitet, dass das System die versteckten API-Aufrufe durchführt.
Mit diesem Trick können Sie eine Methode aufrufen, um Ihrer App versteckte API-Ausnahmen mit passendem Namen zu geben setHiddenApiExemptions()
. Fügen Sie einfach den folgenden Code zu einem frühen Zeitpunkt im Lebenszyklus Ihrer App hinzu (z. B. bei der Anwendung). onCreate()
Methode) und übernimmt die Umgehung der Blacklist.
Method forName = Class.class.getDeclaredMethod("forName", String.class);
Method getDeclaredMethod = Class.class.getDeclaredMethod("getDeclaredMethod", String.class, Class[].class);Class vmRuntimeClass = (Class) forName.invoke(null, "dalvik.system.VMRuntime");
Method getRuntime = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "getRuntime", null);
Method setHiddenApiExemptions = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "setHiddenApiExemptions", newClass[] { String[].class} );
Object vmRuntime = getRuntime.invoke(null);
setHiddenApiExemptions.invoke(vmRuntime, newString[][] { newString[] { "L" } });
Wenn Ihre App mit Android-Versionen unter 9 kompatibel ist, denken Sie daran, dies in eine Versionsprüfung einzubinden.
Android 9 und höher
Um die versteckte API-Blacklist auf Android 9 und späteren Versionen zu umgehen, können Sie die Bibliothek von LSPosed verwenden. Diese Bibliothek verwendet die unsichere API von Java, daher ist es unwahrscheinlich, dass sie jemals kaputt geht.
Um es zu implementieren, fügen Sie einfach die Abhängigkeit zu Ihrem build.gradle auf Modulebene hinzu.
implementation 'org.lsposed.hiddenapibypass: hiddenapibypass: 2.0'
Dann nutzen Sie es, um die Blacklist zu umgehen.
HiddenApiBypass.addHiddenApiExemptions("L");
Wenn Ihre App mit Android-Versionen unter 9 kompatibel ist, denken Sie daran, dies in eine Versionsprüfung einzubinden.
Fazit und weitere Informationen
Es gibt viele Möglichkeiten, die versteckte API-Blacklist auf Android zu umgehen, unabhängig davon, welche Plattformversion Sie anstreben oder verwenden. Wenn Sie mehr über die Funktionsweise dieser Methoden und Bibliotheken erfahren möchten, schauen Sie sich unbedingt die folgenden Links an.
- Meine Fragen und Antworten zum Stapelüberlauf.
- Die Hidden API Bypass-Bibliothek von LSposed auf GitHub.
- Die RestrictionBypass-Bibliothek von ChickenHook auf GitHub.
- tianns FreeReflection-Bibliothek auf GitHub.
- Googles Dokumentation zur versteckten API-Blacklist.