Android辅助功能权限应用及应用锁误触发问题求助
问题分析与解决方案
你的问题核心在于AccessibilityService监听了所有TYPE_WINDOW_STATE_CHANGED事件,而WhatsApp的表情选择、图片查看等界面都属于同一个包名,每次切换这些子界面都会触发事件,导致重复弹出锁屏。同时当前的secondApp逻辑仅简单对比上一个包名,无法区分用户是否已经解锁过当前应用。
具体修复方案
1. 新增已解锁应用状态缓存
添加变量记录用户刚解锁的包名,确保用户在同一个应用内切换界面时不会重复触发锁屏,直到离开该应用。
2. 优化触发逻辑
只有当用户首次进入锁定应用,或者从其他应用切换回锁定应用时,才弹出锁屏;同一应用内的界面切换直接跳过。
修改后的代码
import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.view.accessibility.AccessibilityEvent; import android.widget.Toast; import androidx.core.app.NotificationCompat; import com.coremora.secure.MainActivity; import com.coremora.secure.R; import com.coremora.secure.lockScreens.PatternLockScreen; import com.coremora.secure.lockScreens.PinCodeLockScreen; import static com.coremora.secure.MainActivity.dbPackage; import static com.coremora.secure.MainActivity.pass; import static com.coremora.secure.MainActivity.passType; import static com.coremora.secure.MainActivity.updateData; public class MyAccessibilityService extends AccessibilityService { // 记录当前已解锁的应用包名 private String unlockedPackage = ""; // 记录上一次的包名,用于判断是否切换应用 private String lastPackage = ""; @Override public void onAccessibilityEvent(AccessibilityEvent event) { String topPackage = event.getPackageName().toString(); // 跳过自身应用的界面(锁屏界面属于本应用) if (topPackage.equals(getPackageName())) { lastPackage = topPackage; return; } // 检查当前包是否在锁定列表中 boolean isLockedApp = dbPackage.contains(topPackage); if (isLockedApp) { // 从其他应用切换到锁定应用,或之前解锁过但切换到其他应用后又回来 if (!topPackage.equals(unlockedPackage) || !topPackage.equals(lastPackage)) { triggerLockScreen(topPackage); // 标记当前应用已解锁 unlockedPackage = topPackage; } } else { // 离开锁定应用,清空解锁标记 if (unlockedPackage.equals(lastPackage)) { unlockedPackage = ""; } } lastPackage = topPackage; } private void triggerLockScreen(String packageName) { if (pass.isEmpty()) return; Intent intent; if ("pin".equals(passType)) { intent = new Intent(this, PinCodeLockScreen.class); } else { intent = new Intent(this, PatternLockScreen.class); } intent.putExtra("packageName", packageName); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); } @Override public void onServiceConnected() { updateData(this); AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED; info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN; setServiceInfo(info); } @Override public void onInterrupt() { Toast.makeText(this, "服务已中断", Toast.LENGTH_SHORT).show(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE); Notification notification = new NotificationCompat.Builder(this, App.CHANNEL_ID) .setContentTitle("应用锁") .setContentText("应用锁服务已启动") .setSmallIcon(R.drawable.icon) .setContentIntent(pendingIntent) .build(); startForeground(1, notification); return START_STICKY; } }
额外优化建议
- 可以给
unlockedPackage添加超时机制,比如用户在锁定应用内停留超过10分钟无操作,再次切换界面时重新触发锁屏(需结合Handler或AlarmManager实现)。 - 对于部分应用的特殊界面(如WhatsApp的来电界面),可以通过
event.getClassName()获取当前Activity类名,添加判断跳过不需要锁定的界面。
内容的提问来源于stack exchange,提问作者Amila Udara
相关产品推荐
相关产品推荐

