//Configure these here for compatibility with API 13 and below. AccessibilityServiceInfo config = new AccessibilityServiceInfo(); config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED; config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
if (Build.VERSION.SDK_INT >= 16) //Just in case this helps config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
setServiceInfo(config); }
@Override publicvoidonAccessibilityEvent(AccessibilityEvent event){ if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { ComponentName componentName = new ComponentName( event.getPackageName().toString(), event.getClassName().toString() );
<?xml version="1.0" encoding="utf-8"?> <!-- These options MUST be specified here in order for the events to be received on first start in Android 4.1.1 --> <accessibility-service xmlns:tools="http://schemas.android.com/tools" android:accessibilityEventTypes="typeWindowStateChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagIncludeNotImportantViews" android:description="@string/accessibility_service_description" xmlns:android="http://schemas.android.com/apk/res/android" tools:ignore="UnusedAttribute"/>
3. ActivityManager
使用 ActivityManager有一定版本限制。官方文档有详细的说明:
1
on API-21 as of LOLLIPOP, ActivityManager.getRunningTasks() is no longer available to third partyapplications: the introduction of document-centric recents means it can leak person information to thecaller. For backwards compatibility, it will still return a small subset of its data: at least the caller's owntasks, and possibly some other tasks such as home that are known to not be sensitive.
List<ActivityManager.RunningAppProcessInfo> processes = activityManager().getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo process : processes) { if ( // Filters out most non-activity processes process.importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && // Filters out processes that are just being // _used_ by the process with the activity process.importanceReasonCode == 0 ) { int state = processStateField.getInt(process);
if (state == PROCESS_STATE_TOP) /* If multiple candidate processes can get here, it's most likely that apps are being switched. The first one provided by the OS seems to be the one being switched to, so we stop here. */ return process.pkgList; } } } catch (NoSuchFieldException | IllegalAccessException e) { thrownew RuntimeException(e); } returnnew String[] { }; }