Android Service

NatannielNatanniel BRMember
edited November 2016 in Xamarin.Android

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

  • AlbertKAlbertK MYMember ✭✭✭

    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.

    [Service(Name = "myservice", Enabled = true, Process = ":bgservice") ]
        public partial class MyService : Service
        {
            private const string TAG = "bgservice";
    
    
            private int wakelockcount = 0;
            private System.Timers.Timer _timer= null;
            private PowerManager.WakeLock wakelock = null;
    
    
            public override void OnCreate()
            {
                base.OnCreate();
    
                PowerManager pmanager = (PowerManager)this.GetSystemService("power");
                wakelock = pmanager.NewWakeLock(WakeLockFlags.Partial, "servicewakelock");
                wakelock.SetReferenceCounted(false);
    
            }
    
    
            public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
            {
    
                Log.Info(TAG, "OnstartCommand ");
                //SetWakeLock();
    
    
    
                AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
                long triggerAtTime = SystemClock.ElapsedRealtime() + (10 * 60 * 1000);
                Intent alarmintent = new Intent(this, typeof(AlarmReceiver));
    
                PendingIntent pendingintent = PendingIntent.GetBroadcast(this, 0, alarmintent, 0);
                if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.M)
                {
                    manager.Cancel(pendingintent);
                    manager.SetAndAllowWhileIdle(AlarmType.ElapsedRealtimeWakeup, triggerAtTime, pendingintent);
                    Log.Info(TAG, "Alarm SetAndAllowWhileIdle Set");
    
                }
                else if(Android.OS.Build.VERSION.SdkInt == BuildVersionCodes.KitKat || Android.OS.Build.VERSION.SdkInt == BuildVersionCodes.Lollopop)
                {
                    manager.Cancel(pendingintent);
                    manager.SetExact(AlarmType.ElapsedRealtimeWakeup, triggerAtTime, pendingintent);
                }
    
    
                    timer(this, null);
    
                return StartCommandResult.Sticky;
            }
    
        public void SetWakeLock()
            {
                if( ! wakelock.IsHeld)
                {
                    wakelock.Acquire();
                    wakelockcount += 1;
                    Log.Info(TAG, "WakeLock Armed");
                }
            }
    
         public void timer(object sender, EventArgs e)
            {
    
                Log.Info(TAG, "Starting Timer" );
    
    
                if (_timer != null)
                {
                    _timer.Enabled = false;
                    _timer.Dispose();
                    _timer = null;
                }
                _timer = new System.Timers.Timer();
                //Trigger event every 5 seconds
                _timer.Interval = 5000;
                _timer.Elapsed += OnTimeEvent; //new System.Timers.ElapsedEventHandler(OnTimeEvent);
                _timer.Enabled = true;
                _timer.AutoReset = true;
                _timer.Start();
            }
    
        private async void OnTimeEvent(object sender, System.Timers.ElapsedEventArgs e)
            {
               //This will be called when the timer.Elapsed. So do your work here.
            }
    
  • RubberyDevRubberyDev Member
    edited March 14

    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?

  • AlbertKAlbertK MYMember ✭✭✭

    @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.

  • RubberyDevRubberyDev Member

    Got it!! @AlbertK
    thanks

Sign In or Register to comment.