@ü.li:Listing 1:MultiWindowDemoActivity.java @li:package com.thomaskuenneth.multiwindowdemo; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; public class MultiWindowDemoActivity extends Activity { private static final String TAG = MultiWindowDemoActivity.class.getSimpleName(); private final StringBuilder sb = new StringBuilder(); private TextView tv; private ProgressBar pb; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tv = (TextView) findViewById(R.id.tv); pb = (ProgressBar) findViewById(R.id.pb); Button bt = (Button) findViewById(R.id.launch); bt.setOnClickListener(e -> { Intent i = new Intent(this, ChildActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(i); }); } @Override protected void onStop() { super.onStop(); pb.setVisibility(View.INVISIBLE); Log.d(TAG, "onStop()"); } @Override protected void onStart() { super.onStart(); updateTextView(); pb.setVisibility(View.VISIBLE); Log.d(TAG, "onStart()"); } @Override public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) { Log.d(TAG, "onPictureInPictureModeChanged(): " + isInPictureInPictureMode); } @Override public void onMultiWindowModeChanged(boolean isInMultiWindowMode) { Log.d(TAG, "onMultiWindowModeChanged(): " + isInMultiWindowMode); } private void updateTextView() { sb.setLength(0); sb.append("isInMultiWindowMode(): ") .append(isInMultiWindowMode()) .append("\n"); sb.append("isInPictureInPictureMode(): ") .append(isInPictureInPictureMode()) .append("\n"); tv.setText(sb.toString()); } } @ü.li:Listing 2: BundledNotificationDemoActivity.java @li:package com.thomaskuenneth.bundlednotificationdemo; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.RemoteInput; import android.content.Intent; import android.graphics.drawable.Icon; import android.os.Bundle; import android.service.notification.StatusBarNotification; import android.widget.Button; import android.widget.CheckBox; import android.widget.TextView; import android.widget.Toast; import java.util.Random; import java.util.StringJoiner; public class BundledNotificationDemoActivity extends Activity { private static final Random RANDOM = new Random(); private static final String[] WORDS = {"lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipisici", "elit"}; private static final String TAG = BundledNotificationDemoActivity. class.getSimpleName(); private static final String KEY_TEXT_REPLY = "key_text_reply"; private static final String KEY_ID = "key_id"; private static final int N_SUMMARY = 1; private NotificationManager nm; private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Notification.Builder summary = createBaseNotification(R.drawable.ic_launcher, getString(R.string.summary)); summary.setGroup(TAG); summary.setGroupSummary(true); summary.setOngoing(true); nm.notify(N_SUMMARY, summary.build()); setContentView(R.layout.main); CheckBox cb = (CheckBox) findViewById(R.id.grouped); Button b1 = (Button) findViewById(R.id.new_notification); b1.setOnClickListener(e -> { Notification.Builder b = createBaseNotification(R.drawable.ic_announcement, getString(R.string.subject)); b.setStyle(new Notification.BigTextStyle() .bigText(createPhrase(80))); if (cb.isChecked()) { b.setGroup(TAG); } String reply = getString(R.string.reply); RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY) .setLabel(reply) .build(); Intent i = new Intent(this, BundledNotificationDemoActivity.class); int id = 1 + RANDOM.nextInt(Integer.MAX_VALUE); i.putExtra(KEY_ID, id); Notification.Action action = new Notification.Action.Builder( Icon.createWithResource(this, R.drawable.ic_announcement), reply, PendingIntent.getActivity(this, id, i, PendingIntent.FLAG_UPDATE_CURRENT)) .addRemoteInput(remoteInput) .build(); b.addAction(action); nm.notify(id, b.build()); }); tv = (TextView) findViewById(R.id.message); boolean notificationsEnabled = nm.areNotificationsEnabled(); if (!notificationsEnabled) { Toast.makeText(this, R.string.no_notifications, Toast.LENGTH_LONG).show(); } b1.setEnabled(notificationsEnabled); } @Override protected void onStart() { super.onStart(); Intent i = getIntent(); if (i != null) { Bundle remoteInput = RemoteInput.getResultsFromIntent(i); if (remoteInput != null) { CharSequence cs = remoteInput.getCharSequence(KEY_TEXT_REPLY); tv.setText(cs); int id = i.getIntExtra(KEY_ID, -1); for (StatusBarNotification n : nm.getActiveNotifications()) { if ((getPackageName().equals(n.getPackageName())) && (n.getId() == id)) { Notification.Builder b = Notification.Builder.recoverBuilder(this, n.getNotification()); b.setContentTitle(cs); nm.notify(id, b.build()); break; } } } } } private Notification.Builder createBaseNotification(int icon, String text) { return new Notification.Builder(this) .setContentTitle(getString(R.string.title)) .setContentText(text) .setSmallIcon(icon); } private static String createPhrase(int numWords) { StringJoiner sj = new StringJoiner(" "); for (int i = 0; i < numWords; i++) { sj.add(WORDS[RANDOM.nextInt(WORDS.length)]); } return sj.toString(); } }