美文网首页
高级安卓开发必备——查看当前Activity

高级安卓开发必备——查看当前Activity

作者: gogoingmonkey | 来源:发表于2018-06-06 15:40 被阅读1095次

    障碍辅助功能AccessibilityService

    提到这个障碍功能,可能大家想想到的是前几年很火的自动抢红包功能,基本都是在亮屏时候模拟用户点击事件,市面上也出现不少的红包插件,但是息屏的抢红包软件还是比较少的,前段时间已经完成了一个,但是还没做兼容适配,存在不少bug,目前在我的7.0的华为mate8手机上是完美的。后面开一篇博客专门讲。大致就是用服务实现的。

    查看当前应用的Activity

    很多同学刚去新公司看别人的代码头疼,又不知道代码写在哪里,时间浪费了,老是去问又不好,我刚来现在的公司时候,就存在这个现象,现在没有那么忙了,就做点贡献。不废话

    思路

    大致思路,借助AccessibilityService这个服务,相当于是打了一个擦边球,获取当前event的然后通过发消息去刷新一个浮窗

    具体实现

    1、首先在MainActivity 中 检查权限:

    private void checkOverlayPermission() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(this)) {
                    startActivityForResult(
                            new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()))
                                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
                            REQUEST_CODE
                    );
                    Toast.makeText(this, "请先授予 \"栈顶通\" 悬浮窗权限", Toast.LENGTH_LONG).show();
                }
            }
        }
    

    2.在点击开启的界面处理点击事件:

    public static boolean checkAccessibility(Context context) {
            // 判断辅助功能是否开启
            if (!AccessibilityUtil.isAccessibilitySettingsOn(context)) {
                // 引导至辅助功能设置页面
                context.startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                );
                Toast.makeText(context, "请先开启 \"Activity 栈\" 的辅助功能", Toast.LENGTH_LONG).show();
                return false;
            }
            return true;
        }
    

    3.自定义一个弹窗布局

    public class FloatingView extends LinearLayout {
        private final Context mContext;
        private final WindowManager mWindowManager;
        private TextView mTvPackageName;
        private TextView mTvClassName;
        private ImageView mIvClose;
    
        public FloatingView(Context context) {
            this(context,null);
        }
    
        public FloatingView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            mContext = context;
            mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
            LayoutInflater.from(context).inflate(R.layout.floating_layout,this);
            initView();
        }
    
        private void initView() {
            mTvPackageName = (TextView) findViewById(R.id.tv_package_name);
            mTvClassName = (TextView) findViewById(R.id.tv_class_name);
            mIvClose = (ImageView) findViewById(R.id.iv_close);
            mIvClose.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext, "关闭悬浮框", Toast.LENGTH_SHORT).show();
                    mContext.startService(
                            new Intent(mContext, TrackerService.class)
                                    .putExtra(TrackerService.COMMAND, TrackerService.COMMAND_CLOSE)
                    );
                }
            });
        }
    
        Point preP, curP;
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    preP = new Point((int)event.getRawX(), (int)event.getRawY());
                    break;
    
                case MotionEvent.ACTION_MOVE:
                    curP = new Point((int)event.getRawX(), (int)event.getRawY());
                    int dx = curP.x - preP.x,
                            dy = curP.y - preP.y;
    
                    WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) this.getLayoutParams();
                    layoutParams.x += dx;
                    layoutParams.y += dy;
                    mWindowManager.updateViewLayout(this, layoutParams);
    
                    preP = curP;
                    break;
            }
    
    
            return false;
        }
        @Subscribe(threadMode = ThreadMode.MAIN)
        public void onEventMainThread(TrackerService.ActivityChangedEvent event){
            Log.d(TAG, "event:" + event.getPackageName() + ": " + event.getClassName());
            String packageName = event.getPackageName(),
                    className = event.getClassName();
    
            mTvPackageName.setText(packageName);
            mTvClassName.setText(
                    className.startsWith(packageName)?
                            className.substring(packageName.length()):
                            className
            );
        }
    
        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            EventBus.getDefault().register(this);
            Log.d(TAG, "event:      服务关闭" );
        }
    
        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            Log.d(TAG, "event:      服务关闭" );
            EventBus.getDefault().unregister(this);
        }
    }
    

    4.发送事件

    
     @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {
            Log.d(TAG, "event:" + event.getPackageName() + ": " + event.getClassName());
            if(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event.getEventType()){
    //        if(AccessibilityEvent.TYPE_WINDOWS_CHANGED == event.getEventType()){  //这个坑B
                Log.d(TAG, "窗口改变发送方了一次请求" + event.getPackageName() + ": " + event.getClassName());
                EventBus.getDefault().post(new ActivityChangedEvent(event.getPackageName().toString(),event.getClassName().toString()));
            }
        }
    
    这里有个比较坑的地方小心了

    5.接受事件

        @Subscribe(threadMode = ThreadMode.MAIN)
        public void onEventMainThread(TrackerService.ActivityChangedEvent event){
            Log.d(TAG, "event:" + event.getPackageName() + ": " + event.getClassName());
            String packageName = event.getPackageName(),
                    className = event.getClassName();
    
            mTvPackageName.setText(packageName);
            mTvClassName.setText(
                    className.startsWith(packageName)?
                            className.substring(packageName.length()):
                            className
            );
        }
    

    总结

    在魅族小米手机上悬浮窗要在设置里面去开

    相关文章

      网友评论

          本文标题:高级安卓开发必备——查看当前Activity

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