媒体投影开始时如何收听手指手势

问题描述

我正在尝试用 3 根手指向下滑动截取屏幕截图。我成功地在 3 根手指向下滑动的活动中截取屏幕截图,但我无法在应用程序外截取屏幕截图,即我想听触摸事件/应用程序启动媒体投影时的手势.. 触摸/滑动/手势在应用程序内工作正常并且还可以截取屏幕截图.. 这是我目前使用的代码, ScreenCaptureService.java

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.display.displayManager;
import android.hardware.display.Virtualdisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.mediaprojectionmanager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.display;
import android.view.OrientationEventListener;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Objects;

import androidx.core.util.Pair;

public class ScreenCaptureService extends Service {

    private static final String TAG = "ScreenCaptureService";
    private static final String RESULT_CODE = "RESULT_CODE";
    private static final String DATA = "DATA";
    private static final String ACTION = "ACTION";
    private static final String START = "START";
    private static final String STOP = "STOP";
    private static final String SCREENCAP_NAME = "screencap";

    private static int IMAGES_PRODUCED;

    private MediaProjection mMediaProjection;
    private String mStoreDir;
    private ImageReader mImageReader;
    private Handler mHandler;
    private display mdisplay;
    private Virtualdisplay mVirtualdisplay;
    private int mDensity;
    private int mWidth;
    private int mHeight;
    private int mRotation;
    private OrientationChangeCallback mOrientationChangeCallback;

    public static Intent getStartIntent(Context context,int resultCode,Intent data) {
        Intent intent = new Intent(context,ScreenCaptureService.class);
        intent.putExtra(ACTION,START);
        intent.putExtra(RESULT_CODE,resultCode);
        intent.putExtra(DATA,data);
        return intent;
    }

    public static Intent getStopIntent(Context context) {
        Intent intent = new Intent(context,STOP);
        return intent;
    }

    private static boolean isstartCommand(Intent intent) {
        return intent.hasExtra(RESULT_CODE) && intent.hasExtra(DATA)
                && intent.hasExtra(ACTION) && Objects.equals(intent.getStringExtra(ACTION),START);
    }

    private static boolean isstopCommand(Intent intent) {
        return intent.hasExtra(ACTION) && Objects.equals(intent.getStringExtra(ACTION),STOP);
    }

    private static int getVirtualdisplayFlags() {
        return displayManager.VIRTUAL_disPLAY_FLAG_OWN_CONTENT_ONLY | displayManager.VIRTUAL_disPLAY_FLAG_PUBLIC;
    }

    private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
        @Override
        public void onImageAvailable(ImageReader reader) {

            FileOutputStream fos = null;
            Bitmap bitmap = null;
            try (Image image = mImageReader.acquireLatestimage()) {
                if (image != null) {
                    Image.Plane[] planes = image.getPlanes();
                    ByteBuffer buffer = planes[0].getBuffer();
                    int pixelStride = planes[0].getPixelStride();
                    int rowStride = planes[0].getRowStride();
                    int rowPadding = rowStride - pixelStride * mWidth;

                    // create bitmap
                    bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride,mHeight,Bitmap.Config.ARGB_8888);
                    bitmap.copyPixelsFromBuffer(buffer);

                    // write bitmap to a file
                    fos = new FileOutputStream(mStoreDir + "/myscreen_" + IMAGES_PRODUCED + ".png");
                    bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);

                    IMAGES_PRODUCED++;
                    Log.e(TAG,"captured image: " + IMAGES_PRODUCED);
                }

            } catch (Exception e) {
                e.printstacktrace();
            } finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException ioe) {
                        ioe.printstacktrace();
                    }
                }

                if (bitmap != null) {
                    bitmap.recycle();
                }

            }
        }
    }

    private class OrientationChangeCallback extends OrientationEventListener {

        OrientationChangeCallback(Context context) {
            super(context);
        }

        @Override
        public void onorientationChanged(int orientation) {
            final int rotation = mdisplay.getRotation();
            if (rotation != mRotation) {
                mRotation = rotation;
                try {
                    // clean up
                    if (mVirtualdisplay != null) mVirtualdisplay.release();
                    if (mImageReader != null) mImageReader.setonImageAvailableListener(null,null);

                    // re-create virtual display depending on device width / height
                    createVirtualdisplay();
                } catch (Exception e) {
                    e.printstacktrace();
                }
            }
        }
    }

    private class MediaProjectionStopCallback extends MediaProjection.Callback {
        @Override
        public void onStop() {
            Log.e(TAG,"stopping projection.");
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mVirtualdisplay != null) mVirtualdisplay.release();
                    if (mImageReader != null) mImageReader.setonImageAvailableListener(null,null);
                    if (mOrientationChangeCallback != null) mOrientationChangeCallback.disable();
                    mMediaProjection.unregisterCallback(MediaProjectionStopCallback.this);
                }
            });
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        // create store dir
        File externalFilesDir = getExternalFilesDir(null);
        if (externalFilesDir != null) {
            mStoreDir = externalFilesDir.getAbsolutePath() + "/screenshots/";
            File storeDirectory = new File(mStoreDir);
            if (!storeDirectory.exists()) {
                boolean success = storeDirectory.mkdirs();
                if (!success) {
                    Log.e(TAG,"Failed to create file storage directory.");
                    stopSelf();
                }
            }
        } else {
            Log.e(TAG,"Failed to create file storage directory,getExternalFilesDir is null.");
            stopSelf();
        }

        // start capture handling thread
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                mHandler = new Handler();
                Looper.loop();
            }
        }.start();
    }

    @Override
    public int onStartCommand(Intent intent,int flags,int startId) {
        if (isstartCommand(intent)) {
            // create notification
            Pair<Integer,Notification> notification = NotificationUtils.getNotification(this);
            startForeground(notification.first,notification.second);
            // start projection
            int resultCode = intent.getIntExtra(RESULT_CODE,Activity.RESULT_CANCELED);
            Intent data = intent.getParcelableExtra(DATA);
            startProjection(resultCode,data);
        } else if (isstopCommand(intent)) {
            stopProjection();
            stopSelf();
        } else {
            stopSelf();
        }

        return START_NOT_STICKY;
    }

    private void startProjection(int resultCode,Intent data) {
        mediaprojectionmanager mpManager =
                (mediaprojectionmanager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        if (mMediaProjection == null) {
            mMediaProjection = mpManager.getMediaProjection(resultCode,data);
            if (mMediaProjection != null) {
                // display metrics
                mDensity = Resources.getSystem().getdisplayMetrics().densityDpi;
                WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
                mdisplay = windowManager.getDefaultdisplay();

                // create virtual display depending on device width / height
                createVirtualdisplay();

                // register orientation change callback
                mOrientationChangeCallback = new OrientationChangeCallback(this);
                if (mOrientationChangeCallback.canDetectOrientation()) {
                    mOrientationChangeCallback.enable();
                }

                // register media projection stop callback
                mMediaProjection.registerCallback(new MediaProjectionStopCallback(),mHandler);
            }
        }
    }

    private void stopProjection() {
        if (mHandler != null) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mMediaProjection != null) {
                        mMediaProjection.stop();
                    }
                }
            });
        }
    }

    @SuppressLint("WrongConstant")
    private void createVirtualdisplay() {
        // get width and height
        mWidth = Resources.getSystem().getdisplayMetrics().widthPixels;
        mHeight = Resources.getSystem().getdisplayMetrics().heightPixels;

        // start capture reader
        mImageReader = ImageReader.newInstance(mWidth,PixelFormat.RGBA_8888,2);
        mVirtualdisplay = mMediaProjection.createVirtualdisplay(SCREENCAP_NAME,mWidth,mDensity,getVirtualdisplayFlags(),mImageReader.getSurface(),null,mHandler);
        mImageReader.setonImageAvailableListener(new ImageAvailableListener(),mHandler);

        startListen(mImageReader);

    }

    public void startListen(ImageReader virtualdisplay)
    {
        Toast.makeText(this,"listen",Toast.LENGTH_SHORT).show();
        SimpleFingerGestures sfg = new SimpleFingerGestures();
        sfg.setDebug(true);
        sfg.setConsumetouchEvents(true);

        sfg.setonFingerGestureListener(new SimpleFingerGestures.OnFingerGestureListener() {
            @Override
            public boolean onSwipeUp(int fingers,long gestureDuration,double gesturedistance) {
                //grtv.setText("You swiped " + fingers + " fingers  up " + gestureDuration + " milliseconds " + gesturedistance + " pixels far");
                return false;
            }

            @Override
            public boolean onSwipeDown(int fingers,double gesturedistance) {
                //grtv.setText("You swiped " + fingers + " fingers  down " + gestureDuration + " milliseconds " + gesturedistance + " pixels far");

                if (fingers==3)
                {
                    Toast.makeText(ScreenCaptureService.this,"3 fingers",Toast.LENGTH_SHORT).show();
                    //screenshot.takeScreenshot();
//                    savetogallery();

                }
                return false;
            }

            @Override
            public boolean onSwipeLeft(int fingers,double gesturedistance) {
                //grtv.setText("You swiped " + fingers + " fingers  left " + gestureDuration + " milliseconds " + gesturedistance + " pixels far");
                return false;
            }

            @Override
            public boolean onSwipeRight(int fingers,double gesturedistance) {
                //grtv.setText("You swiped " + fingers + " fingers  right " + gestureDuration + " milliseconds " + gesturedistance + " pixels far");
                return false;
            }

            @Override
            public boolean onPinch(int fingers,double gesturedistance) {
                //grtv.setText("You pinched " + fingers + " fingers " + gestureDuration + " milliseconds " + gesturedistance + " pixels far");
                return false;
            }

            @Override
            public boolean onUnpinch(int fingers,double gesturedistance) {
                //grtv.setText("You unpinched " + fingers + "fingers"  + gestureDuration + " milliseconds " + gesturedistance + " pixels far");
                return false;
            }

            @Override
            public boolean onDoubleTap(int fingers) {
                //grtv.setText("You double tapped");
                return false;
            }
        });


        virtualdisplay.setonTouchListener(sfg);//here want to set on touch listener but doesn't works
    }
}

如何在 startListen() 函数中监听触摸事件?我应该在哪里调用这个函数

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...