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!
Leave a Reply



(Your email will not be publicly displayed.)


Captcha Code

Click the image to see another captcha.