Попытка создать быстрый ответ Whatsapps для телефонов с поддержкой до N

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

Я открываю операцию под названием NotificationActivity. В AndroidManifest.xml я зарегистрировал активность как

<activity
    android:name=".activity.NotificationActivity"
    android:theme="@style/Theme.AppCompat.Light.Dialog.custom"
    android:label="@string/title_activity_notification"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="adjustResize|stateHidden" />

Это стиль:

<style name="Theme.AppCompat.Light.Dialog.custom">
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
</style>

Теперь, когда приложение завершено закрыто (закрыто, а затем удалено), он работает отлично.

Однако, если приложение просто сведено к минимуму, когда кто-то нажимает кнопку ответа, он открывает приложение, а затем вставляет над ним NotificationActivity. Как запретить открывать приложение в фоновом режиме и открывать только активность уведомлений о половине экрана.

Большое спасибо

Изменить: Я думал, что, возможно, файл xml имеет значение?

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="300dp"
    android:layout_marginTop="15dp"
    android:background="@color/white"
    android:orientation="vertical"
    android:paddingTop="12dp"
    android:weightSum="20">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="vertical">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/lvChat"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="10"
            android:background="@android:color/transparent"
            android:cacheColorHint="@android:color/transparent"
            android:divider="@android:color/transparent"
            android:dividerHeight="0dp"
            android:listSelector="@android:color/transparent"
            android:scrollbars="none"
            android:stackFromBottom="false"
            android:transcriptMode="alwaysScroll"/>

        <LinearLayout
            android:id="@+id/chatFooter"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ECEFF1"
            android:orientation="horizontal">

            <LinearLayout
                android:id="@+id/sendLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:paddingBottom="@dimen/scale_5dp"
                android:paddingTop="@dimen/scale_5dp"
                android:weightSum="2">

                <LinearLayout
                    android:layout_width='0dp'
                    android:layout_height="wrap_content"
                    android:layout_weight="1.8">

                    <com.heyjude.heyjudeapp.customview.EditRobotoRegular
                        android:id="@+id/editChatMsg"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:background="@drawable/linear_back"
                        android:hint="Type your message..."
                        android:imeOptions="actionSend"
                        android:inputType="textMultiLine|textCapSentences|text"
                        android:padding="@dimen/scale_5dp"
                        android:textColor="#5f6060"
                        android:textColorHint="#5f6060"
                        android:textSize="@dimen/text_14"/>
                </LinearLayout>

                <ImageButton
                    android:id="@+id/ivSend"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="0.3"
                    android:background="@android:color/transparent"
                    android:src="@drawable/ic_chat_icon"/>

            </LinearLayout>

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:background="@color/grey_list"
            android:gravity="center"
            android:orientation="horizontal"
            android:weightSum="2">

            <Button
                android:id="@+id/buttonView"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="View"
                android:textAllCaps="false"
                android:textSize="@dimen/text_22"/>

            <Button
                android:id="@+id/buttonCancel"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="Cancel"
                android:textAllCaps="false"
                android:textSize="@dimen/text_22"/>

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

Также не уверен, что это актуально, но вот как я создаю ответ

String KEY_TEXT_REPLY = "key_text_reply";
String replyLabel = "Type here";
Intent intent = new Intent(context, NotificationActivity.class);
intent.putExtra(Constants.REQUEST_ID, messageData.taskid);
intent.putExtra(Constants.JUDE_ID, messageData.from);
intent.putExtra(Constants.FROM, Constants.NOTIFICATION);

PendingIntent pendingIntent = PendingIntent.getActivity(
                context,
                0,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT);

RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
        .setLabel(replyLabel)
        .build();

NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder(
                R.drawable.send_button,
                "Reply", pendingIntent)
                .addRemoteInput(remoteInput)
                .build();

builder.addAction(replyAction);

Ответ 1

Для достижения желаемого вам нужно использовать атрибут android:launchMode со значением singleInstance:

То же, что и "singleTask", за исключением того, что система не запускает никаких других действия в задание, содержащее экземпляр. Активность всегда единственный и единственный член своей задачи.

Вы также должны добавить android:excludeFromRecents="true", чтобы исключить свою активность из списка недавно использованных приложений, как описано в документации:

Следует ли исключать задачу, инициированную этим действием из списка недавно использованных приложений - обзорный экран. Что когда эта деятельность является корневой деятельностью новой задачи, это атрибут определяет, должна ли задача не отображаться в списке последние приложения. Установите "true", если задача должна быть исключена из списка; установите "false", если он должен быть включен. Значение по умолчанию - "false".

Подводя итог, вы должны изменить свой AndroidManifest.xml следующим образом:

<activity
    android:name=".activity.NotificationActivity"
    android:theme="@style/Theme.AppCompat.Light.Dialog.custom"
    android:label="@string/title_activity_notification"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="adjustResize|stateHidden"
    android:launchMode="singleInstance"
    android:excludeFromRecents="true" />

Ответ 2

Чтобы начать специальную деятельность из уведомления, как описано здесь,

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

Специальная активность не нуждается в обратном стеке, поэтому вам не нужно определять свою иерархию Activity в манифесте, и вам не нужно вызывать addParentStack() для создания обратного стека. Вместо этого используйте манифест для настройки параметров задачи Activity и создайте PendingIntent, вызвав getActivity():

  • В своем манифеста добавьте следующие атрибуты в

    для операции

    android:name="activityclass" 
    

    Полностью квалифицированное имя операции.

    android:taskAffinity=""
    

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

    android:excludeFromRecents="true"
    

    Исключает новую задачу из Recents, так что пользователь не может случайно вернуться к ней.

Фрагмент кода

<activity
    android:name=".YourActivity"
    android:theme="@style/Theme.AppCompat.Light.Dialog.custom"
...
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>
  1. Создайте и опубликуйте уведомление. (Хотя вы делаете это уже, я предлагаю просто проверить его):

    • Создайте намерение, которое запускает действие.

    • Задайте действие для запуска в новой пустой задаче, вызвав setFlags() с флагами FLAG_ACTIVITY_NEW_TASK и FLAG_ACTIVITY_CLEAR_TASK.

    • Задайте любые другие параметры, необходимые для намерения.

    • Создайте PendingIntent из намерения, вызвав getActivity(). Затем вы можете использовать этот PendingIntent в качестве аргумента для setContentIntent().

фрагмент кода.

// Instantiate a Builder object.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Creates an Intent for the Activity
Intent notifyIntent =
        new Intent(this, ResultActivity.class);
// Sets the Activity to start in a new, empty task
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Creates the PendingIntent
PendingIntent notifyPendingIntent =
        PendingIntent.getActivity(
        this,
        0,
        notifyIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
);

// Puts the PendingIntent into the notification builder
builder.setContentIntent(notifyPendingIntent);
// Notifications are issued by sending them to the
// NotificationManager system service.
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Builds an anonymous Notification object from the builder, and
// passes it to the NotificationManager
mNotificationManager.notify(id, builder.build());

Также проверьте официальную документацию, если это необходимо.

Надеюсь, это поможет вам.