Using M2MQTT running as a bound service. Once phone sleeps it stops receiving messages.

My application receives information from another micro-controller about actuator status (postion of motor and state of motor on/off). State of the motor is where I am having problems. My setup sends on command if actuator is running and another if actuator is not running. Everything works perfectly if connected to the computer. However, if I run the app on the phone dis connected from the computer, it will work fine until phone sleeps. After phone sleeps the actuator state is no longer being updated.

I know the messages are being sent because I am watching them come across my mqtt broker.

before I created the service once the phone slept I couldn't send any commands at all. Now with the service the commands are being sent. But which command to send is based on wether the actuator is running or not and this is not being updated.

I even put the receive method in the serviceConnection class. this does not help.

I am using m2mqtt.net.dll that I got from compiling the github version of m2mqtt.

Please help

Tagged:

Best Answers

Answers

  • MarkTalentMarkTalent USMember ✭✭

    I tried using the adm so started the application on the phone not through debugger and the application is working fine after entering sleep mode the only problem I am having is when the phone is not connected to the computer. I am going to try just connecting to power and seeing what difference that makes

  • MarkTalentMarkTalent USMember ✭✭

    OK I am hoping this is going to narrow it down. When plugged into just power and the app is started it works fine after phone sleeps. I am going to try to research what exactly happens different when phone is not plugged in at all. Please help

  • MarkTalentMarkTalent USMember ✭✭

    Well I guess this is either a boring question or no one has an answer. My application is somewhat large and complex, so this morning I am going to design a very simplified version of what I need and see if I can find a way to make it work with the phone not plugged into power.

  • MarkTalentMarkTalent USMember ✭✭

    Ryan you are 100% correct I have been working on forground service all day. I was trying to have a bound service because when the app shuts down I don't need the connection to the mqtt any more. But I couldn't get it to work that way.

    But when I did a started service that implemented the OnStartCommand(Intent intent, StartCommandFlags flags, int startId)

    and I put my connection and the notification build (your way looks easier) and the the return start sticky It appears to be working..

    Crud everything was working fine until my test phone got a call while asleep and after that the mqtt seemed to stop updating the actuator status. I am going to play with it for a while here is my OnStartCommand

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {

            // this is the class that opens the mqtt connection
            connect = new Connection(Utility.data, Utility.cdata);
            // here I put connect variable into a static class I use this connect throughout the app            
            Utility.connect = connect;
    
            Toast.MakeText(this, "OnStart Called", ToastLength.Long).Show();
    
            var notification = new Notification.Builder(this)
                .SetContentTitle("Apollo Title")
                .SetContentText("Apollo Content")
                .SetSmallIcon(Resource.Drawable.ic_stat_more)
                //.SetContentIntent(BuildIntentToShowMainActivity())
                .SetOngoing(true)
                //.AddAction(BuildRestartTimerAction())
                //.AddAction(BuildStopServiceAction())
                .Build();
    
            // Enlist this instance of the service as a foreground service
            StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
    
            return StartCommandResult.Sticky;
    
        } 
    

    this is in my mqttService class that extends service

    I am so glad you replied I have to help a friend out for an hour or so, then I will be back at it and I have question and I will be PM you

    thanks
    Mark

  • RyanFrenchRyanFrench USMember ✭✭
    edited October 2017

    I have not tested on Android 8, so if your device is running that it may have something to do with the service going down.

    To stop the service when the app goes down add OnDestroy to main:

        protected override void OnDestroy()
            {
                _serviceTools.ShutdownServices();
                base.OnDestroy();
            }
    

    In your service util class you would add something like this (Android Studio says GetRunningServices is depreciated in API 26 so there might be a better way)

        public void ShutdownServices()
            {
                Context context = Android.App.Application.Context;
                ActivityManager mngr = (ActivityManager)context.GetSystemService(Context.ActivityService);
                List<RunningServiceInfo> services = mngr.GetRunningServices(Int32.MaxValue).ToList();
                services = services.Where(x => x.Service.PackageName.ToString() == "com.xyz.appName").ToList();
    
                foreach (RunningServiceInfo runningServiceInfo in services)
                {
                    if (runningServiceInfo.Service.ClassName == "com.xyz.appName.AppService")
                    {
                        MessagingCenter.Send<IServiceTools>(this, AppMessages.AppServiceOnDestroy);
                        context.StopService(new Intent(context, typeof(Services.AppService)));
                    }
                }
            }
    

    EDIT I didn't see where you were actually calling Notify (for your notification). Here is an example of my BuildNotification() method.

     public void BuildNotification(String message = "", Boolean uploadInProgress = false)
            {
                Intent intent = Android.App.Application.Context.PackageManager.GetLaunchIntentForPackage(Android.App.Application.Context.PackageName);
                intent.AddFlags(ActivityFlags.ClearTop);
    
                PendingIntent pendingIntent = PendingIntent.GetActivity(Android.App.Application.Context, 0, intent, PendingIntentFlags.UpdateCurrent);
                if (!uploadInProgress)
                {
                    SvcsNotification = new Notification.Builder(Android.App.Application.Context)
                    .SetAutoCancel(false)
                    .SetOngoing(true)
                    .SetContentTitle("App Service")
                    .SetContentText("App Running")
                    .SetSmallIcon(Resource.Drawable.cp_icon)
                    .SetContentIntent(pendingIntent)
                    .Build();
                }
                else
                {
                    _builder = new NotificationCompat.Builder(Android.App.Application.Context);
                    _builder.SetAutoCancel(false);
                    _builder.SetOngoing(true);
                    _builder.SetContentTitle("App Service");
                    _builder.SetContentText(String.Format("Uploading... {0}", message));
                    _builder.SetSmallIcon(Android.Resource.Drawable.StatSysUpload);
                    _builder.SetLargeIcon(BitmapFactory.DecodeResource(Android.Content.Res.Resources.System, Android.Resource.Drawable.StatSysUpload));
                    _builder.SetContentIntent(pendingIntent);
                    SvcsNotification = _builder.Build();
                }
    
                if (_nMgr != null)
                    _nMgr.Notify((Int32)ServiceType.CoPilotServiceID, (Notification)SvcsNotification);
                else
                {
                    _nMgr = (NotificationManager)Android.App.Application.Context.GetSystemService(ContextWrapper.NotificationService);
                    _nMgr.Notify((Int32)ServiceType.CoPilotServiceID, (Notification)SvcsNotification);
                }
            }
    
Sign In or Register to comment.