100 votes

Android, Détecter quand d'autres applications sont lancées

Bonjour J'essaie de développer une application qui empêche un utilisateur d'accéder à une application spécifique sans mot de passe. Le scénario est...

  1. l'utilisateur clique sur l'application "Email" (par exemple)
  2. mon application détecte le lancement d'une application
  3. mon application confirme qu'il s'agit de l'application "Email".
  4. mon application ouvre une vue en haut, demandant un mot de passe
  5. l'utilisateur saisit un mot de passe, s'il est correct, mon application disparaît, laissant l'application "Email" en haut.

Je suis d'accord pour faire le reste, mais la partie 2 me laisse perplexe, et après de nombreux jours de lecture sur les intentions de diffusion, etc. et d'essais d'écoute de "Android.intent.action.MAIN", etc. dans mes projets d'essai, je n'arrive pas à détecter quand une autre application que la mienne est lancée.

Quelqu'un peut-il m'aider ? Est-ce que je m'y prends de la bonne façon, en recherchant les nouvelles applications qui diffusent une intention de démarrage, ou devrais-je lire le journal système pour les nouvelles intentions, ou faire quelque chose dans le code natif ?

Toute indication serait utile, même si vous ne pouvez pas répondre complètement à la question, je pourrai faire d'autres recherches. Merci beaucoup. Ian

34voto

M.Movaffagh Points 555

Je pense que nous pouvons utiliser logcat et d'analyser ses résultats.

Dans tous les programmes similaires, j'ai trouvé cette autorisation :

android.permission.READ_LOGS

Cela signifie que tous l'utilisent mais il semble que le programme démarre et qu'après cela notre programme (app protector) démarre et apporte le front.

Utilisez le code ci-dessous :

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();
    }

Et n'oubliez pas d'ajouter sa permission dans le fichier Manifest.

21voto

Aimeric Points 101

Un moyen astucieux de le faire est d'avoir un service avec une boucle temporisée qui vérifie

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

Vous parcourez cette liste pour voir ce qui est en cours d'exécution sur le téléphone. Maintenant, vous pouvez les identifier avec les identifiants et les noms de processus, donc pour les activités standard, c'est facile, pour les activités personnalisées, à moins que vous ne les arrêtiez toutes, il est difficile de les distinguer...

Note : Ce n'est pas une liste de ce qui est réellement à l'écran, juste une liste de ce qui est en cours d'exécution... cela annule peut-être votre objectif mais au moins vous saurez quand quelque chose commence à s'exécuter... cela restera dans cette liste même si c'est en arrière-plan.

Pour le mot de passe, vous pouvez simplement lancer votre activité lorsque vous trouvez une application qui est protégée ou autre.

13voto

Veaceslav Gaidarji Points 1372
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();
    }
}

Vous pouvez obtenir des informations sur le fonctionnement actuel Activity et vérifier si ce Activity correspond à Email application.

Exécuter CheckRunningActivity Thread sur Application au démarrage (ou au démarrage du périphérique).

new CheckRunningActivity().start();

Mise à jour : Cette classe doit android.permission.GET_TASKS la permission, donc ajoutez la ligne suivante au manifeste :

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

12voto

Pontus Gagge Points 12950

Je pense et j'espère que ce n'est pas possible. Pensez à la facilité avec laquelle une telle fonctionnalité pourrait être exploitée par des logiciels malveillants. Vous pouvez écouter les intentions qui vous sont adressées et celles qui sont diffusées, mais le lancement d'une application ne devrait pas être un événement diffusé.

Ce que vous pouvez faire, c'est remplacer le lanceur . Si l'utilisateur l'accepte.

11voto

CodeFusionMobile Points 6173

Le principal problème est que vous essayez d'écouter des intentions implicites alors que le lanceur (écran d'accueil) utilise généralement des intentions explicites.

Une intention implicite, c'est lorsque vous voulez dire "Que quelqu'un lise cette vidéo" et qu'Android choisit une application qui peut gérer cette intention.

Une intention explicite est ce qui se passe lorsque vous cliquez sur l'icône "Email" sur l'écran d'accueil. Elle indique spécifiquement à Android d'ouvrir cette application spécifique par son nom complet (c'est-à-dire com.Android.mail ou autre).

Il n'y a aucun moyen AFAIK d'intercepter de telles intentions explicites. Il s'agit d'une mesure de sécurité intégrée à Android selon laquelle deux activités ne peuvent avoir le même nom de paquetage entièrement qualifié. Cela empêche une tierce partie de cloner l'application et de se faire passer pour cette dernière. Si ce que vous souhaitez faire était possible, vous pourriez théoriquement installer une application qui empêcherait toutes les applications de vos concurrents de fonctionner.

Ce que vous essayez de faire va à l'encontre du modèle de sécurité d'Android.

Vous pourriez vous associer à des développeurs d'applications spécifiques pour transmettre les intentions à votre système de sécurité, mais ce n'est probablement pas quelque chose dont vous voulez vous occuper.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X