This is the second recipe on our way to building The Internship application. Here, we will monitor the applications that are open on our system.
For this recipe, we will continue to work with the TimeReceiver
class created in the previous recipe.
We will do the application monitoring using the following steps:
SMS_APP_NAME
constant in the TimeReceiver
class as follows:private const String SMS_APP_NAME = "com.android.mms.ui.ConversationList";
smsAppLaunched
, taking a Context
object as parameter and returning a Boolean
value:private bool smsAppLaunched(Context context) { //Check the 20 last launched activity ActivityManager activityManager = (ActivityManager) context.GetSystemService (Context.ActivityService); IList<ActivityManager.RunningTaskInfo> list = activityManager.GetRunningTasks (20); foreach (ActivityManager.RunningTaskInfo task in list) { //If the sms app is open if (task.BaseActivity.ClassName.Equals (SMS_APP_NAME, StringComparison.Ordinal)) { Console.WriteLine ("The SMS app is open..."); return true; } } return false; }
smsAppLaunched
in the OnReceive()
method so that it now looks as follows:public override void OnReceive (Context context, Intent intent) { Console.WriteLine ("Time Received"); //If we are in the dangerous timeframe if (DateTime.Now.Hour >= 0 && DateTime.Now.Hour <= 6) { Console.WriteLine ("We are in the dangerous hours"); if (smsLaunched(context)) { Console.WriteLine ("We have to do something !"); } } }
READ_LOG
and GET_TASKS
permissions in your AndroidManifest
file in order to have the authorization to execute activityManager.GetRunningTasks (20);
.Console.WriteLine ("Time Received"); Console.WriteLine ("We are in the dangerous hours"); Console.WriteLine ("The SMS app is open..."); Console.WriteLine ("We Have to do something!");
The modifications performed in order to have the running application are contained in the smsAppLaunched()
method:
ActivityManager activityManager = (ActivityManager) context.GetSystemService (Context.ActivityService); IList<ActivityManager.RunningTaskInfo> list = activityManager.GetRunningTasks (20);
In this snippet of code, we use the context object received in the OnReceived()
method passed to the smsAppLaunched
parameter to obtain the activity manager. The activity manager is cast from the ActivityService
instance running continuously on Android. Then, we retrieve the last 20 running tasks using the GetRunningTasks()
method of the activityManager
class and store the response in a list of RunningTaskInfo
.
This RunningTaskInfo
instance contains a reference to the base activity that it represents. We can get the name of the activity using the following:
RunningTaskInfo.BaseActivity.ClassName
By browsing through our list with a foreach
statement and testing the class name, we can determine if the SMS activity is running or not:
foreach (ActivityManager.RunningTaskInfo task in list) { //If the sms app is open if (task.BaseActivity.ClassName.Equals (SMS_APP_NAME, StringComparison.Ordinal)) { Console.WriteLine ("The SMS app is open..."); return true; } }
Hold on! Is this a security hole? Should we be able to see what other applications are running on the phone? Well, yes and no. Yes, you can retrieve all the applications running on the system at the same time as your application and as often as you want, which can be seen as a privacy problem, but you won't be able to kill those applications. Now, you may be wondering how the task killer works. Well, they don't kill applications but restart them. As you know from Chapter 2, Mastering the Life and Death of Android Apps, restarting an application will save the application state and remove the process if the application was pushed to the background.
18.117.229.187