Android, виявляти при запуску інших програм


92

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

  1. користувач натискає додаток "Електронна пошта" (наприклад)
  2. мій додаток виявляє запуск програми
  3. мій додаток підтверджує, що це додаток "Електронна пошта"
  4. моя програма відкриває вид зверху, запитуючи пароль
  5. користувач вводить пароль, якщо правильно, мій додаток зникає, залишаючи зверху програму "Електронна пошта"

Я все добре роблю, просто частина 2 мене бентежить, і через багато днів читаючи трансляції про наміри тощо і намагаючись вислухати "android.intent.action.MAIN" тощо у своїх пробних проектах, я не можу схоже виявляє, коли запускається програма, окрім моєї.

Хто-небудь може допомогти? Чи я роблю це правильно, шукаючи нові програми, які транслюють намір розпочати, чи я повинен читати системний журнал про нові наміри або робити щось у власному коді?

Будь-які вказівки допоможуть, навіть якщо ви не можете відповісти повністю, я зможу провести ще кілька досліджень. Дуже дякую. Ян


Я не впевнений, як вони це зробили, але такі програми, як App Protector , виконують саме те, про що ви просите, тому технічно це можливо.
hanspeide

@lan, як ти вирішив твою проблему, можеш поділитися своїми знаннями
ніда,

привіт у вас є рішення?
ask4solutions

Відповіді:


34

Я думаю, ми можемо використовувати 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();
    }

І не забудьте додати його дозвіл у файл Manifest.


будь ласка, куди ми повинні помістити цей код? в службі? у onStartCommand ()?
haythem souissi

56
не працюватиме з JellyBean і вище. Дозвіл READ_LOGS тепер зарезервований лише для системних програм.
Пробіг

5
Ви в цьому абсолютно впевнені? Оскільки Smart AppLock, здається, може це робити навіть на пристроях JB. Це тому, що програма піднімається до статусу Адміністратора пристрою? play.google.com/store/apps/…
Картік Балакрішнан

1
@ Torcellite, ця програма має дозвіл "Отримати запущені завдання", тому, можливо, вона використовує цю техніку.
Сем

1
@Ran, а що робити, щоб зараз його використовувати ... чи є зараз доступне рішення для вирішення проблеми, зазначеної у запитанні, оскільки мені потрібно бути вище, ніж квасоля ... будь ласка, дайте свій відгук якомога швидше ...
Шреян Мехта

19

Вигадливий спосіб це зробити - це служба із приуроченим циклом, яка перевіряє

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

Ви проглядаєте цей список, щоб подивитися, що працює на телефоні. Тепер ви можете ідентифікувати їх з ідентифікаторами та ProcessName, тому для стандартних дій це легко для користувацьких, якщо ви не зупините їх усіх, що важко розрізнити ...

Примітка: це не перелік того, що насправді є на екрані, просто перелік того, що працює ... начебто зводить нанівець вашу мету, але, принаймні, ви знатимете, коли щось починає працювати ... це буде продовжувати бути в цьому список навіть у фоновому режимі.

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


чи можна отримати час запуску / відновлення програми?
0LLiena

4
Натомість в Android L використовуйте android.app.usageпакет. developer.android.com/reference/android/app/usage/…
Plo_Koon

12

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

Що ви можете зробити, це замінити пускову установку . Якщо користувач погоджується на це.


1
Чому це не повинно бути можливим? Це мій пристрій, і я вирішую, що на ньому запускати. Як це більша проблема, ніж інші дозволи, які ми регулярно надаємо? Замінна програма запуску не зафіксує запуск усіх програм, лише тих, що запускаються безпосередньо нею. Є багато коментарів щодо цієї та подібних тем у SO, які стверджують, що можливість просто бачити, як проходять наміри, була б масовою проблемою, але ніхто не пояснює, в чому проблема, і чому її слід вважати такою неприємною, що існуюча система привілеїв не може використовувати, щоб дати зрозуміти користувачеві, що відбувається.
Kevin Whitefoot

У міру перспективних дозволів, це один дурний. Сенс створення моделі безпеки полягає в тому, щоб дозволити більшість законних випадків використання, одночасно запобігаючи більшості (в ідеалі всім) експлуатаціям. Потрібно захищати не тільки вас (мабуть, досвідченого користувача), але й наївних користувачів, які встановлюють програми, та авторів програм, яких не потрібно розглядати ще один вектор атаки. Вся безпека - це компроміси: у цьому випадку між корисністю та владою проти масової експлуатації. Ви можете клонувати стек Android і кодувати власну систему, якщо дійсно хочете для себе такий рівень свободи.
Pontus Gagge

12
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" />

Я використовую цей підхід, але це відкриє вашу "// показувати вашу активність тут, поверх PACKAGE_NAME.ACTIVITY_NAME" знову і знову через цикл. Будь-яке обхідне рішення для цього?
Anuj Sharma

зупинити ланцюжок CheckRunningActivity, коли ви отримаєте бажаний результат
Веачеслав Гайдарджі

Дякую за відповідь. Тоді як / коли цей потік буде перезапущено знову? Я використовую Sticky Service.
Anuj Sharma

залежить від контексту проблеми, детальніше опишіть, будь ласка, що ви хочете отримати.
Веачеслав Гайдарджі

2
У вашому коді тут Looper.loop()оператор виглядає так, ніколи його не буде виконано через те, що while(true)цикл не закінчується. Це помилка?
Сем

11

Основна проблема полягає в тому, що ви намагаєтеся прислухатися до неявних намірів, коли Launcher (головний екран) зазвичай використовує явні наміри.

Прихований намір - це коли ви хочете сказати "Хтось відтворить це відео", а Android вибирає додаток, який може впоратися з цим наміром.

Явний намір - це те, що відбувається, коли ви натискаєте піктограму "Електронна пошта" на головному екрані. Це конкретно вказує Android відкрити цю конкретну програму під повною назвою (тобто com.android.mail або щось інше).

AFAIK не може перехопити такі явні наміри. Це засіб безпеки, вбудований в Android, що жоден із двох видів діяльності не може мати однакову повну назву пакета. Це заважає третій стороні клонувати програму та видавати її за програму. Якщо те, що ви хочете зробити, було можливим, ви теоретично можете встановити програму, яка може заблокувати роботу всіх програм вашої конкуренції.

Те, що ви намагаєтесь зробити, суперечить моделі безпеки Android.

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


7

getRunningTasks() застаріло в Android L.

Щоб отримати статистику використання додатків, ви можете використовувати клас UsageStats із пакета android.app.usage .

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

Щоб використовувати цей API, спочатку потрібно заявити android.permission.PACKAGE_USAGE_STATSдозвіл у своєму маніфесті. Користувач також повинен дозволити доступ до цієї програми через Settings > Security > Apps with usage access.

Ось базовий приклад програми, який показує, як використовувати API статистики використання додатків, щоб дозволити користувачам збирати статистику, пов’язану з використанням програм.


як статистика використання може допомогти зрозуміти, яка програма стоїть на передньому плані?
Аджай

3

Можливо, вам потрібна послуга, яка буде працювати у фоновому режимі постійно. Тоді нехай ваша служба виконує те, що ви сказали. Слухайте android.intent.action.MAIN також із категорією android.intent.category.LAUNCHER. Потім нехай цей широкомовний приймач перевизначає метод onReceive і перевіряє ім’я програми тощо


2
Це звучить просто як метод, про який я думав, але я намагаюся отримати головну трансляцію (кат. LAUNCHER) з базовим BroadcastReceiver. Хтось встиг це зробити раніше? На цьому етапі я просто хочу виявити, що програма запущена або відновлена. Потім я можу порівняти ім'я пакета з рядком, що містить імена, які я шукаю.
Ян
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.