Determinar la aplicación en primer plano actual a partir de una tarea o servicio en segundo plano

Resuelto dhaiwat asked hace 54 años • 0 respuestas

Deseo tener una aplicación que se ejecute en segundo plano, que sepa cuándo se está ejecutando alguna de las aplicaciones integradas (mensajería, contactos, etc.).

Entonces mis preguntas son:

  1. Cómo debo ejecutar mi aplicación en segundo plano.

  2. Cómo mi aplicación en segundo plano puede saber cuál es la aplicación que se ejecuta actualmente en primer plano.

Se agradecerían mucho las respuestas de gente con experiencia.

dhaiwat avatar Jan 01 '70 08:01 dhaiwat
Aceptado

Con respecto a "2. Cómo mi aplicación en segundo plano puede saber cuál es la aplicación que se ejecuta actualmente en primer plano".

NO utilices el getRunningAppProcesses()método ya que, según mi experiencia, devuelve todo tipo de basura del sistema y obtendrás múltiples resultados que tienen RunningAppProcessInfo.IMPORTANCE_FOREGROUND. Usar getRunningTasks()en su lugar

Este es el código que uso en mi servicio para identificar la aplicación en primer plano actual, es realmente fácil:

ActivityManager am = (ActivityManager) AppService.this.getSystemService(ACTIVITY_SERVICE);
// The first in the list of RunningTasks is always the foreground task.
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);

Eso es todo, luego podrás acceder fácilmente a los detalles de la aplicación/actividad en primer plano:

String foregroundTaskPackageName = foregroundTaskInfo .topActivity.getPackageName();
PackageManager pm = AppService.this.getPackageManager();
PackageInfo foregroundAppPackageInfo = pm.getPackageInfo(foregroundTaskPackageName, 0);
String foregroundTaskAppName = foregroundAppPackageInfo.applicationInfo.loadLabel(pm).toString();

Esto requiere un permiso adicional en el menú de actividad y funciona perfectamente.

<uses-permission android:name="android.permission.GET_TASKS" />
Oliver Pearmain avatar Oct 01 '2012 14:10 Oliver Pearmain

Pruebe el siguiente código:

ActivityManager activityManager = (ActivityManager) newContext.getSystemService( Context.ACTIVITY_SERVICE );
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for(RunningAppProcessInfo appProcess : appProcesses){
    if(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
        Log.i("Foreground App", appProcess.processName);
    }
}

El nombre del proceso es el nombre del paquete de la aplicación que se ejecuta en primer plano. Compárelo con el nombre del paquete de su aplicación. Si es igual, entonces su aplicación se está ejecutando en primer plano.

Espero que esto responda tu pregunta.

Friedrich Bhaer avatar Dec 28 '2010 05:12 Friedrich Bhaer

Tuve que encontrar la solución correcta por las malas. El siguiente código es parte de cyanogenmod7 (los ajustes de la tableta) y está probado en Android 2.3.3/gingerbread.

métodos:

  • getForegroundApp: devuelve la aplicación de primer plano.
  • getActivityForApp: devuelve la actividad de la aplicación encontrada.
  • isStillActive: determina si una aplicación encontrada anteriormente sigue siendo la aplicación activa.
  • isRunningService: una función auxiliar para getForegroundApp

Con suerte, esto responde a este problema en toda su extensión (:

private RunningAppProcessInfo getForegroundApp() {
    RunningAppProcessInfo result=null, info=null;

    if(mActivityManager==null)
        mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
    List <RunningAppProcessInfo> l = mActivityManager.getRunningAppProcesses();
    Iterator <RunningAppProcessInfo> 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 <ActivityManager.RunningTaskInfo> l = mActivityManager.getRunningTasks(9999);
    Iterator <ActivityManager.RunningTaskInfo> 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 <RunningServiceInfo> l = mActivityManager.getRunningServices(9999);
    Iterator <RunningServiceInfo> i = l.iterator();
    while(i.hasNext()){
        service = i.next();
        if(service.process.equals(processname))
            return true;
    }

    return false;
}
Sven Dawitz avatar Apr 03 '2011 08:04 Sven Dawitz