【问题标题】:Problem with screen capturing in Xamarin-AndroidXamarin-Android 中的屏幕捕获问题
【发布时间】:2021-04-15 06:21:24
【问题描述】:

我创建了一个用于捕获设备屏幕的程序。 该程序包括 2 部分。主类和服务类。捕获操作在服务类中执行。 我必须通过 Dependency Service 将 Main Activity 上下文发送到服务类。 这是 MainActivity 类:

     protected override void OnCreate(Bundle savedInstanceState)
        {
            Xamarin.Forms.Forms.Init(this, savedInstanceState);
            Xamarin.Forms.DependencyService.Register<A_Service.ScreenshotService>();
            Xamarin.Forms.DependencyService.Get<A_Service.ScreenshotService>().SetActivity(this);
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            SetContentView(Resource.Layout.activity_main);
            StartRecordButton = (Button)FindViewById(Resource.Id.btnStartRecord);
            StopRecordButton = (Button)FindViewById(Resource.Id.btnStopRecord);

            StartRecordButton.Click += (sender, e) => {
                StartService(intent);
            };
            StopRecordButton.Click += (sender, e) => {
                StopService(intent);
            };

            Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
            SetSupportActionBar(toolbar);

            intent = new Intent(this, typeof(A_Service));
        }

这里是服务类:

    namespace AndroidService
{
    [Service]
    public class A_Service : Android.App.Service
    {
        private interface IScreenshotService
        {
            byte[] Capture();
        }

        public class ScreenshotService : IScreenshotService, IDisposable
        {
            public Activity _currentActivity;

            public void SetActivity(Activity activity)
            {
                _currentActivity = activity;
            }
            public byte[] Capture()
            {
                Android.Views.View rootView;
                rootView= _currentActivity.Window.DecorView.RootView;
                using (var screenshot = Bitmap.CreateBitmap(rootView.Width, rootView.Height, Bitmap.Config.Argb8888))
                {
                    var canvas = new Canvas(screenshot);
                    rootView.Draw(canvas);
                    using(var stream=new MemoryStream())
                    {
                        screenshot.Compress(Bitmap.CompressFormat.Png, 90, stream);
                        return stream.ToArray();
                    }
                }  
            }

            public void Dispose()
            {
                this.Dispose();
            }
        }

        public override void OnCreate()
        {
            Toast.MakeText(this, "Service is created ...", ToastLength.Long).Show();
        }

        [return: GeneratedEnum]
        public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
        {
            Toast.MakeText(this, "سرویس استارت شد", ToastLength.Short).Show();
           
            Task.Run(() =>
            {
                StartCapturing();
            });
            return StartCommandResult.Sticky;
        }

        protected void StartCapturing()
        {
            bool d = true;
            int StartSecond = DateTime.Now.Hour * 3600 + DateTime.Now.Minute * 60 + DateTime.Now.Second;
            int StopSecond;
            using(var snpshot=new ScreenshotService())
            {
                var sShot = snpshot.Capture();
                SavePhoto(sShot);
            }

            while (d)
            {
                StopSecond = DateTime.Now.Hour * 3600 + DateTime.Now.Minute * 60 + DateTime.Now.Second;
                int secDiff = System.Math.Abs(StopSecond - StartSecond);
                if (secDiff == 5) d = false;
            }
        }
        
        public bool SavePhoto(byte[] data)
        {
            string filePath = FullPath("Image");
            try
            {
                using (FileOutputStream bitmapFile = new FileOutputStream(filePath))
                {
                    var buffer = ByteBuffer.Allocate(data.Length);
                    //fos.Write(new byte[buffer.Remaining()]); 
                    byte[] bmpData = new byte[data.Length];
                    buffer.Position(0); //or buffer.Flip();
                    buffer.Get(bmpData, 0, buffer.Remaining());
                    bitmapFile.Write(bmpData);
                    bitmapFile.Close();
                }
            }
            catch
            {
                return false;
            }
            return true;
        }
    }
}

问题是在运行程序并启动服务后,在Capture方法的Service类的第二行,“_currentActivity”的值变成了NULL。(“ScreenshotService”类)

【问题讨论】:

标签: android xamarin.android


【解决方案1】:

使用DependencyService时,接口应该在共享项目中创建,不要在类中创建接口。请为接口设置public关键字,以便在原生平台上可用。

如何使用DependencyService,您可以按照以下步骤操作:

1.在共享项目中创建接口

namespace AndroidService
{
    public interface IScreenshotService
    {
        byte[] Capture();
    }
}

2.各平台实现接口注册平台实现。

[assembly: Dependency(typeof(ScreenshotService))]
namespace AndroidService.Droid
{
    public class ScreenshotService : IScreenshotService
    {
        public byte[] Capture()
        {
            //
            return xx;
        }
    }
}

2.然后使用共享项目中的函数。

var data = DependencyService.Get<IScreenshotService>().Capture();

查看文档:
DependencyService Introduction 和 DependencyService Registration and Resolution

【讨论】:

    猜你喜欢
    • 2015-06-21
    • 2013-11-13
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多