Search code examples
androidtcpsleeplocked

How to communicate with a client app on an idle/sleeping/locked Android device from server?


I am trying to figure out how to send event actions to my client app from the server when the device has gone to sleep/idle/locked.

I know this is possible as I can see Whatsapp/Facebook/Viber calls waking the device immediately on incoming call and starting their dialer activity. This means they can communicate with the app. More than just sending a notification to be displayed.

Currently I have implemented it in what I believe is a kind of workaround way. I send a push notification from the server, which in turn is received on a PushBroadCastReceiver in the client app side. Then, this receiver starts my service which maintains a TCP connection with my server. At this point I can start communicating with my app through this service by sending messages/event actions to the TCP connection.

It works, but nevertheless I feel this way is quirky and they must be doing it in some better way. But I can't think of one. Can anyone help?

Thanks!


Solution

  • I'm not exactly sure if this is what you want, but perhaps an AlarmManger is what you're looking for. Rather than pushing from the server to the client, you just have the client wake up and request info from the server at a regular interval. Here's a snippet of code that I have used to periodically send location information.

    public class LocationRequestReceiver extends BroadcastReceiver {
        private static final String TAG = "Location Request Receiver";
    
        public LocationRequestReceiver() {}
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() == null) {
                WakefulIntentService.sendWakefulWork(context, LocationRequestService.class);
            }
            else {
                scheduleLocationRequestService(context);
            }
        }
    
        public static void scheduleLocationRequestService(Context context) {
            Log.d(TAG,"Scheduling Location Request Service");
            AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(context, LocationRequestReceiver.class);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
    
            mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                    SystemClock.elapsedRealtime() + Constants.INITIAL_DELAY,
                    Constants.PASSIVE_LOCATION_UPDATE_INTERVAL_IN_MILLISECONDS, pendingIntent);
    
        }
    }