如何从Shell脚本调用Android OS API实现指定设备操作?
针对两个Android自动化场景的实现方案
针对你提到的两个Android自动化需求,我整理了具体的实现思路和代码片段,帮你搞定这两个场景:
场景1:自动点亮屏幕并启动Spotify到前台
这个需求核心是两个点:唤醒屏幕,以及把Spotify拉到前台。要注意Android不同版本的权限限制,尤其是后台启动Activity的规则,步骤如下:
- 申请必要权限:在
AndroidManifest.xml里添加唤醒锁权限,以及Android 11+启动第三方应用所需的包查询权限:<uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- Android 11+ 启动Spotify需要指定包名查询 --> <queries> <package android:name="com.spotify.music" /> </queries> - 唤醒屏幕:用
PowerManager获取唤醒锁,使用ACQUIRE_CAUSES_WAKEUP强制点亮屏幕,记得设置超时自动释放避免一直亮屏:PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); if (pm != null && !pm.isInteractive()) { PowerManager.WakeLock wakeLock = pm.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "AutoSpotify:WakeLockTag" ); wakeLock.acquire(10_000); // 10秒后自动释放 } - 启动Spotify到前台:通过包名获取启动Intent,添加
FLAG_ACTIVITY_REORDER_TO_FRONT确保直接拉后台的Spotify到前台,而非重启:PackageManager packageManager = getPackageManager(); Intent spotifyIntent = packageManager.getLaunchIntentForPackage("com.spotify.music"); if (spotifyIntent != null) { spotifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(spotifyIntent); } - 触发时机:如果需要定时触发,用
WorkManager创建周期性任务;如果要精确计时,用AlarmManager即可,根据你的需求选择。
场景2:有声书停止8小时后设置闹钟
这个需求的关键是监听有声书停止事件,再延迟8小时执行闹钟设置,分两种情况处理:
情况1:有声书是你自己开发的应用
直接在播放停止的回调里启动延迟任务:
- 用
WorkManager创建8小时延迟的一次性任务:OneTimeWorkRequest alarmWork = new OneTimeWorkRequest.Builder(AlarmSetupWorker.class) .setInitialDelay(8, TimeUnit.HOURS) .build(); WorkManager.getInstance(this).enqueue(alarmWork); - 在
AlarmSetupWorker里实现闹钟设置逻辑(适配Doze模式确保触发):public class AlarmSetupWorker extends Worker { public AlarmSetupWorker(@NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @NonNull @Override public Result doWork() { setupAlarm(); return Result.success(); } private void setupAlarm() { AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); Intent alarmIntent = new Intent(getApplicationContext(), AlarmReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast( getApplicationContext(), 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); long triggerTime = System.currentTimeMillis() + 8 * 60 * 60 * 1000; // 适配Android 6.0+的Doze模式,确保闹钟能触发 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent); } else { alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent); } } } - 创建
AlarmReceiver发送闹钟提醒通知:public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 发送高优先级通知 NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); Notification notification = new NotificationCompat.Builder(context, "ALARM_REMINDER_CHANNEL") .setSmallIcon(R.drawable.ic_alarm) .setContentTitle("起床闹钟") .setContentText("已经睡够8小时啦!") .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true) .build(); notificationManager.notify(1, notification); } } - 别忘了在
AndroidManifest.xml注册Receiver和Worker,以及Android 8.0+需要创建通知渠道。
情况2:有声书是第三方应用
这种情况需要用AccessibilityService监听应用状态,步骤如下:
- 在
AndroidManifest.xml注册辅助服务:<service android:name=".AudiobookMonitorService" 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_config" /> </service> - 在
res/xml/accessibility_config.xml配置监听的有声书包名(替换成你实际用的应用包名):<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeWindowStateChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:packageNames="com.example.audiobook" /> - 在
AudiobookMonitorService里监听应用状态,结合音频状态判断是否停止:public class AudiobookMonitorService extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { String packageName = event.getPackageName().toString(); if ("com.example.audiobook".equals(packageName)) { // 检查音频是否停止播放 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); if (!audioManager.isMusicActive()) { // 启动8小时后的闹钟任务 enqueueAlarmWork(); } } } } private void enqueueAlarmWork() { OneTimeWorkRequest alarmWork = new OneTimeWorkRequest.Builder(AlarmSetupWorker.class) .setInitialDelay(8, TimeUnit.HOURS) .build(); WorkManager.getInstance(this).enqueue(alarmWork); } @Override public void onInterrupt() {} } - 注意:用户需要在系统设置的「辅助功能」里手动开启你的应用权限,这是Android的安全限制,无法自动开启。
内容的提问来源于stack exchange,提问作者Luc
相关产品推荐
相关产品推荐

