Перенесите задание на фронт на android.intent.action.USER_PRESENT - PullRequest
3 голосов
/ 06 января 2012

ФОН
У меня есть задача (то есть приложение) с несколькими действиями.

ВОПРОС
Как вывести задачу на передний план без переупорядочения стека активности для этой задачи?

СЦЕНАРИЙ ПОЛЬЗОВАТЕЛЯ
Когда устройство загружается (т.е. после получения широковещательной рассылки android.intent.action.BOOT_COMPLETED), мое приложение запускается, вызывает эту задачу 1 и отображает действие A (код ниже). Когда пользователь взаимодействует с задачей 1, он / она открывает операцию B в стеке (операция B теперь отображается на экране). Затем пользователь нажимает клавишу «Домой» и открывает другую задачу, называет ее задачей 2, затем блокирует экран. Пользователь разблокирует экран, и намерение android.intent.action.USER_PRESENT передается и принимается моим приложением (см. Фрагмент кода ниже). My выполняет вызов startActivity () в моем классе IntentReceiver, как и ожидалось, но вместо того, чтобы просто вывести задачу на передний план, она создает новую задачу, вызывая ее как задачу 3.

ИЗМЕНЕНИЯ, КОТОРЫЕ Я ПРОБОВАЛ
Если я изменяю или изменяю Intent.FLAG_ACTIVITY_NEW_TASK на любое другое намерение, я получаю это сообщение об ошибке:

Для вызова startActivity () вне контекста Activity требуется флаг FLAG_ACTIVITY_NEW_TASK. Вы действительно этого хотите?

... похоже, мне нужно использовать Intent.FLAG_ACTIVITY_NEW_TASK.

Если я изменю lauchMode основного действия на «singleTask», правильная задача будет выведена на передний план (т. Е. Новая задача не создана), но стек действий будет переупорядочен так, чтобы активность_А находилась на вершине стека.

На данный момент я в растерянности относительно того, как вывести существующую задачу на передний план без переупорядочения стека активности при прослушивании намерения android.intent.action.USER_PRESENT, любая помощь будет принята с благодарностью.

Кстати, это приложение доставляется группе сотрудников, а не широкой публике, на принадлежащих компании устройствах Android.

КОДОВЫЕ ОШИБКИ
Чтобы запустить приложение, я настроил приемник вещания в моем файле манифеста.

<application
       :
    <activity
        android:label="@string/app_name"
        android:launchMode="singleTop"
        android:name=".activities.activity_A" >
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.HOME" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
       :
    <receiver
        android:enabled="true"
        android:name=".utilities.IntentReceiver"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
        <intent-filter >
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.USER_PRESENT" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

В моем классе IntentReceiver я начинаю свою основную деятельность ...

public class IntentReceiver extends BroadcastReceiver {

@Override

    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent(context, activity_A.class);  
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);  
    }
}

Ответы [ 2 ]

5 голосов
/ 06 января 2012

Вот немного хакерская реализация, которая работает для меня:

  • Создайте простое действие BringToFront, которое просто finish() само по себе onCreate():

    public class BringToFront extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            finish();
        }
    
    }
    
  • В вашем BroadcastReceiver запустите выше действие BringToFront вместо вашего action_A, если действие USER_PRESENT:

    @Override
    public void onReceive(Context context, Intent intent) {
        Class<? extends Activity> activityClass = activity_A.class;
    
        if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
            activityClass = BringToFront.class;
        }
    
        Intent i = new Intent(context, activityClass);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }
    

Это работает, потому что действие BringToFront имеет то же самоеtaskAffinity в качестве вашей активности_A и ее запуска система выведет существующую задачу на передний план.Затем действие BringToFront немедленно завершается, в результате чего последнее действие вашей задачи (activity_B в вашем сценарии) выходит на передний план.

Стоит отметить, что на уровне API 11 (Honeycomb) добавлен метод moveTaskToFront() всистемный ActivityManager сервис, который, вероятно, может быть лучшим способом достижения того, что вы хотите.

0 голосов
/ 09 января 2012

Хорошо, я смог заставить это работать, добавив статическую глобальную переменную в мою основную деятельность (activity_A). В onCreate я устанавливаю isRunning = true, а onDestory = false. Затем в своем классе IntentReceiver я проверяю isRunning, чтобы определить, какое действие нужно запустить:

            :
    if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
        if (GlobalVariables.isRunning) {
            activityClass = BringToFront.class;
        } else {
            activityClass = activity_A.class;
        }
    } else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
        activityClass = activity_A.class;
    }
            :
...