Ich möchte die unter Einstellungen -> Option "Eingabehilfen" aufgeführten Eingabehilfedienste programmatisch aktivieren/deaktivieren.
Ich könnte Accessibility Intent wie folgt starten:
Intent intent = new Intent(Android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivityForResult(intent, 0);
Ich habe jedoch keine Idee, wie die in der Ansicht aufgeführten Dienste durch meinen Code aktiviert werden können.
Bitte geben Sie mir Ihre Ansichten.
Ich fand eine Lösung für mich, indem ich anrief
Settings.Secure.putString(getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "pkgname/classname");
Settings.Secure.putString(getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, "1");
Dabei ist pkgname
der Name Ihres Pakets und classname
der Klassenname Ihres Accessibility-Services.
Wenn Sie mehrere Dienste aktivieren müssen oder die vorherigen Einstellungen nicht ändern möchten, möchten Sie möglicherweise :
verwenden, um andere Dienste zu trennen.
Sie müssen möglicherweise auch als system-Anwendung ausgeführt werden und benötigen möglicherweise die folgenden Berechtigungen
<uses-permission Android:name="Android.permission.WRITE_SETTINGS" />
<uses-permission Android:name="Android.permission.WRITE_SECURE_SETTINGS" />
Laut @Rupert Rawnsley funktioniert dies jedoch möglicherweise nicht für einige Android-Versionen. Ich arbeite an Android 4.0.4 und hoffe, dass es für Sie funktioniert.
PS. Wenn es nicht funktioniert, könnten Sie vielleicht etwas Glück in /data/data/com.Android.providers.settings/databases/settings.db/secure
finden. Dort speichert Android sichere Einstellungen.
In Android 7 (API 24) kann sich ein AccessibilityService durch Aufrufen der disableSelf () - Methode selbst deaktivieren.
Ab Android 6.0 können Sie Folgendes verwenden:
adb Shell settings put secure enabled_accessibility_services packagname/servicename
Die settings.db aus alten Releases ist auf Android 6.0 nicht mehr vorhanden.
AccessibilityService ist speziell und kann nicht programmgesteuert gestartet werden.
Das Beste, was Sie tun können, ist das manuelle Öffnen der Zugriffseinstellungen mit:
Vorsatz = neuer Vorsatz (Settings.ACTION_ACCESSIBILITY_SETTINGS)
und starten Sie den Vorsatz - Sie können dies auch von der Prefernece-XML-Datei aus tun:
intent Android: action = "Android.settings.ACCESSIBILITY_SETTINGS"
Für den Fall, dass noch jemand versucht, aus talkback von adb zu schalten, wenn Sie in Ihrem Sperrbildschirm stecken und das Kennwort oder die PIN eingeben. Eine Sache, die Sie versuchen können, ist adb Shell am force-stop com.google.Android.marvin.talkback
In instrumentierten Tests starte ich meinen Erreichbarkeitsdienst wie folgt:
private fun enableAccessibilityService() {
val packageName = "com.example"
val className = "$packageName.service.MyService"
val string = "enabled_accessibility_services"
val cmd = "settings put secure $string $packageName/$className"
InstrumentationRegistry.getInstrumentation()
.getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES)
.executeShellCommand(cmd)
.close()
TimeUnit.SECONDS.sleep(3)
}
Ich habe auf Android 6 und 8 getestet. Dies funktioniert auch für Nicht-System-Apps.
Hier ist die funktionierende Lösung (wenn Ihre Aktivität nicht ausgeführt wird, wird sie sich selbst deaktivieren)
@Override
protected void onServiceConnected() {
super.onServiceConnected();
Toast.makeText(this, "Connected!",Toast.LENGTH_SHORT).show();
ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
serviceChecker();
}
}, 0, 5, TimeUnit.SECONDS);
}
private void serviceChecker(){
if(!isActivityRunning(MainActivity.class)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
disableSelf();
}
}
}
protected Boolean isActivityRunning(Class activityClass)
{
ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (ActivityManager.RunningTaskInfo task : tasks) {
if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName()))
return true;
}
return false;
}