Determining the current foreground application from a background task or service

后端 未结 13 1703
我寻月下人不归
我寻月下人不归 2020-11-22 02:29

I wish to have one application that runs in the background, which knows when any of the built-in applications (messaging, contacts, etc) is running.

So my questions

13条回答
  •  野的像风
    2020-11-22 03:10

    i had to figure out the right solution the hard way. the below code is part of cyanogenmod7 (the tablet tweaks) and is tested on android 2.3.3 / gingerbread.

    methods:

    • getForegroundApp - returns the foreground application.
    • getActivityForApp - returns the activity of the found app.
    • isStillActive - determines if a earlier found app is still the active app.
    • isRunningService - a helper function for getForegroundApp

    this hopefully answers this issue in all extend (:

    private RunningAppProcessInfo getForegroundApp() {
        RunningAppProcessInfo result=null, info=null;
    
        if(mActivityManager==null)
            mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
        List  l = mActivityManager.getRunningAppProcesses();
        Iterator  i = l.iterator();
        while(i.hasNext()){
            info = i.next();
            if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
                    && !isRunningService(info.processName)){
                result=info;
                break;
            }
        }
        return result;
    }
    
    private ComponentName getActivityForApp(RunningAppProcessInfo target){
        ComponentName result=null;
        ActivityManager.RunningTaskInfo info;
    
        if(target==null)
            return null;
    
        if(mActivityManager==null)
            mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
        List  l = mActivityManager.getRunningTasks(9999);
        Iterator  i = l.iterator();
    
        while(i.hasNext()){
            info=i.next();
            if(info.baseActivity.getPackageName().equals(target.processName)){
                result=info.topActivity;
                break;
            }
        }
    
        return result;
    }
    
    private boolean isStillActive(RunningAppProcessInfo process, ComponentName activity)
    {
        // activity can be null in cases, where one app starts another. for example, astro
        // starting rock player when a move file was clicked. we dont have an activity then,
        // but the package exits as soon as back is hit. so we can ignore the activity
        // in this case
        if(process==null)
            return false;
    
        RunningAppProcessInfo currentFg=getForegroundApp();
        ComponentName currentActivity=getActivityForApp(currentFg);
    
        if(currentFg!=null && currentFg.processName.equals(process.processName) &&
                (activity==null || currentActivity.compareTo(activity)==0))
            return true;
    
        Slog.i(TAG, "isStillActive returns false - CallerProcess: " + process.processName + " CurrentProcess: "
                + (currentFg==null ? "null" : currentFg.processName) + " CallerActivity:" + (activity==null ? "null" : activity.toString())
                + " CurrentActivity: " + (currentActivity==null ? "null" : currentActivity.toString()));
        return false;
    }
    
    private boolean isRunningService(String processname){
        if(processname==null || processname.isEmpty())
            return false;
    
        RunningServiceInfo service;
    
        if(mActivityManager==null)
            mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
        List  l = mActivityManager.getRunningServices(9999);
        Iterator  i = l.iterator();
        while(i.hasNext()){
            service = i.next();
            if(service.process.equals(processname))
                return true;
        }
    
        return false;
    }
    

提交回复
热议问题