1

I need to update my Activity from a background service using LocalBroadcast if the Activity is running. If the Application or Activity is not running at present, I would like to add a Pending Notification.

I went through following posts -

Check if activity is running from service

Activity or Notification via Ordered Broadcast

I have following queries -

  • How to check if Application/Activity is running from a background service?
  • If I register and un-register broadcast listener in onPause() and onResume() in my activity, do i still need to check if activity is running?
  • According to link#2 above - If the activity is not on-screen, its receiver will not be registered, so the event will go to the default handler, in the form of your manifest-registered BroadcastReceiver, which will raise the Notification - How to achieve this if possible?

If there are other solutions, please share them too.

Community
  • 1
  • 1
pankaj
  • 1,316
  • 3
  • 16
  • 27
  • register and un-register broadcast listener in onPause() and onResume() is good solution, and u can register listener in your service, each time activity going to background, call registered listener in service and set something to add pending notification – Saeed-rz Oct 30 '15 at 08:12
  • @Leon_SFS, can you please elaborate on what you mean by `registering listener in service` – pankaj Oct 30 '15 at 08:24
  • i mean a broadcast listener on your service, activity send broadcast and service get it and know activity is shutdown – Saeed-rz Oct 30 '15 at 08:27
  • Ohk, that means whenever activity is closed we gets to know the status in Service. thanks! – pankaj Oct 30 '15 at 08:36

1 Answers1

1

I faced the same situation from the past one week. I found out a better solution which might help you.

To find whether the activity is the currently running activity in service

boolean isNotificationRequired = true;
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
Log.d("TEST", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName());
ComponentName componentInfo = taskInfo.get(0).topActivity;
componentInfo.getPackageName();

Add in manifest file

<uses-permission android:name="android.permission.GET_TASKS" />

Now Perform the operation if the activity is current running activity.

if(taskInfo.get(0).topActivity.getClassName().equals(YOUR_CURRENT_ACTIVITY.class.getName())
{
     //Perform the Operations
     isNotificationRequired = false;
}

Now send the notification only if isNotificationRequired is true.

if(isNotificationRequired){
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this).setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("Notification Title")
                .setContentText("Notification Message");
        PendingIntent notifyIntent = PendingIntent.getActivity(this, requestcode,
                resultIntent, PendingIntent.FLAG_ONE_SHOT);
        mBuilder.setContentIntent(notifyIntent);
        mBuilder.setAutoCancel(true);
        mBuilder.setDefaults(Notification.DEFAULT_VIBRATE
                | Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS);
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        mNotificationManager.notify(requestcode, mBuilder.build());    
}

Else, send the broadcast and update your activity.

(For me if I send the existing intent, its not received properly in the receiver. So i created new intent and passed the existing intent's data in putExtras() of this newIntent.)

else {
            Log.i("TEST", "Sending broadcast to activity");
            Intent newIntent = new Intent();
            newIntent.setAction("TestAction");
            sendBroadcast(newIntent);
     }

Then in your activity handle the broadcast by Creating broadcat receiver. Dont forget to instantiate. No need to mention your receiver in manifest.xml.

public class YourCurrentRunningActivity extends Activity {
    YourBroadcastReceiver receiver = new YourBroadcastReceiver();

    protected void onCreate(Bundle savedInstanceState) {
    (this).registerReceiver(receiver, new IntentFilter("TestAction"));

     public class YourBroadcastReceiver extends BroadcastReceiver {

         @Override
         public void onReceive(Context arg0, Intent arg1) {
              // Perform the Actions u want.
         }
     }
}

Then you can unregister the receiver in onStop()/onPause()/onDestroy() like this :

this.unregisterReceiver(receiver);
Geetha
  • 36
  • 5
  • Thanks ! A downside of this approach is that - Using ActivityManager is not recommended - `As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak person information to the caller. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive` – pankaj Oct 30 '15 at 14:54
  • I finally went ahead with your suggestion, except that check for Activity. – pankaj Nov 03 '15 at 01:30
  • Glad to hear. Can you please tell me how you find current activity without using ActivityManager? – Geetha Nov 03 '15 at 09:58
  • As mentioned in the comments above - you can use another broadcast receiver which gets fired in onPause() of your activity and you can get this info in your service. There is another way, which may not be a recommended practice - you can have a static variable in your activity and set/reset it in onPause() and onResume() ; you can read this variable in your service. – pankaj Nov 03 '15 at 17:34