patternjavaMinor
Android close running apps
Viewed 0 times
appscloserunningandroid
Problem
I have developed a service to automatically detect whether an app has started. If the user forbid this app to start (could be chosen from a list of apps), a dialog will be shown.
```
public class AppStartReceiver extends Service {
private static final int DELAY_IN_MS = 2000;
private List forbiddenApps = new ArrayList();
private BroadcastReceiver screenReceiver = null;
private Timer timer;
private static boolean screenOn = true;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//register screen on/off receiver
registerScreenReceiver();
if (forbiddenApps.isEmpty()) {
DatabaseHelper db = new DatabaseHelper(this);
forbiddenApps = db.getAllApps();
}
//start listening for app starts
listenForAppStarts();
return START_STICKY;
}
@Override
public void onDestroy() {
unregisterReceiver(screenReceiver);
timer.cancel();
super.onDestroy();
}
/**
* start listening for apps to start
* only foreground apps are being watched
*/
private void listenForAppStarts() {
final ActivityManager actMgr = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
final String foregroundApp = actMgr.getRunningTasks(1).get(0).topActivity.getPackageName();
if (forbiddenApps.contains(foregroundApp)) {
//forbidden app detected => show dialog
Intent dialogIntent = new Intent(getBaseContext(), AlertActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
}
// stop if user turns screen off
if(!screenOn) {
timer.cancel();
}
}
```
public class AppStartReceiver extends Service {
private static final int DELAY_IN_MS = 2000;
private List forbiddenApps = new ArrayList();
private BroadcastReceiver screenReceiver = null;
private Timer timer;
private static boolean screenOn = true;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//register screen on/off receiver
registerScreenReceiver();
if (forbiddenApps.isEmpty()) {
DatabaseHelper db = new DatabaseHelper(this);
forbiddenApps = db.getAllApps();
}
//start listening for app starts
listenForAppStarts();
return START_STICKY;
}
@Override
public void onDestroy() {
unregisterReceiver(screenReceiver);
timer.cancel();
super.onDestroy();
}
/**
* start listening for apps to start
* only foreground apps are being watched
*/
private void listenForAppStarts() {
final ActivityManager actMgr = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
final String foregroundApp = actMgr.getRunningTasks(1).get(0).topActivity.getPackageName();
if (forbiddenApps.contains(foregroundApp)) {
//forbidden app detected => show dialog
Intent dialogIntent = new Intent(getBaseContext(), AlertActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
}
// stop if user turns screen off
if(!screenOn) {
timer.cancel();
}
}
Solution
- Code-Style: Good
- Functionality: no problem seen
- Potential Bugs: only one I can see
- Android-Expert-Level: I am not an android expert.
- Android-Basic-Level: Everything looks sane
Bug (in jest):
People can play 1.9 seconds of angry birds, swap to a different app, and then swap back ;-)
Suggestions:
There is only one improvement I can suggest.
private BroadcastReceiver screenReceiver = null;This line is out-of-place. The only place it is used is in your registerScreenReceiver method. You may as well declare it in that method.
I would be tempted actually to pull the declaration out of the method and make it a final in-initialization anonymous instance:
private final BroadcastReceiver screenReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i("ScreenReceiver", "Screen off");
screenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.i("ScreenReceiver", "Screen on");
listenForAppStarts();
screenOn = true;
}
}
};Code Snippets
private BroadcastReceiver screenReceiver = null;private final BroadcastReceiver screenReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i("ScreenReceiver", "Screen off");
screenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.i("ScreenReceiver", "Screen on");
listenForAppStarts();
screenOn = true;
}
}
};Context
StackExchange Code Review Q#45039, answer score: 3
Revisions (0)
No revisions yet.