Android平台.NET MAUI应用:检测用户停止使用设备的方案问询
Android全局无交互检测与应用启动方案
核心思路
要实现后台监听全局触摸交互并在用户x分钟无操作时启动应用显示图片,Android系统下唯一合法的方式是借助AccessibilityService(无障碍服务)记录用户最后操作时间,结合定时任务检查无交互时长,最终触发应用启动。
步骤1:实现无障碍服务监听触摸事件
无障碍服务可全局监听系统交互事件,我们用它来追踪用户的最后操作时刻:
1.1 创建AccessibilityService子类
class TouchMonitorService : AccessibilityService() { companion object { // 静态变量存储最后交互时间,供定时任务读取 var lastInteractionTime = System.currentTimeMillis() } override fun onAccessibilityEvent(event: AccessibilityEvent?) { event?.let { // 监听触摸、点击、长按等交互事件,更新最后操作时间 when (it.eventType) { AccessibilityEvent.TYPE_TOUCH_INTERACTION_START, AccessibilityEvent.TYPE_VIEW_CLICKED, AccessibilityEvent.TYPE_VIEW_LONG_CLICKED -> { lastInteractionTime = System.currentTimeMillis() } } } } override fun onInterrupt() { // 服务被中断时的默认处理,无需额外操作 } }
1.2 注册服务并配置权限
在AndroidManifest.xml中注册服务,声明无障碍权限:
<service android:name=".TouchMonitorService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config" /> </service>
1.3 创建无障碍服务配置文件
在res/xml目录下新建accessibility_service_config.xml,指定监听的事件类型:
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeTouchInteractionStart|typeViewClicked|typeViewLongClicked" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="false" android:description="@string/accessibility_service_description" />
同时在strings.xml中添加服务描述:
<string name="accessibility_service_description">监听设备交互,在无操作时展示图片</string>
步骤2:定时检查无交互时长并启动应用
使用WorkManager实现周期性检查,平衡功能需求与后台耗电:
2.1 实现Worker子类
class InactivityCheckWorker( context: Context, workerParams: WorkerParameters ) : Worker(context, workerParams) { override fun doWork(): Result { // 从参数中获取无操作阈值(分钟) val thresholdMinutes = inputData.getLong("THRESHOLD_MINUTES", 5) val inactivityThreshold = thresholdMinutes * 60 * 1000 val currentTime = System.currentTimeMillis() // 判断是否超过无操作时长 if (currentTime - TouchMonitorService.lastInteractionTime >= inactivityThreshold) { // 启动图片展示Activity val intent = Intent(applicationContext, ImageDisplayActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) applicationContext.startActivity(intent) } // 任务执行成功,继续周期性调度 return Result.success() } companion object { // 启动周期性检查任务 fun startPeriodicCheck(context: Context, thresholdMinutes: Long) { val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.NOT_REQUIRED) .build() val data = Data.Builder() .putLong("THRESHOLD_MINUTES", thresholdMinutes) .build() // 每15分钟检查一次,可根据需求调整间隔 val request = PeriodicWorkRequestBuilder<InactivityCheckWorker>(15, TimeUnit.MINUTES) .setConstraints(constraints) .setInputData(data) .build() WorkManager.getInstance(context).enqueue(request) } } }
步骤3:实现图片展示Activity
创建全屏Activity,显示目标图片,并在用户触摸时关闭:
3.1 Activity代码
class ImageDisplayActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 设置全屏模式 window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN ) supportActionBar?.hide() setContentView(R.layout.activity_image_display) // 加载并显示图片 val imageView = findViewById<ImageView>(R.id.display_image) imageView.setImageResource(R.drawable.your_target_image) // 替换为你的图片资源 // 触摸屏幕时关闭Activity,回到之前的应用 imageView.setOnTouchListener { _, _ -> finish() true } } }
3.2 布局文件(activity_image_display.xml)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/display_image" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" /> </RelativeLayout>
关键注意事项
- 无障碍服务授权:应用首次启动时,需要引导用户手动开启无障碍服务,可通过以下代码跳转到设置页面:
fun openAccessibilitySettings(context: Context) { val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) } - Android 12+后台启动限制:通过无障碍服务上下文启动Activity不受后台启动限制,若用普通WorkManager启动可能被拦截,建议优先通过无障碍服务触发启动逻辑。
- 耗电优化:避免设置过短的检查间隔,推荐10-15分钟一次,减少后台唤醒次数。
内容的提问来源于stack exchange,提问作者lamed
相关产品推荐
相关产品推荐

