如何在Android Studio实现其他应用启动时自动打开自身应用并悬浮显示
Android实现监听应用启动并自动启动自身+悬浮绘制的方案
要实现当指定应用(比如游戏)启动时,自动打开自身应用并在目标应用上方悬浮绘制内容,可按以下步骤完成:
一、监听其他应用启动事件
Android 5.0及以上版本,普通广播已无法监听应用启动,需借助AccessibilityService实现:
1. 自定义辅助服务类
创建一个继承AccessibilityService的类,在事件回调中判断目标应用是否启动:
public class AppLaunchMonitor extends AccessibilityService { // 替换成你要监听的游戏包名,可扩展为列表监听多个应用 private static final String TARGET_GAME_PACKAGE = "com.example.targetgame"; @Override public void onAccessibilityEvent(AccessibilityEvent event) { // 监听窗口状态变化事件 if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { String currentPackage = event.getPackageName().toString(); if (TARGET_GAME_PACKAGE.equals(currentPackage)) { // 目标应用启动,触发自身应用启动 launchSelf(); } } } private void launchSelf() { Intent launchIntent = getPackageManager().getLaunchIntentForPackage(getPackageName()); if (launchIntent != null) { launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(launchIntent); } } @Override public void onInterrupt() { // 服务中断时的空实现,可按需添加日志或恢复逻辑 } }
2. 注册并配置辅助服务
在AndroidManifest.xml中注册服务,添加必要权限和配置:
<service android:name=".AppLaunchMonitor" 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配置文件:
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeWindowStateChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:description="@string/accessibility_service_desc" />
注意:辅助功能权限需要用户手动在系统设置中开启,应用内要引导用户进入对应设置页面。
二、实现悬浮窗绘制功能
悬浮窗需要SYSTEM_ALERT_WINDOW权限,且Android 8.0+有特殊窗口类型要求:
1. 申请悬浮窗权限
在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
在应用启动时检查权限,未授权则引导用户开启:
private void checkOverlayPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivityForResult(intent, 1001); } }
2. 创建悬浮绘制View
自定义View实现绘制逻辑,比如绘制一个红色边框:
public class FloatingDrawView extends View { private Paint mDrawPaint; public FloatingDrawView(Context context) { super(context); initPaint(); } private void initPaint() { mDrawPaint = new Paint(); mDrawPaint.setColor(Color.RED); mDrawPaint.setStrokeWidth(6f); mDrawPaint.setStyle(Paint.Style.STROKE); mDrawPaint.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 在View范围内绘制矩形框,可替换为你需要的绘制内容 canvas.drawRect(30, 30, getWidth()-30, getHeight()-30, mDrawPaint); } }
3. 将悬浮窗添加到系统窗口
在应用启动后(比如MainActivity的onCreate方法)添加悬浮窗:
private void showFloatingWindow() { if (!Settings.canDrawOverlays(this)) { return; } WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams params = new WindowManager.LayoutParams(); // 适配Android版本的窗口类型 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; } else { params.type = WindowManager.LayoutParams.TYPE_PHONE; } // 设置悬浮窗属性:不获取焦点、全屏布局 params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; params.width = 500; // 悬浮窗宽度,可设为WRAP_CONTENT params.height = 500; // 悬浮窗高度,可设为WRAP_CONTENT params.x = 100; // 悬浮窗初始X坐标 params.y = 100; // 悬浮窗初始Y坐标 params.format = PixelFormat.TRANSLUCENT; FloatingDrawView floatingView = new FloatingDrawView(this); windowManager.addView(floatingView, params); }
三、关键注意事项
- 权限引导:辅助功能和悬浮窗权限均需用户手动开启,应用内必须明确告知用户开启路径,否则功能完全失效。
- 多应用监听:可将目标包名改为
List<String>,在onAccessibilityEvent中判断当前包名是否在列表内,实现监听多个游戏。 - 性能优化:
AccessibilityService回调中避免耗时操作,如需处理复杂逻辑,建议使用异步线程。 - 悬浮窗交互:若需要悬浮窗支持触摸交互,移除
FLAG_NOT_FOCUSABLE标志,但会拦截底层应用的触摸事件,需权衡使用。
内容的提问来源于stack exchange,提问作者Anselum
相关产品推荐
相关产品推荐

