Reputation: 93
I've created a program for capturing the screen of my device. This program is include of 2 part. The main class and the service class. Capturing operation is performed in the service class. I have to send Main Activity context to service class via Dependency Service . Here is the MainActivity class:
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));
}
And here is the Service class:
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;
}
}
}
The problem is that after running the program and start the service , on second line of Service class in Capture method the value of "_currentActivity" is became NULL.("ScreenshotService" class)
Upvotes: 0
Views: 164
Reputation: 1013
When using DependencyService, the interface should be created in the shared project and don't create the interface inside a class. Please set the public
keyword for the interface so that it could be available in the native platform.
How to use the DependencyService, you could following the steps:
1.Create an interface in the shared project
namespace AndroidService
{
public interface IScreenshotService
{
byte[] Capture();
}
}
2.Implement the interface on each platform register the platform implementation.
[assembly: Dependency(typeof(ScreenshotService))]
namespace AndroidService.Droid
{
public class ScreenshotService : IScreenshotService
{
public byte[] Capture()
{
//
return xx;
}
}
}
2.Then consume the function in the shared project.
var data = DependencyService.Get<IScreenshotService>().Capture();
Check the docs:
DependencyService Introduction and DependencyService Registration and Resolution
Upvotes: 1