Как закрыть пункт меню приложения/действия или кода с помощью намерения/ожидания намерения в пользовательских вкладках Chrome

Я пытаюсь понять, как работают пользовательские вкладки Chrome. Следуя рекомендациям, добавление пользовательского элемента в меню выполняется с помощью pendingIntent, например:

Intent intent =  new Intent(Intent.ACTION_VIEW, Uri.parse("http://google.com"));
PendingIntent pendingIntent =  PendingIntent
        .getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
customTabsIntent = new CustomTabsIntent.Builder()
        .addMenuItem("Visit Google Website", pendingIntent)
        .build();

Я знаю, как использовать pendingIntent для перехода на веб-сайт или для создания действия «поделиться». Вопрос в том, можно ли выполнять более сложные задачи, добавляя пункт меню «Закрыть», чтобы закрыть действие или выйти из приложения; или «подключить» этот пункт меню к методу, поэтому, когда пользователь нажимает на него, код из метода будет обрабатываться. Я предполагаю, что второе, если возможно, будет простым решением для первого.

Я пытался найти ответы, но если я ищу, как закрыть или завершить действие или приложение (или подобное), используя намерение или pendingIntent, я получаю что-то с использованием 'finish();' или 'startActivity(намерение);' или аналогичный, который я не могу применить здесь, так как не знаю, как и откуда его вызвать. Я пытался просто прочитать об использовании намерения и pendingIntent, но я не могу понять, как, скажем, закрыть действие или процесс, не имея возможности вызвать метод.

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


person Vlad    schedule 09.05.2016    source источник
comment
Не могли бы лучше объяснить поведение, которого вы пытаетесь достичь? Кажется, вы хотите иметь кнопку в CCT, которая приведет к завершению действия, вызывающего пользовательские вкладки, верно?   -  person andreban    schedule 09.05.2016
comment
@andreban: если на устройстве нет Chrome, приложение откроет ссылку в браузере пользователя по умолчанию. В этом случае, если вы откроете «диспетчер задач», чтобы увидеть «запущенные приложения» на устройстве, вы увидите как приложение, так и пользовательский браузер. Если Chrome версии 45 или выше установлен на устройстве и выбран в качестве браузера по умолчанию, откроется CCT, и если вы откроете «диспетчер задач», чтобы увидеть «запущенные приложения», вы увидите только работающее приложение (например, CCT открывается внутри - Браузер Chrome не запускается).   -  person Vlad    schedule 10.05.2016
comment
@andreban: Итак, да, я пытаюсь добавить, ну, не обязательно кнопку, а настраиваемый пункт меню в меню CCT, чтобы закрыть «все это», с предположением, что когда я закрываю приложение, CCT также закрывается . Хотя я думаю, что было бы то же самое, если бы вы хотели сделать это с помощью кнопки пользовательского действия, поскольку, насколько мне известно, оба управляются намерением/pendIntent, как описано в моем примере выше.   -  person Vlad    schedule 10.05.2016
comment
Итак, вы хотите добавить пункт меню, который выходит из приложения? (например: закрывает пользовательскую вкладку и действие вызывающего абонента). Если это так, у Android на самом деле нет концепции выхода из приложения. Я бы рекомендовал прочитать документацию по жизненному циклу активности: developer.android.com/reference/ android/app/Activity.html. Что касается пользовательской вкладки, невозможно закрыть пользовательскую вкладку из BroadcastReceiver, как это обычно невозможно сделать с другими действиями. Вы можете использовать finish() для вызывающей активности, когда она перезапускается после закрытия пользовательских вкладок.   -  person andreban    schedule 10.05.2016
comment
@andreban: позволю себе не согласиться; см. мое решение с использованием BroadcastReceiver.   -  person Vlad    schedule 11.05.2016


Ответы (1)


Это решение использует BrodcastReceiver:

В своем действии (в данном случае MainActivity), из которого вы запускаете настраиваемые вкладки Chrome (CCT), создайте статическое поле, чтобы определить, было ли действие создано из Broadcastreceiver, и сеттер, чтобы мы могли установить его из Broadcastreceiver:

    // For determining if Activity was started from BroadcastReceiver
    private static boolean fromBroadcastReceiver = false;

    public static void setFromBroadcastReceiver(boolean bool) {
        fromBroadcastReceiver = bool;
    }

Создайте открытый класс для BroadcastReceiver. Переопределив метод onReceive, создайте экземпляр MainActivity и установите для fromBroadcastReceiver значение true. Затем создайте намерение с этим действием и другое намерение для перезапуска с использованием первого намерения. Закройте CCT и перезапустите активность, используя последнее намерение:

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.IntentCompat;

public class CctBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        // Create an instance of MainActivity and set fromBroadcastReceiver flag to true.
        MainActivity mainActivity = new MainActivity();
        mainActivity.setFromBroadcastReceiver(true);

        // Create an intent with that activity and another intent for restarting using first intent.
        Intent intent = new Intent(context, mainActivity.getClass());
        ComponentName compName = intent.getComponent();
        Intent mainIntent = IntentCompat.makeRestartActivityTask(compName);

        // Restart the activity using later intent (also close CCT)
        mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        mainIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        context.startActivity(mainIntent);

    } // End onReceive.

} // End BroadcastReceiver class.

Не забудьте зарегистрировать ресивер в AndroidManifest.xml:

...
        </activity>

    <receiver
        android:name=".cctBroadcastReceiver"
        android:enabled="true">
    </receiver>

</application>

Теперь внутри onCreate MainActivity проверьте, было ли оно создано из BroadcastReceiver, и если это так, сбросьте «флаг» и finish() действие:

        // Check if activity was created from the BroadcastReceiver, and if so reset the 'flag' and finish() the activity.
        if (fromBroadcastReceiver) {
            setFromBroadcastReceiver(false);
            finish();
            return;
        }

Не забудьте использовать класс BroadcastReceiver для создания намерений и pendingIntent для CCT:

     Intent broadcastIntent =  new Intent(this, CctBroadcastReceiver.class);
     PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);

И вы сделали. По сути, код внутри BroadcastReceiver закрывает CCT (аналогично тому, как если бы вы нажали кнопку закрытия CCT по умолчанию). Добавление «флага» и кода внутри MainActivity дополнительно закрывает MainActivity.

person Vlad    schedule 10.05.2016
comment
Что такое browserActivity? - person Bob Snyder; 11.05.2016
comment
@qbix: извините, это должно быть mainActivity. Я изменил это. Спасибо. - person Vlad; 11.05.2016