Контекст
Мое приложение использует AccessibilityService
для обнаружения изменений текущего приложения переднего плана. В зависимости от того, какое приложение находится на переднем плане, выполняются определенные действия. Я отслеживаю изменения, идентифицируя packageName
в onAccessibilityEvent()
.
Теперь, когда пользователь находится в приложении и запрашивает разрешение во время выполнения, система отображает GrantPermissionsActivity
. Это вызывает мой код (см. Ниже). Однако мне не нужно предпринимать какие-либо действия в этом случае, и мне нужно как-то это отфильтровать.
Вопрос
До сих пор я определил, что:
- имя пакета
GrantPermissionsActivity
зависит от производителя. Например: в MIUI 11 это com.lbe.security.miui
, тогда как в AOSP 9 (/ OmniROM) это com.android.packageinstaller
. - однако имя класса всегда было
com.android.packageinstaller.permission.ui.GrantPermissionsActivity
на всех протестированных устройствах.
В идеале я могу фильтровать вызовы, проверяя имя класса. Это хорошо работает на моих устройствах. Но: Как я могу быть уверен, что это верно везде , без тестирования на десятках устройств? Есть ли ресурс, где я мог бы подтвердить, что это имя класса не изменяется на разных устройствах?
Альтернативно: может ли код быть изменен другими способами, чтобы в этом сценарии даже не вызывался onAccessibilityEvent()
? Такой ответ или подсказки о том, как сформулировать это как новый вопрос, также был бы оценен.
Код
public class AppChangeDetectorService extends AccessibilityService {
private static final String grantPermissionsActivityClassName =
"com.android.packageinstaller.permission.ui.GrantPermissionsActivity";
@Override
protected void onServiceConnected() {
super.onServiceConnected();
AccessibilityServiceInfo config = new AccessibilityServiceInfo();
config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
setServiceInfo(config);
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (event.getPackageName() != null && event.getClassName() != null) {
ComponentName componentName = new ComponentName(
event.getPackageName().toString(),
event.getClassName().toString()
);
ActivityInfo activityInfo = tryGetActivity(componentName);
boolean isActivity = activityInfo != null;
if (isActivity) {
String currentPackage = componentName.getPackageName();
String currentClass = componentName.getClassName();
// Take action depending on package / class name.
if (currentClass.equals(grantPermissionsActivityClassName)) {
return;
}
}
}
}
private ActivityInfo tryGetActivity(ComponentName componentName) {
try {
return getPackageManager().getActivityInfo(componentName, 0);
} catch (PackageManager.NameNotFoundException e) {
return null;
}
}
}