Good morning person,
I'm trying to create a service that runs every 5 seconds without binding the application, but I'm starting with basic routines that shows the moment the service goes into operation and the moment it shuts off, I can see that the service is not restarting, Can anyone give me a hand ?
Main Activity
protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); global::Xamarin.Forms.Forms.Init(this, bundle); LoadApplication(new App()); this.StartService(MyService ); }
Service Code
[Service(Exported=true)] public class MyService : Service{ public override IBinder OnBind(Intent intent){ throw new NotImplementedException(); } public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId){ Toast.MakeText(this, "Service Start", ToastLength.Long).Show(); StopSelf(); return StartCommandResult.Sticky; } public override void OnDestroy() { Toast.MakeText(this, "Service Destroy", ToastLength.Long).Show(); base.OnDestroy(); } }
Answers
Hi,
You will need something like a remote service where it will run when the application is not in focus (if that is what you want) The process cannot be running forever every 5 seconds as it will drain the battery in a few hours. For Marshmallow and above your process will start get frozen (doze mode) in half an hours then progressively more restriction as time goes by when the phone is no in motion (not moving). The Alarm that I am setting in my code is to wake up the phone to run my code but in Marshmallow you can only set it to run once every 9 minutes (you can set less time but nothing will happen).
Another thing, my code will run without the Alarm wake up if you have the device plug in to a power source. Well that defeats the purpose of having a smartphone. Anyway, until someone comes up with a battery that last a month you can have process running constantly in the background.
Hi @AlbertK
First of all, I'm relatively new in Xamarin,
I'm going to do the same process in my app and I have a questions, Why the invoke SetWakeLock method is commented and what is the purpose to use wakelock.SetReferenceCounted(false) on constructor service, can I have process running constantly in the background without plug in the device to a power source of this way?
@RubberyDev , Well SetReferenceCounted() is referenced counted by default and setting it to false means that I am counting the wakelock call locally. SetWakeLock() is not called here as you need to unset it somewhere (no included in this example). Hope this helps.
Got it!! @AlbertK
thanks
Hi @AlbertK
Thanks for sharing your code.
I'm new to Xamarin and have a question about your code:
When pasting in the code, "AlarmReceiver" is not recognized on the line:
Intent alarmintent = new Intent(this, typeof(AlarmReceiver));
Can you please also share that class, as I don't really know what to do in that class?
Also what is the correct way of calling your the service? (the way I do it is deprecated):
Kind regards
You cannot call Android specific code from Xamarin Forms. Forms is for cross platform ie the same UI and code should work in all the supported platforms (eg Android, IOS, MacOS, Tizen, UWP,etc). To run platform specific code you need to utilize Dependency Service.
In this example raising an alarm. All the different platform has their own API to set alarm. A good start is the official documentation
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction
Thanks for the answer. I made it work with your code.
In OnTimeEvent I post the current position to my server, which works really well. I set the timer to 60000 ms = 1 minute and it posts positions every minute.
But after I turn off the screen and the app goes in the background I excepted the service to post every tenth minute, as I wrote the same code in the alarmreceiver which also should post the current position. What happens is that it only calls the alarmreceiver once and then never again.
Don't really know what's wrong, but could be the code is not working on newer phones. I'm using huawei P30 Pro.
Kind regards
Maybe its the wakelock which I'm not utilizing in my code? You wrote that I have to unset it from somewhere, where would be a good place for that in my case, when posting locations.
I tried to uncomment it the call to start the wakelock but didnt unset it. Would it be expected behavior, that it still only hit the alarmreceiver once?
I don't have the latest Android OS phone. Wakelock is to hold a lock so that you can finish the task but that does not work if the phone OS does not allows it to run. Why do you ask is whatsapp, facebook working? well they are in the phone whitelist (this is fixed in the OS, ie set in factory), unfair? yes.
Also with Android 6.0 and above you have to live with Doze mode where you are only allowed to wake up every 10 minutes or so. Any lower time resolution will be ignored. I think that is what you are facing. With regards to the wake lock, yes you have to release them after running your task.
https://developer.android.com/training/monitoring-device-state/doze-standby
Hello! @mivewi @AlbertK !
I have the same question, i stop the service, and in Ondestroy i set the wakelok.release() but my alarm with a local notification only hit one time in my test. Would it be expected behavior?
or i have wakelock.Release(); after finish task on every execution from the timer (OnTimeEvent)?
Hi. trainings are available on our site to create mobile applications. you can visit.
digitalvizyon.net/Egitimdetay.aspx?EgitimID=865