Android, определить, когда запускаются другие приложения - PullRequest
89 голосов
/ 20 июля 2010

Я пытаюсь разработать приложение, которое не позволяет пользователю получить доступ к указанному приложению без пароля.Сценарий ...

  1. пользователь нажимает на приложение "Электронная почта" (например)
  2. мое приложение обнаруживает запуск приложения
  3. мое приложение подтверждает, что оноприложение "Электронная почта"
  4. мое приложение открывает вид сверху, запрашивая пароль
  5. пользователь вводит пароль, если правильно, мое приложение исчезает, оставляя приложение "Электронная почта" сверху

Все остальное я в порядке, просто часть 2 озадачивает меня, и после многих дней я читаю о Broadcast Intents и т. Д. И пытаюсь послушать "android.intent.action.MAIN"и т. д. в своих пробных проектах я не могу определить, когда запускается приложение, отличное от моего.

Кто-нибудь может помочь?Правильно ли я делаю это, ища новые приложения, передающие намерение начать, или я должен читать системный журнал для новых намерений или делать что-то в нативном коде?

Любые указатели помогут, даже если вы не сможете ответить на него полностью, я смогу провести еще несколько исследований.Большое спасибо.Ian

Ответы [ 7 ]

33 голосов
/ 30 августа 2011

Я думаю, что мы можем использовать logcat и проанализировать его вывод.

Во всех похожих программах я нашел это разрешение:

android.permission.READ_LOGS

Это означает, что все они используют его, но кажется, что программа запускается, и после этого наша программа (приложение-защитник) запускается и выводит на передний план.

Используйте код ниже:

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

И не забудьте добавить его разрешение в файл манифеста.

19 голосов
/ 10 ноября 2010

Хитрый способ сделать это - использовать службу с синхронизированным циклом, которая проверяет

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

Вы просматриваете этот список, чтобы посмотреть, что работает на телефоне. Теперь вы можете идентифицировать их с помощью идентификаторов и processName, поэтому для стандартных действий это легко сделать для пользовательских, если только вы не остановите их, их трудно различить ...

Примечание: это не список того, что на самом деле отображается на экране, это просто список того, что выполняется ... может быть, своего рода сводит на нет вашу цель, но, по крайней мере, вы будете знать, когда что-то начинает выполняться ... он останется в этом списке, даже если он будет в фоновом режиме.

Что касается пароля, вы можете просто начать свою деятельность, когда вы нашли приложение это защищено или что-то еще.

12 голосов
/ 10 марта 2014
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();
    }
}

Вы можете запустить текущий Activity и проверить, соответствует ли это Activity приложению Email.

Запуск CheckRunningActivity Thread при Application запуске (или при загрузке устройства).

new CheckRunningActivity().start();

Обновление: Этому классу нужно разрешение android.permission.GET_TASKS, поэтому добавьте следующую строку в манифест:

<uses-permission android:name="android.permission.GET_TASKS" />
12 голосов
/ 20 июля 2010

Я думаю и надеюсь, что это невозможно. Подумайте, как легко такая функциональность может быть использована вредоносным программным обеспечением. Вы можете слушать намерения, направленные на вас, и те, которые транслируются, но запуск приложения не должен быть трансляцией.

Что вы можете сделать, это заменить пусковую установку . Если пользователь согласен с этим.

10 голосов
/ 20 июля 2010

Основная проблема заключается в том, что вы пытаетесь прослушивать неявные намерения, когда Launcher (домашний экран) обычно использует явные намерения.

Под неявным намерением подразумевается, когда вы хотите сказать «Кто-нибудь воспроизводит это видео», и Android выбирает приложение, которое может обработать это намерение.

Явное намерение - это то, что происходит, когда вы нажимаете значок «Электронная почта» на главном экране. В частности, Android сообщает, что нужно открыть это конкретное приложение по полному имени (то есть com.android.mail или что-то в этом роде).

У AFAIK нет способа перехватить такие явные намерения. Это встроенная в Android мера безопасности, заключающаяся в том, что никакие два действия не могут иметь одно и то же полное имя пакета. Это предотвращает клонирование стороннего приложения и маскировку под это приложение. Если то, что вы хотите сделать, было возможно, вы теоретически могли бы установить приложение, которое могло бы блокировать работу всех приложений вашего конкурента.

То, что вы пытаетесь сделать, противоречит модели безопасности Android.

Одна вещь, которую вы могли бы сделать, - это сотрудничать с конкретными разработчиками приложений, чтобы направить намерения в вашу систему безопасности, но, вероятно, это не то, с чем вы хотите иметь дело.

7 голосов
/ 06 сентября 2015

getRunningTasks() устарела в Android L.

Для получения статистики использования приложения вы можете использовать UsageStats класс из android.app.usage пакета.

Новый API статистики использования приложений позволяет разработчикам приложений собирать статистику, связанную с использованием приложений. Этот API предоставляет более подробную информацию об использовании, чем устаревший метод getRecentTasks ().

Чтобы использовать этот API, вы должны сначала объявить разрешение android.permission.PACKAGE_USAGE_STATS в своем манифесте. Пользователь также должен разрешить доступ для этого приложения через Settings > Security > Apps with usage access.

Здесь - базовый пример приложения, показывающий, как использовать API статистики использования приложений, чтобы позволить пользователям собирать статистику, связанную с использованием приложений.

3 голосов
/ 20 июля 2010

Возможно, вам нужен сервис, который будет постоянно работать в фоновом режиме. Чем ваш сервис делает то, что вы сказали. Слушайте android.intent.action.MAIN также с категорией android.intent.category.LAUNCHER. Затем этот широковещательный приемник переопределит метод onReceive и проверьте, чтобы увидеть имя приложения и т. Д.

...