xamarin c# android截屏代码


自己基于xamarin做了一个有趣的小工具,具体就是截屏,然后图片识别,点击屏幕

这是自己做的截屏模块(可能需要后台服务),安卓anroid 10开始截屏需要后台服务

请求权限模块

private void requestMediaProjection()
        {
            var mediaManager = (Android.Media.Projection.MediaProjectionManager)this.GetSystemService(Android.Content.Context.MediaProjectionService);
            this.StartActivityForResult(mediaManager.CreateScreenCaptureIntent(), REQUEST_CODE_REQUEST_MEDIA_PROJECTION_RESULT);
        }
        public void SetupMediaProjection(Result resultCode, Android.Content.Intent data)
        {
            if (resultCode != Result.Ok)
            {
                requestMediaProjection();
                return;
            }

            int mResultCode;
            Android.Content.Intent mResultData;
            mResultCode = (int)resultCode;
            mResultData = data;

            ScreenTranslatorService.start(this);
            //get a MediaProjection object
            var mediaManager = (Android.Media.Projection.MediaProjectionManager)this.GetSystemService(Android.Content.Context.MediaProjectionService);

            //Create an ImageReader and a screen-size-fit VirtualDisplay
            windowManager = (Android.Views.IWindowManager)this.GetSystemService(Android.Content.Context.WindowService).JavaCast<Android.Views.IWindowManager>();

            AndroidHelpers.ScreenCapture.Setup(windowManager, mediaManager, mResultCode, mResultData);
        }

 

截屏模块

 public enum ScreenType
    {
        Screen,
        ScreenGamma,
        ScreenToGray,
        ScreenExposure,
        ScreenToGrayAndGamma
    }
    public static class ScreenCapture
    {
        private static Android.Views.IWindowManager _windowManager;
        private static Android.Media.Projection.MediaProjectionManager _mediaManager;
        private static Handler handler;
        private static int _mResultCode;
        private static Android.Content.Intent _mResultData;
        private static Android.Media.Projection.MediaProjection _mediaProjection;
        public static void Setup(
            Android.Views.IWindowManager windowManager,
            Android.Media.Projection.MediaProjectionManager mediaManager,
            int mResultCode,
            Android.Content.Intent mResultData)
        {
            _windowManager = windowManager;
            _mediaManager = mediaManager;
            handler = new Handler();
            _mResultCode = mResultCode;
            _mResultData = (Android.Content.Intent)mResultData.Clone();
        }

        public static Point GetScreenSize()
        {
            var display = _windowManager.DefaultDisplay;
            var metrics = new Android.Util.DisplayMetrics();
            display.GetMetrics(metrics);
            var pos = new Android.Graphics.Point();
            display.GetRealSize(pos);
            return new Point(pos.X, pos.Y);
        }
        public static async System.Threading.Tasks.Task<byte[]> ScreenShot(ScreenType screenType, bool wantBytes, float argFirst = 1)
        {
            if (_mediaProjection == null)
            {
                _mediaProjection = _mediaManager.GetMediaProjection(_mResultCode, _mResultData);
            }
            var display = _windowManager.DefaultDisplay;
            var metrics = new Android.Util.DisplayMetrics();
            display.GetMetrics(metrics);
            var pos = new Android.Graphics.Point();
            display.GetRealSize(pos);
            var densityDpi = metrics.DensityDpi;

            var ImageReader = ImageReaderEx.NewInstance(pos.X, pos.Y, Android.Graphics.Format.Rgba8888, 2);

            MyImageReaderListener imageReaderListener = new MyImageReaderListener(handler, pos.Y > pos.X, wantBytes, display, screenType, argFirst);
            DisplayFlags displayFlags = (DisplayFlags)(
                Android.Hardware.Display.VirtualDisplayFlags.OwnContentOnly |
                Android.Hardware.Display.VirtualDisplayFlags.Public);

            _mediaProjection.CreateVirtualDisplay("ScreenCapture", pos.X, pos.Y, (int)densityDpi, displayFlags, ImageReader.Surface, null, handler);

            ImageReader.SetOnImageAvailableListener(imageReaderListener, handler);

            if (!wantBytes)
                return null;

            byte[] data = null;

            for (int count = 0; count < 12; ++count)
            {
                await Task.Delay(200);
                data = imageReaderListener.GetImage();
                if (data != null)
                    return data;
            }
            return null;
        }
    }