Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to create Whatsapps quick reply for pre N phones

I am trying to create a small window to open if you click on the quick reply button on a notification. In WhatsApp it opens up a half screen window. Currently I am doing the following:

I open up an activity called NotificationActivity. In AndroidManifest.xml I registered the activity as a

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

This is the style:

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

Now when the app is complete closed (closed and then swiped away) it works perfectly.

However if the app is just minimized, when someone clicks on the reply button it opens up the app and then pastes the NotificationActivity over it. How do I prevent the app from being opened in the background and only have the half screen notification activity opened.

Thanks so much

Edit: I was thinking that maybe the xml file was relevant?

<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>

Also not sure if this is relevant but here is how I create the reply

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);
like image 910
Adam Katz Avatar asked Sep 06 '16 08:09

Adam Katz


2 Answers

To achieve what you want you need use the attribute android:launchMode with the value singleInstance:

Same as "singleTask", except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task.

You should also add android:excludeFromRecents="true" to exclude your activity from the list of recently used applications as explained by the documentation:

Whether or not the task initiated by this activity should be excluded from the list of recently used applications, the overview screen. That is, when this activity is the root activity of a new task, this attribute determines whether the task should not appear in the list of recent apps. Set "true" if the task should be excluded from the list; set "false" if it should be included. The default value is "false".

To summarize you need to change your AndroidManifest.xml like this:

<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" />
like image 97
Mattia Maestrini Avatar answered Nov 17 '22 00:11

Mattia Maestrini


To start a special activity from notification as described here,

For this situation, set up the PendingIntent to start in a fresh task. There's no need to create a back stack, though, because the started Activity isn't part of the application's activity flow. Clicking Back will still take the user to the Home screen.

A special Activity doesn't need a back stack, so you don't have to define its Activity hierarchy in the manifest, and you don't have to call addParentStack() to build a back stack. Instead, use the manifest to set up the Activity task options, and create the PendingIntent by calling getActivity():

  1. In your manifest, add the following attributes to the

    element for the Activity

    android:name="activityclass" 
    

    The activity's fully-qualified class name.

    android:taskAffinity=""
    

    Combined with the FLAG_ACTIVITY_NEW_TASK flag that you set in code, this ensures that this Activity doesn't go into the application's default task. Any existing tasks that have the application's default affinity are not affected.

    android:excludeFromRecents="true"
    

    Excludes the new task from Recents, so that the user can't accidentally navigate back to it.

Code snippet

<activity
    android:name=".YourActivity"
    android:theme="@style/Theme.AppCompat.Light.Dialog.custom"
...
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>
  1. Build and issue the notification.(Though you are doing this already I suggest just check it):

    • Create an Intent that starts the Activity.

    • Set the Activity to start in a new, empty task by calling setFlags() with the flags FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_CLEAR_TASK.

    • Set any other options you need for the Intent.

    • Create a PendingIntent from the Intent by calling getActivity(). You can then use this PendingIntent as the argument to setContentIntent().

Code snippet.

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

Also check this official documentation if required.

Hope this will help you.

like image 27
Pravin Divraniya Avatar answered Nov 16 '22 23:11

Pravin Divraniya