当前位置: 首页 > news >正文

Android监测顶层包名+类名

Android 监测顶层包名+类名

本文主要介绍下通过辅助功能来实现android 中实时监测顶层包名类名.

1: 检测应用是否开启辅助功能

通过读取系统设置中的 ACCESSIBILITY_ENABLED 和 ENABLED_ACCESSIBILITY_SERVICES 来判断当前服务是否已启用.

/**
 * 检查辅助功能是否已启用
 */
private boolean isAccessibilityServiceEnabled(Context context) {
    int accessibilityEnabled = 0;
    try {
        accessibilityEnabled = Settings.Secure.getInt(
                context.getContentResolver(),
                android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
    } catch (Settings.SettingNotFoundException e) {
        Log.e(TAG, "Error finding accessibility setting: " + e.getMessage());
    }

    if (accessibilityEnabled == 1) {
        String services = Settings.Secure.getString(
                context.getContentResolver(),
                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
        if (services != null) {
            Log.d(TAG, "Enabled services: " + services);
            return services.contains(context.getPackageName() + "/" + MyAccessibilityService.class.getName());
        }
    }
    return false;
}

2: 跳转到辅助功能设置页面

使用 Intent 跳转到系统辅助功能设置页面, 添加 FLAG_ACTIVITY_NEW_TASK 标志以确保可以从服务中启动 Activity.

注意权限声明:确保在 AndroidManifest.xml 中已声明 BIND_ACCESSIBILITY_SERVICE 权限

/**
 * 跳转到辅助功能设置页面
 */
private void openAccessibilitySettings() {
    Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}

3: 实现MyAccessibilityService类

package com.example.topclass;

import android.accessibilityservice.AccessibilityService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;

import androidx.annotation.RequiresApi;

/**
 * @Author: zh
 * @Time: 24-12-12.
 * @Describe: 辅助功能监测顶层包名
 */
public class MyAccessibilityService extends AccessibilityService {
    private static final String TAG = "MyAccessibilityService";
    private static final String CHANNEL_ID = "AccessibilityServiceChannel";
    private Handler handler = new Handler(Looper.getMainLooper());
    private Runnable heartbeatRunnable;
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // 检查事件类型是否为窗口状态变化
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            // 获取当前顶层页面的包名
            String packageName = event.getPackageName().toString();
            // 获取当前顶层页面的类名
            String className = event.getClassName().toString();
            // 打印包名和类名
            Log.d(TAG, "Top Activity: PackageName=" + packageName + ", ClassName=" + className);
        }
    }

    @Override
    public void onInterrupt() {
        // 当服务被中断时调用
        Log.d(TAG, "Accessibility service interrupted");
    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        // 提升服务优先级,绑定前台服务
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService();
            // 启动心跳机制,每1s发送一次通知
            heartbeatRunnable = new Runnable() {
                @Override
                public void run() {
                 
                   // 增强日志记录,确保服务状态可见
                    Log.d(TAG, "Heartbeat: Service is active. Thread ID: " + Thread.currentThread().getId());
                    handler.postDelayed(this, 1000); // 每1s执行一次
                }
            };
            handler.post(heartbeatRunnable);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 停止心跳机制
        if (heartbeatRunnable != null) {
            handler.removeCallbacks(heartbeatRunnable);
        }
        // 增加详细日志记录,确保资源释放过程被记录
        Log.d(TAG, "Service destroyed. Resources cleaned up. Thread ID: " + Thread.currentThread().getId());
    }

    /**
     * 绑定前台服务,提升优先级
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startForegroundService() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    CHANNEL_ID,
                    "Accessibility Service",
                    NotificationManager.IMPORTANCE_HIGH
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }

        Notification notification = new Notification.Builder(this, CHANNEL_ID)
                .setContentTitle("Accessibility Service Running")
                .setContentText("Listening for page changes...")
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setPriority(Notification.PRIORITY_HIGH)
                .build();

        startForeground(999, notification);
    }

}
  1. 实现了 AccessibilityService,并在 onAccessibilityEvent 方法中监听 TYPE_WINDOW_STATE_CHANGED 事件。
    提取事件中的包名和类名,并通过 Log.d 打印到日志中
  2. 在 onServiceConnected 方法中调用 startForegroundService,将服务绑定为前台服务。使用 Notification 提示用户服务正在运行,避免被系统回收。
  3. 增加 android.permission.FOREGROUND_SERVICE权限, 避免启动前台服务时抛出 java.lang.SecurityException 异常.

4: 声明 AccessibilityService

AndroidManifest.xml文件中声明AccessibilityService.并配置了必要的权限和元数据.

<!-- 声明 AccessibilityService -->
<service
    android:name=".MyAccessibilityService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
    android:exported="false">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_service_config" />
</service>

5: 编写accessibility_service_config

编写accessibility_service_config, 配置服务的事件类型和反馈类型,确保能够监听窗口状态变化.

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_service_description"
    android:notificationTimeout="100" />

6: 添加字符串资源

<string name="accessibility_service_description">This service listens to page changes and logs the top activity.</string>

7: 输出如下

2024-12-12 15:41:37.190 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:39.135 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:39.136 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.android.contacts, ClassName=android.widget.FrameLayout
2024-12-12 15:41:39.136 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.android.contacts, ClassName=com.android.dialer.BBKTwelveKeyDialer
2024-12-12 15:41:39.171 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.android.contacts, ClassName=com.android.dialer.BBKTwelveKeyDialer
2024-12-12 15:41:39.274 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.bbk.launcher2, ClassName=com.bbk.launcher2.Launcher
2024-12-12 15:41:40.153 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:40.247 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.bbk.launcher2, ClassName=com.bbk.launcher2.Launcher
2024-12-12 15:41:41.163 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:42.171 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:43.965 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:44.019 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.android.mms, ClassName=android.widget.FrameLayout
2024-12-12 15:41:44.019 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.android.mms, ClassName=com.android.mms.ui.ConversationList
2024-12-12 15:41:44.023 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.android.mms, ClassName=com.android.mms.ui.ConversationList
2024-12-12 15:41:44.125 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.bbk.launcher2, ClassName=com.bbk.launcher2.Launcher
2024-12-12 15:41:44.970 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:45.023 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.bbk.launcher2, ClassName=com.bbk.launcher2.Launcher
2024-12-12 15:41:46.562 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:46.596 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.tencent.mm, ClassName=com.tencent.mm.ui.LauncherUI
2024-12-12 15:41:46.596 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.tencent.mm, ClassName=com.tencent.mm.plugin.account.ui.LoginPasswordUI
2024-12-12 15:41:46.730 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.bbk.launcher2, ClassName=com.bbk.launcher2.Launcher
2024-12-12 15:41:47.569 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:47.806 7064-7064/com.example.topclass D/MyAccessibilityService: Top Activity: PackageName=com.bbk.launcher2, ClassName=com.bbk.launcher2.Launcher
2024-12-12 15:41:48.578 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2
2024-12-12 15:41:49.586 7064-7064/com.example.topclass D/MyAccessibilityService: Heartbeat: Service is active. Thread ID: 2

相关文章:

  • 动态规划(6)——01背包问题
  • 2025蓝桥杯JavaB组
  • jupyter notebook 无法启动- markupsafe导致
  • Day3—循环起来吧
  • 深入理解 PyTorch 的 nn.Embedding:词向量映射及变量 weight 的更新机制
  • 算法专题:双指针
  • 470用 Rand7() 实现 Rand10()
  • [MSPM0开发]之五 MSPM0G3507 SysTick定时器的配置与使用(systick中断实现延时函数)
  • 微信小程序运行机制详解
  • 单片机Day05---动态数码管显示01234567
  • WindowsPE文件格式入门08.导出表
  • 蓝桥杯嵌入式历年省赛客观题
  • GPU虚拟化技术在深度学习集群中的应用实践
  • Spring AI 结构化输出详解
  • 【foc思考】为什么svpwm要不停变换占空比
  • Python 实现最小插件框架
  • JDK(Java Development Kit)从发布至今所有主要版本 的详细差异、新增特性及关键更新的总结,按时间顺序排列
  • 【架构师从入门到进阶】第五章:DNSCDN网关优化思路——第七节:网关-XSS攻击与预防
  • uniapp日常总结--uniapp页面跳转方式
  • 单片机Day05---静态数码管
  • 新疆交通建设集团网站/关键词检测工具
  • wordpress怎么在本地安装/seo新手入门教程
  • 做网站是什么/合肥百度快照优化排名
  • 重庆做模块网站/黄页网站推广服务
  • 网站建设运营/线上营销平台有哪些
  • 手机做网站公司有哪些/58同城关键词怎么优化