美文网首页
获取顶端应用的包名原理浅析

获取顶端应用的包名原理浅析

作者: WindMajor | 来源:发表于2017-04-06 18:01 被阅读53次

    由于监控在最顶端的App需要持续进行,所以首先需要单独开一个后台进程,运行一个单例Manager。

    初始化Manager

    private TopAppManager() {
        // workHandler
        workerThread = new HandlerThread(getClass().getName());
        workerThread.start();
        workerThreadHandler = new Handler(workerThread.getLooper()) {
    
            @Override
            public void handleMessage(Message msg) {
                monitorInWorkThread();
            }
        };
        isAccessibilityAvailable = HSAccessibilityManager.getInstance().isAvailable();
        isUsageAccessGranted = HSUsageAccessMgr.getInstance().checkPermission(new HSUsageAccessMgr.PermissionListener() {
            @Override
            public void onPermissionChanged(boolean isGranted) {
                isUsageAccessGranted = isGranted;
                if (isUsageAccessGranted && !isAccessibilityAvailable) {
                    resumeMonitor();
                }
            }
        });
    
        HSAccessibilityManager.getInstance().registerEvent(new HSAccessibilityManager.AccEventListener() {
            @Override
            public void onAvailable() {
                isAccessibilityAvailable = true;
                L.l("isAccessibilityAvailable:" + isAccessibilityAvailable);
                pauseMonitor();
            }
    
            @Override
            public void onEvent(AccessibilityEvent event) {
                if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                    if (TextUtils.isEmpty(event.getPackageName()) || TextUtils.isEmpty(event.getClassName())) {
                        return;
                    }
                    ComponentName componentName = new ComponentName(event.getPackageName().toString(), event.getClassName().toString());
                    if (TopAppUtil.tryGetActivityInfo(componentName) == null) {
                        return;
                    }
                    tryToNotifyTopApp(event.getPackageName().toString());
                }
            }
    
            @Override
            public void onUnavailable(@HSTopAppManager.FailCode int code, String failMsg) {
                L.l("onUnavailable code:" + code + " msg:" + failMsg);
                isAccessibilityAvailable = false;
                resumeMonitor();
                L.l("resumeMonitor");
            }
        });
        //sendBroadcast HSTopAppManager.BROADCAST_TOP_APP_MONITOR_INITIATED
        Intent intent = new Intent(HSTopAppManager.BROADCAST_TOP_APP_MONITOR_INITIATED);
        intent.putExtra(HSTopAppManager.EXTRA_DATA_TOP_APP, getTopApp());
        intent.setPackage(HSApplication.getContext().getPackageName());
        HSApplication.getContext().sendBroadcast(intent);
    }
    

    创建一个唯一的HandlerThread对象;使用HandlerThread对象在创建一个Handler,并且重写handleMessage方法

    如果已经获得Accessibility的权限,那么实现监听很容易,这里需要提前判定是否已经有了这个权限,这个方法的实现,以后再写。

    如果已经获得UsageAccess权限,对于实现监听也非常重要,这里也在提前判断是否已经获得UsageAccess权限。关于这个权限的判断,以后会写。

    然后动态注册广播,去监听亮屏、灭屏和用户操作等广播

        private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                switch (intent.getAction()) {
                    case Intent.ACTION_SCREEN_ON:
                    case Intent.ACTION_USER_PRESENT:
                        resumeMonitor();
                        break;
                    case Intent.ACTION_SCREEN_OFF:
                        pauseMonitor();
                        break;
                }
            }
        };
    

    未完待续……

    相关文章

      网友评论

          本文标题:获取顶端应用的包名原理浅析

          本文链接:https://www.haomeiwen.com/subject/gieqattx.html