2010-07-20 11 views
77

Estoy tratando de desarrollar una aplicación que impida que un usuario llegue a una aplicación específica sin una contraseña. El escenario es ...Android, detectar cuando se inician otras aplicaciones

  1. usuario hace clic en la aplicación "Enviar" (por ejemplo)
  2. mi aplicación detecta lanzamiento de una aplicación
  3. mi aplicación confirma que es el "Enviar" aplicación
  4. mi aplicación se abre una vista sobre la parte superior, solicitando una contraseña
  5. usuario introduce una contraseña, si es correcto, mi aplicación desaparece, dejando la aplicación "Enviar" en la parte superior

estoy bien haciendo el resto de ella , jus La parte 2 me deja perplejo, y después de muchos días leyendo en Broadcast Intents, etc. y tratando de escuchar "android.intent.action.MAIN", etc. en mis proyectos de prueba, parece que no puedo detectar cuándo otra aplicación que no sea la mía es empezado.

¿Alguien puede ayudar? ¿Lo estoy haciendo de la manera correcta, buscando nuevas aplicaciones que transmitan un intento de comenzar, o debería leer el registro del sistema para nuevas intenciones o hacer algo con código nativo?

Cualquier apuntador ayudaría, incluso si no puede responderlo completamente, podré investigar un poco más. Muchas gracias. Ian

+0

@lan ¿Cómo resolvió su problema? ¿Puede compartir su conocimiento? – nida

+0

¿tiene la solución? – ask4solutions

+0

No estoy seguro de cómo lo han hecho, pero aplicaciones como [App Protector] (http://www.androlib.com/android.application.com-carrotapp-protectdemo12-nFzA.aspx) hacen exactamente lo que tú ' preguntando, por lo que es técnicamente posible. – hanspeide

Respuesta

30

Creo que podemos usar logcat y analizar su salida.

En todos los programas similares que he encontrado este permiso:

android.permission.READ_LOGS

Es decir, todas ellas lo utilizan pero parece que el programa se inicia y después de que nuestro programa (protector de la aplicación) pondrá en marcha y llevar a delante .

Uso continuación Código:

try 
    { 
     Process mLogcatProc = null; 
     BufferedReader reader = null; 
     mLogcatProc = Runtime.getRuntime().exec(new String[]{"logcat", "-d"}); 

     reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream())); 

     String line; 
     final StringBuilder log = new StringBuilder(); 
     String separator = System.getProperty("line.separator"); 

     while ((line = reader.readLine()) != null) 
     { 
      log.append(line); 
      log.append(separator); 
     } 
     String w = log.toString(); 
     Toast.makeText(getApplicationContext(),w, Toast.LENGTH_LONG).show(); 
    } 
    catch (Exception e) 
    { 
     Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show(); 
    } 

Y no se olvide de añadir que es el permiso de archivo de manifiesto.

+0

por favor, ¿dónde tenemos que poner este código? en un servicio? en el comando onStart()? –

+0

@haythemsouissi puede ejecutarlo en un hilo. –

+0

Hola, alguien puede responder esta pregunta: http://stackoverflow.com/questions/10874904/detect-when-user-lunch-a-new-application-in-android-device/10875633#10875633 Está relacionado con esto el tema –

9

El problema principal es que está tratando de escuchar los intentos implícitos cuando el Iniciador (pantalla de inicio) normalmente utiliza intenciones explícitas.

Un intento implícito es cuando quieres decir "Somebody play this video" y Android elige una aplicación que pueda manejar esa intención.

Una intención explícita es lo que sucede cuando hace clic en el ícono "Correo electrónico" en la pantalla de inicio. Específicamente le está diciendo a Android que abra esa aplicación específica con un nombre completamente calificado (es decir, com.android.mail o algo así).

No hay manera de que AFAIK intercepte tales intentos explícitos. Es una medida de seguridad integrada en Android que no hay dos actividades que puedan tener el mismo nombre de paquete completamente calificado. Esto evita que un tercero clone la aplicación y se haga pasar por esa aplicación. Si lo que desea hacer es posible, en teoría podría instalar una aplicación que podría bloquear el funcionamiento de todas las aplicaciones de su competencia.

Lo que intenta hacer va en contra del modelo de seguridad de Android.

Una cosa que podría hacer es asociarse con desarrolladores de aplicaciones específicas para reenviar los intentos a su sistema de seguridad, pero eso probablemente no sea algo con lo que quiera lidiar.

2

Quizás necesite un servicio, algo que se ejecutará en segundo plano constantemente. Que tu servicio haga lo que dijiste. Escucha el android.intent.action.MAIN también con la categoría android.intent.category.Launcher. Luego haga que el receptor de difusión anule el método onReceive y verifique para ver el nombre de la aplicación, etc.

+2

Esto suena como el método en el que estaba pensando, pero estoy luchando por recibir la transmisión MAIN (cat. LAUNCHER) con un BroadcastReceiver básico. ¿Alguien ha logrado hacer esto antes? En este momento solo estoy buscando detectar que una aplicación se ha iniciado o reanudado. Entonces puedo comparar el nombre del paquete con una cadena que contenga los nombres que estoy buscando. – Ian

10

Creo y espero que esto no sea posible. Considere cuán fácilmente esa funcionalidad podría ser abusada por software malicioso. Puede escuchar los intentos dirigidos a usted, y aquellos que se transmiten, pero el lanzamiento de la aplicación no debe ser un evento de transmisión.

Lo que puede hacer es replace the launcher. Si el usuario está de acuerdo.

+2

+1 para una solución alternativa para resolver la verdadera pregunta. – Nate

+1

¿Por qué no debería ser posible? Es mi dispositivo y decido qué ejecutar en él. ¿Cómo es esto más un problema que los otros permisos que otorgamos de forma rutinaria? Un iniciador de reemplazo no detectará el lanzamiento de todas las aplicaciones solo aquellas lanzadas directamente por él. Hay muchos comentarios sobre esto y temas similares sobre SO que afirman que ser capaz de simplemente ver los intentos sería un gran problema, pero nadie explica cuál es el problema y por qué debe considerarse tan desagradable que el sistema de privilegios existente no puede ser utilizado para dejar en claro al usuario lo que está sucediendo. –

+0

Como van los permisos prospectivos, este es un juego de niños. El objetivo de tener un modelo de seguridad es habilitar la mayoría de los casos de uso legítimos, al tiempo que se previene la mayoría de los exploits (idealmente todos). No es solo usted (presumiblemente un usuario bien informado) quien necesita protección, sino también usuarios ingenuos que instalan aplicaciones y escritores de aplicaciones que no tienen que considerar otro vector de ataque. Toda la seguridad es una solución de compromiso: en este caso, entre la utilidad y la potencia frente a la explotación masiva. Usted es libre de clonar la pila de Android y codificar su propio sistema si realmente desea ese grado de libertad para usted. –

15

Una manera efectista de hacerlo es tener un servicio con un ciclo temporizado que comprueba

ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); 
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses(); 

Se ejecuta a través de esa lista para ver lo que se está ejecutando en el teléfono. Ahora se puede identificarlos con las identificaciones y processName, por lo que para la actividad normal esto es fácil para los personalizados bien a menos que todos ellos deja su difícil discriminar ...

Nota: esto no es una lista de cuál es en realidad en la pantalla, solo una lista de lo que se está ejecutando ... un poco anulando tu objetivo, pero al menos sabrás cuando algo está comenzando a correr ... seguirá estando en esa lista incluso cuando esté en el fondo.

Para la cosa de contraseña puede simplemente comenzar su actividad cuando encuentre una aplicación que esté protegida o lo que sea.

+0

¿es posible obtener el momento en que se inició/reinició la aplicación? – 0LLiena

+3

Ya no se ejecutará en Android L, aunque es una buena respuesta. – JacksOnF1re

+2

En Android L, use el paquete 'android.app.usage' en su lugar. https://developer.android.com/reference/android/app/usage/package-summary.html –

10
class CheckRunningActivity extends Thread{ 
    ActivityManager am = null; 
    Context context = null; 

    public CheckRunningActivity(Context con){ 
     context = con; 
     am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
    } 

    public void run(){ 
     Looper.prepare(); 

     while(true){ 
      // Return a list of the tasks that are currently running, 
      // with the most recent being first and older ones after in order. 
      // Taken 1 inside getRunningTasks method means want to take only 
      // top activity from stack and forgot the olders. 
      List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); 

      String currentRunningActivityName = taskInfo.get(0).topActivity.getClassName(); 

      if (currentRunningActivityName.equals("PACKAGE_NAME.ACTIVITY_NAME")) { 
       // show your activity here on top of PACKAGE_NAME.ACTIVITY_NAME 
      } 
     } 
     Looper.loop(); 
    } 
} 

Puede obtener actual que se ejecuta Activity y comprobar si esto corresponde a ActivityEmail aplicación.

Ejecutar CheckRunningActivityThread en Application iniciar (o en el inicio del dispositivo).

new CheckRunningActivity().start(); 

Actualización: Esta clase necesitan android.permission.GET_TASKS permiso, por lo que añadir la siguiente línea al Manifiesto:

<uses-permission android:name="android.permission.GET_TASKS" /> 
+0

Estoy usando este enfoque, pero esto abrirá su "// muestra su actividad aquí sobre PACKAGE_NAME.ACTIVITY_NAME "una y otra vez debido al bucle. ¿Alguna solución para eso? –

+0

detener el hilo de CheckRunningActivity cuando obtiene el resultado deseado –

+0

Gracias por responder, ¿cómo/cuándo este hilo se reinicia nuevamente? Estoy usando un servicio fijo. –

5

getRunningTasks() está en desuso en Android L.

Para obtener aplicaciones de uso de estadísticas que puede usar la clase UsageStats del paquete android.app.usage.

La nueva API de estadísticas de uso de aplicaciones permite a los desarrolladores de aplicaciones recopilar estadísticas relacionadas con el uso de las aplicaciones. Esta API proporciona información de uso más detallada que el método obsoleto getRecentTasks().

Para utilizar esta API, primero debe declarar el permiso android.permission.PACKAGE_USAGE_STATS en su manifiesto. El usuario también debe habilitar el acceso para esta aplicación a través del Settings > Security > Apps with usage access.

Here es un ejemplo de aplicación básica que muestra cómo usar la API de estadísticas de uso de aplicaciones para que los usuarios puedan recopilar estadísticas relacionadas con el uso de las aplicaciones.

+0

cómo las estadísticas de uso pueden ayudar a saber qué aplicación está en primer plano? – Ajay

+0

@Ajay como este: https://gist.github.com/plateaukao/011fa857d1919f2bbfdc – Boy

Cuestiones relacionadas