Android Activity Foreground Surveillance

In order to check if an Activity of my Android application is currently in the foreground I wrote a simple Service.

  1. public class UEService extends Service {
  2. private static final String TAG = "UEService";
  3. private Timer timer;
  4. private static final int delay = 1000; // delay for 1 sec before first start
  5. private static final int period = 10000; // repeat check every 10 sec.
  6.  
  7. // This is the old onStart method that will be called on the pre-2.0
  8. // platform. On 2.0 or later we override onStartCommand() so this
  9. // method will not be called.
  10. @Override
  11. public void onStart(Intent intent, int startId) {
  12. handleCommand(intent);
  13. }
  14.  
  15. // To make this Service work in pre Level 5 APIs just remove this method
  16. @Override
  17. public int onStartCommand(Intent intent, int flags, int startId) {
  18. handleCommand(intent);
  19. return START_NOT_STICKY;
  20. }
  21.  
  22. // handles a Start command
  23. private void handleCommand(Intent intent) {
  24. Log.d(TAG, "service is starting");
  25.  
  26. if (timer == null) {
  27. timer = new Timer();
  28. timer.schedule(new TimerTask() {
  29. public void run() {
  30. checkActivityForeground();
  31. }
  32. }, delay, period);
  33. }
  34. }
  35.  
  36. protected void checkActivityForeground() {
  37. Log.d(TAG, "start checking for Activity in foreground");
  38. Intent intent = new Intent();
  39. intent.setAction(UESurveillanceActivity.UE_ACTION);
  40. sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
  41.  
  42. @Override
  43. public void onReceive(Context context, Intent intent) {
  44. int result = getResultCode();
  45.  
  46. if (result != Activity.RESULT_CANCELED) { // Activity caught it
  47. Log.d(TAG, "An activity caught the broadcast, result " + result);
  48. activityInForeground();
  49. return;
  50. }
  51. Log.d(TAG, "No activity did catch the broadcast.");
  52. noActivityInForeground();
  53. }
  54. }, null, Activity.RESULT_CANCELED, null, null);
  55. }
  56.  
  57. protected void activityInForeground() {
  58. Log.d(TAG, "starting method which gets called when an SureveillanceActivity is in foreground");
  59.  
  60. // TODO something you want to happen when an Activity is in the foreground
  61. }
  62.  
  63. protected void noActivityInForeground() {
  64. Log.d(TAG, "starting method which gets called when no SureveillanceActivity is in foreground");
  65.  
  66. // TODO something you want to happen when no Activity is in the foreground
  67.  
  68. stopSelf(); // quit
  69. }
  70.  
  71. @Override
  72. public IBinder onBind(Intent arg0) {
  73. // TODO Auto-generated method stub
  74. return null;
  75. }
  76.  
  77. @Override
  78. public void onDestroy() {
  79. super.onDestroy();
  80. timer.cancel();
  81. Log.d(TAG, "service is destroyed");
  82. }
  83. }

The Service class sends a special Intent witch gets answered by our custom Activity in case it is currently in the foreground.

  1. public class UESurveillanceActivity extends Activity {
  2. public static final String UE_ACTION = "at.mannaz.surveilance.inforeground";
  3. private IntentFilter mIntentFilter;
  4.  
  5. private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
  6. @Override
  7. public void onReceive(Context context, Intent intent) {
  8. String action = intent.getAction();
  9. if(action.equals(UE_ACTION)) {
  10. Log.d("UESurveilanceActivity","i'm in the foreground");
  11. this.setResultCode(Activity.RESULT_OK);
  12. }
  13. }
  14. };
  15.  
  16. @Override
  17. public void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19.  
  20. mIntentFilter = new IntentFilter();
  21. mIntentFilter.addAction(UE_ACTION);
  22.  
  23. Intent serviceIntent = new Intent(this, UEService.class);
  24. startService(serviceIntent);
  25. }
  26.  
  27. @Override
  28. protected void onResume() {
  29. registerReceiver(mIntentReceiver, mIntentFilter);
  30.  
  31. super.onResume();
  32. }
  33.  
  34. @Override
  35. protected void onPause() {
  36. unregisterReceiver(mIntentReceiver);
  37.  
  38. super.onPause();
  39. }
  40. }

This activity registers a BroadcastReceiver when it comes to the foreground and unregisters it when it goes to the background.

Here is how you use those two classes in your application:

  1. public class Dashboard extends UESurveillanceActivity {
  2. ...

Thats all. All you have to do is to change the parent class of your Activity to UESurveillanceActivity and register the Service in your manifest:

<service android:name=".UEService"></service>

If you override onCreate, onStop or onStart in your Activity don't forget to call super.onCreate/Stop/Start trough.

Download

Here is an Eclipse example project with all the sourcecodes: ActivitySurveillance.zip

Comments:

Posted by Olivier on
I am trying to use your code across 2 different APKs. Actually I am auto starting a Service on BOOT and such service is using your method to broadcast a custom intent to an external APK I am also writing. The main Activity in the APK never receives the intent. What am I doing wrong? Or what needs to be changed from your code + config to handle this case.

Thanks in advance

Olivier
Posted by Joao on
Nice solution! Worked like a charm :P thanks!
Posted by Axel on
Danke für die Idee. In meiner App habe ich ein Kommunikationsservice am laufen, welcher auch beim Programmende beendet werden muss, und deine Lösung ist gut geeignet und simpel.
Leave a Reply



(Your email will not be publicly displayed.)


Captcha Code

Click the image to see another captcha.