【Android M】平台方实现三指左右滑动任何应用界面截屏


frameworks/base/core/java/com/android/internal/policy/MultiGestureSupport/MultiGestureMonitor.java //新增的类

frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java


原文地址:http://blog.csdn.net/yelangjueqi/article/details/56275913

源码

1 MultiGestureMonitor.java //多指检测类

package com.example.android;

import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;

/**
 * Multi Finger Screenshot Gesture Monitor
 *
 * @hide
 */
public class MultiGestureMonitor {
    private static final String TAG = "FingerScreenShotGesture/" + MultiGestureMonitor.class.getSimpleName();
    private final String TAG_EVENT = TAG + "/EventPoint";

    private boolean DBG = false;
    private boolean isSupportHorizontalSlide = true;

    public static final String ACTION_MULTI_FINGER_SCREEN_SHOT = "android.intent.action.MULTI_FINGER_SCREEN_SHOT";
    public static final String MULTI_FINGER_SCREEN_SHOT_ENABLED = "multi_finger_screen_shot_enabled";

    private final int SUPPORT_FINGER_COUNTS = 3;
    private final int HORIZONTAL_SLIDE_OFFSET_DISTANCEY = 300;
    private final int HORIZONTAL_SLIDE_OFFSET_DISTANCEX = 160;
    private final int VERTICAL_SLIDE_OFFSET_DISTANCEY = 160;
    private final int VERTICAL_SLIDE_OFFSET_DISTANCEX = 80;
    private final float BASEVELOCOTY = 45;

    private int mode;
    private float mOldx0;
    private float mOldy0;
    private float mOldx1;
    private float mOldy1;
    private float mOldx2;
    private float mOldy2;
    private float mVelocityX0;
    private float mVelocityY0;

    private Context mContext;
    private VelocityTracker mVelocityTracker;

    private boolean mFingerScreenShotEnabled = false;

    private boolean getFingerEnable() {
        int mFingerMode = Settings.System.getInt(mContext.getContentResolver(), MULTI_FINGER_SCREEN_SHOT_ENABLED, 0);
        if (mFingerMode == 1) {
            return true;
        } else {
            return false;
        }
    }

    // private static MultiGestureMonitor sInstance;
    //
    // public static MultiGestureMonitor getInstance(Context context) {
    // if (sInstance == null) {
    // sInstance = new MultiGestureMonitor(context);
    // }
    // return sInstance;
    // }

    public MultiGestureMonitor(Context context) {
        mContext = context;
    }

    public boolean onTouchEvent(MotionEvent event) {
        boolean handled = false;
        int action = event.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            if (mVelocityTracker == null) {
                mVelocityTracker = VelocityTracker.obtain();
            } else {
                mVelocityTracker.clear();
            }
            mVelocityTracker.addMovement(event);
            mode = 1;
            break;
        case MotionEvent.ACTION_MOVE:
            if (mVelocityTracker != null) {
                mVelocityTracker.addMovement(event);
                mVelocityTracker.computeCurrentVelocity(1000);
                mVelocityX0 = mVelocityTracker.getXVelocity();
                mVelocityY0 = mVelocityTracker.getYVelocity();
            }
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            mode += 1;
            if (mode == SUPPORT_FINGER_COUNTS) {
                mFingerScreenShotEnabled = getFingerEnable();
                try {
                    mOldx0 = event.getX(event.getPointerId(0));
                    mOldy0 = event.getY(event.getPointerId(0));
                    mOldx1 = event.getX(event.getPointerId(1));
                    mOldy1 = event.getY(event.getPointerId(1));
                    mOldx2 = event.getX(event.getPointerId(2));
                    mOldy2 = event.getY(event.getPointerId(2));

                    if (DBG) {
                        Log.v(TAG_EVENT, "oldx0:" + mOldx0 + ",oldy0:" + mOldy0 + ",oldx1:" + mOldx1 + ",oldy1:"
                                + mOldy1 + ",mOldx2=" + mOldx2 + ",mOldy2=" + mOldy2);
                    }
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                }
            }
            break;
        case MotionEvent.ACTION_POINTER_UP:
            if (mode == SUPPORT_FINGER_COUNTS) {
                if (!mFingerScreenShotEnabled) {
                    return false;
                }
                try {
                    float newx0 = event.getX(event.getPointerId(0));
                    float newy0 = event.getY(event.getPointerId(0));
                    float newx1 = event.getX(event.getPointerId(1));
                    float newy1 = event.getY(event.getPointerId(1));
                    float newx2 = event.getX(event.getPointerId(2));
                    float newy2 = event.getY(event.getPointerId(2));

                    if (DBG) {
                        Log.d(TAG_EVENT,
                                "newx0:" + (Math.abs(newx0 - mOldx0) > HORIZONTAL_SLIDE_OFFSET_DISTANCEX) + ",newy0:"
                                        + (Math.abs(newy0 - mOldy0) < HORIZONTAL_SLIDE_OFFSET_DISTANCEY) + ",newx1:"
                                        + (Math.abs(mVelocityX0) > BASEVELOCOTY) + ",newy1:"
                                        + (Math.abs(newy0 - mOldy0) > VERTICAL_SLIDE_OFFSET_DISTANCEY) + ",newx2="
                                        + (Math.abs(newx0 - mOldx0) < VERTICAL_SLIDE_OFFSET_DISTANCEX) + ",newy2="
                                        + (Math.abs(mVelocityY0) > BASEVELOCOTY));

                        Log.d(TAG_EVENT, "mVelocityX0=" + mVelocityX0 + ",mVelocityY0=" + mVelocityY0);
                    }

                    if (isSupportHorizontalSlide) {
                        if (Math.abs(newx0 - mOldx0) > HORIZONTAL_SLIDE_OFFSET_DISTANCEX
                                && Math.abs(newy0 - mOldy0) < HORIZONTAL_SLIDE_OFFSET_DISTANCEY
                                && Math.abs(mVelocityX0) > BASEVELOCOTY) {
                            notifyScreenshotGestureCompleted();
                        }
                    } else {
                        if (Math.abs(newy0 - mOldy0) > VERTICAL_SLIDE_OFFSET_DISTANCEY
                                && Math.abs(newx0 - mOldx0) < VERTICAL_SLIDE_OFFSET_DISTANCEX
                                && Math.abs(mVelocityY0) > BASEVELOCOTY) {
                            notifyScreenshotGestureCompleted();
                        }
                    }
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                }
            }
            mode -= 1;
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            Log.v(TAG, "ACTION_UP or ACTION_CANCEL");

            mode = 0;
            if (mVelocityTracker != null) {
                mVelocityTracker.recycle();
                mVelocityTracker = null;
            }
            resetToInitValue();
            break;
        }
        Log.v(TAG, TAG + String.valueOf(handled));
        return handled;
    }

    private void notifyScreenshotGestureCompleted() {
        if (mContext != null) {
            Intent intent = new Intent();
            intent.setAction(ACTION_MULTI_FINGER_SCREEN_SHOT);
            mContext.sendBroadcast(intent);
            Log.d(TAG, "sendBroadcast:" + ACTION_MULTI_FINGER_SCREEN_SHOT);
        }
    }

    private void resetToInitValue() {
        mOldx0 = 0;
        mOldy0 = 0;
        mOldx1 = 0;
        mOldy1 = 0;
        mOldx2 = 0;
        mOldy2 = 0;
    }
}

说明:

该类为多指手势检测的关键类,具体支持几个手指截屏,由常亮"SUPPORT_FINGER_COUNTS"控制,此处为3,即三指截屏

A,MULTI_FINGER_SCREEN_SHOT_ENABLED = "multi_finger_screen_shot_enabled" 为三指截屏的控制开关

B,满足三指滑动手势后调用notifyScreenshotGestureCompleted()方法发送Action到PhoneWindowManager类,调用takeScreenshot()进行截屏


2 PhoneWindow.java

PhoneWindow类修改如下,见高亮部分代码:


    public PhoneWindow(Context context) {
        super(context);
        mLayoutInflater = LayoutInflater.from(context);

        initFingerScreenshot();
    }

    ......

    private final String TAG_FINGER = "/FingerScreenShotGesture";
    private boolean DBG = true;
    private MultiGestureMonitor mMultiGestureMonitor;
    private int mFingerScreenShotEnabled = 0;
    private final String MULTI_FINGER_SCREEN_SHOT_ENABLED = MultiGestureMonitor.MULTI_FINGER_SCREEN_SHOT_ENABLED;

    private void initFingerScreenshot() {
        mMultiGestureMonitor = new MultiGestureMonitor(getContext());
    }

    private boolean isSupportFingerScreenshot() {
        return Settings.System.getInt(getContext().getContentResolver(),
                MULTI_FINGER_SCREEN_SHOT_ENABLED, 0) == 1;
    }

    ......

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
            if (mMultiGestureMonitor != null) {
                boolean ishanded = mMultiGestureMonitor.onTouchEvent(ev);
                if (DBG) Log.v(TAG, "dispatchTouchEvent:" + String.valueOf(ishanded));
                if (ishanded) {
                    return true;
                }
            }


            final Callback cb = getCallback();
            return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev)
                    : super.dispatchTouchEvent(ev);
     }

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值