blob: f5448d32a542aad95a24a03b768904e96d84a715 [file] [log] [blame]
package com.google.android.car.kitchensink.notification;
import android.annotation.Nullable;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationCompat.Action;
import androidx.core.app.NotificationCompat.MessagingStyle;
import androidx.core.app.Person;
import androidx.core.app.RemoteInput;
import androidx.fragment.app.Fragment;
import com.google.android.car.kitchensink.KitchenSinkActivity;
import com.google.android.car.kitchensink.R;
import java.util.HashMap;
/**
* Test fragment that can send all sorts of notifications.
*/
public class NotificationFragment extends Fragment {
private static final String IMPORTANCE_HIGH_ID = "importance_high";
private static final String IMPORTANCE_HIGH_NO_SOUND_ID = "importance_high_no_sound";
private static final String IMPORTANCE_DEFAULT_ID = "importance_default";
private static final String IMPORTANCE_LOW_ID = "importance_low";
private static final String IMPORTANCE_MIN_ID = "importance_min";
private static final String IMPORTANCE_NONE_ID = "importance_none";
private int mCurrentNotificationId = 0;
private NotificationManager mManager;
private Context mContext;
private Handler mHandler = new Handler();
private HashMap<Integer, Runnable> mUpdateRunnables = new HashMap<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getActivity();
mManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mManager.createNotificationChannel(new NotificationChannel(
IMPORTANCE_HIGH_ID, "Importance High", NotificationManager.IMPORTANCE_HIGH));
NotificationChannel noSoundChannel = new NotificationChannel(
IMPORTANCE_HIGH_NO_SOUND_ID, "No sound", NotificationManager.IMPORTANCE_HIGH);
noSoundChannel.setSound(null, null);
mManager.createNotificationChannel(noSoundChannel);
mManager.createNotificationChannel(new NotificationChannel(
IMPORTANCE_DEFAULT_ID,
"Importance Default",
NotificationManager.IMPORTANCE_DEFAULT));
mManager.createNotificationChannel(new NotificationChannel(
IMPORTANCE_LOW_ID, "Importance Low", NotificationManager.IMPORTANCE_LOW));
mManager.createNotificationChannel(new NotificationChannel(
IMPORTANCE_MIN_ID, "Importance Min", NotificationManager.IMPORTANCE_MIN));
mManager.createNotificationChannel(new NotificationChannel(
IMPORTANCE_NONE_ID, "Importance None", NotificationManager.IMPORTANCE_NONE));
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.notification_fragment, container, false);
initCancelAllButton(view);
initCarCategoriesButton(view);
initImportanceHighBotton(view);
initImportanceDefaultButton(view);
initImportanceLowButton(view);
initImportanceMinButton(view);
initOngoingButton(view);
initMessagingStyleButton(view);
initProgressButton(view);
initNavigationButton(view);
return view;
}
private void initCancelAllButton(View view) {
view.findViewById(R.id.cancel_all_button).setOnClickListener(v -> {
for (Runnable runnable : mUpdateRunnables.values()) {
mHandler.removeCallbacks(runnable);
}
mUpdateRunnables.clear();
mManager.cancelAll();
});
}
private void initCarCategoriesButton(View view) {
view.findViewById(R.id.category_car_emergency_button).setOnClickListener(v -> {
Notification notification = new Notification
.Builder(mContext, IMPORTANCE_DEFAULT_ID)
.setContentTitle("Car Emergency")
.setContentText("Shows heads-up; Shows on top of the list; Does not group")
.setCategory(Notification.CATEGORY_CAR_EMERGENCY)
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(mCurrentNotificationId++, notification);
});
view.findViewById(R.id.category_car_warning_button).setOnClickListener(v -> {
Notification notification = new Notification
.Builder(mContext, IMPORTANCE_MIN_ID)
.setContentTitle("Car Warning")
.setContentText(
"Shows heads-up; Shows on top of the list but below Car Emergency; "
+ "Does not group")
.setCategory(Notification.CATEGORY_CAR_WARNING)
.setColor(mContext.getColor(android.R.color.holo_orange_dark))
.setColorized(true)
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(mCurrentNotificationId++, notification);
});
view.findViewById(R.id.category_car_info_button).setOnClickListener(v -> {
Notification notification = new Notification
.Builder(mContext, IMPORTANCE_DEFAULT_ID)
.setContentTitle("Car information")
.setContentText("Doesn't show heads-up; Importance Default; Groups")
.setCategory(Notification.CATEGORY_CAR_INFORMATION)
.setColor(mContext.getColor(android.R.color.holo_orange_light))
.setColorized(true)
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(mCurrentNotificationId++, notification);
});
}
private void initImportanceHighBotton(View view) {
Intent mIntent = new Intent(mContext, KitchenSinkActivity.class);
PendingIntent mPendingIntent = PendingIntent.getActivity(mContext, 0, mIntent, 0);
Notification notification1 = new Notification
.Builder(mContext, IMPORTANCE_HIGH_ID)
.setContentTitle("Importance High: Shows as a heads-up")
.setContentText(
"Each click generates a new notification. And some "
+ "looooooong text. "
+ "Loooooooooooooooooooooong. "
+ "Loooooooooooooooooooooooooooooooooooooooooooooooooong.")
.setSmallIcon(R.drawable.car_ic_mode)
.addAction(
new Notification.Action.Builder(
null, "Long Action (no-op)", mPendingIntent).build())
.addAction(
new Notification.Action.Builder(
null, "Action (no-op)", mPendingIntent).build())
.addAction(
new Notification.Action.Builder(
null, "Long Action (no-op)", mPendingIntent).build())
.setColor(mContext.getColor(android.R.color.holo_red_light))
.build();
view.findViewById(R.id.importance_high_button).setOnClickListener(
v -> mManager.notify(mCurrentNotificationId++, notification1)
);
}
private void initImportanceDefaultButton(View view) {
view.findViewById(R.id.importance_default_button).setOnClickListener(v -> {
Notification notification = new Notification
.Builder(mContext, IMPORTANCE_DEFAULT_ID)
.setContentTitle("No heads-up; Importance Default; Groups")
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(mCurrentNotificationId++, notification);
});
}
private void initImportanceLowButton(View view) {
view.findViewById(R.id.importance_low_button).setOnClickListener(v -> {
Notification notification = new Notification.Builder(mContext, IMPORTANCE_LOW_ID)
.setContentTitle("Importance Low")
.setContentText("No heads-up; Below Importance Default; Groups")
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(mCurrentNotificationId++, notification);
});
}
private void initImportanceMinButton(View view) {
view.findViewById(R.id.importance_min_button).setOnClickListener(v -> {
Notification notification = new Notification.Builder(mContext, IMPORTANCE_MIN_ID)
.setContentTitle("Importance Min")
.setContentText("No heads-up; Below Importance Low; Groups")
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(mCurrentNotificationId++, notification);
});
}
private void initOngoingButton(View view) {
view.findViewById(R.id.ongoing_button).setOnClickListener(v -> {
Notification notification = new Notification
.Builder(mContext, IMPORTANCE_DEFAULT_ID)
.setContentTitle("Persistent/Ongoing Notification")
.setContentText("Cannot be dismissed; No heads-up; Importance default; Groups")
.setSmallIcon(R.drawable.car_ic_mode)
.setOngoing(true)
.build();
mManager.notify(mCurrentNotificationId++, notification);
});
}
private void initMessagingStyleButton(View view) {
view.findViewById(R.id.category_message_button).setOnClickListener(v -> {
int id = mCurrentNotificationId++;
PendingIntent replyIntent = createServiceIntent(id, "reply");
PendingIntent markAsReadIntent = createServiceIntent(id, "read");
Person personJohn = new Person.Builder().setName("John Doe").build();
Person personJane = new Person.Builder().setName("Jane Roe").build();
MessagingStyle messagingStyle =
new MessagingStyle(personJohn)
.setConversationTitle("Heads-up: New Message")
.addMessage(
new MessagingStyle.Message(
"The meaning of life, or the answer to the question"
+ "What is the meaning of life?, pertains to "
+ "the significance of living or existence in"
+ " general. Many other related questions "
+ "include: Why are we here?, What is "
+ "life all about?, or What is the "
+ "purpose of existence?",
System.currentTimeMillis() - 3600,
personJohn))
.addMessage(
new MessagingStyle.Message(
"Importance High; Groups; Each click generates a new"
+ "notification. And some looooooong text. "
+ "Loooooooooooooooooooooong. "
+ "Loooooooooooooooooooooooooong."
+ "Long long long long text.",
System.currentTimeMillis(),
personJane));
NotificationCompat.Builder notification = new NotificationCompat
.Builder(mContext, IMPORTANCE_HIGH_ID)
.setContentTitle("Message from someone")
.setContentText("hi")
.setShowWhen(true)
.setCategory(Notification.CATEGORY_MESSAGE)
.setSmallIcon(R.drawable.car_ic_mode)
.setStyle(messagingStyle)
.setAutoCancel(true)
.setColor(mContext.getColor(android.R.color.holo_green_light))
.addAction(
new Action.Builder(R.drawable.ic_check_box, "read", markAsReadIntent)
.setSemanticAction(Action.SEMANTIC_ACTION_MARK_AS_READ)
.setShowsUserInterface(false)
.build())
.addAction(
new Action.Builder(R.drawable.ic_check_box, "reply", replyIntent)
.setSemanticAction(Action.SEMANTIC_ACTION_REPLY)
.setShowsUserInterface(false)
.addRemoteInput(new RemoteInput.Builder("input").build())
.build());
mManager.notify(id, notification.build());
});
}
private PendingIntent createServiceIntent(int notificationId, String action) {
Intent intent = new Intent(mContext, KitchenSinkActivity.class).setAction(action);
return PendingIntent.getForegroundService(mContext, notificationId, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
private void initProgressButton(View view) {
view.findViewById(R.id.progress_button).setOnClickListener(v -> {
int id = mCurrentNotificationId++;
Notification notification = new Notification
.Builder(mContext, IMPORTANCE_DEFAULT_ID)
.setContentTitle("Progress")
.setOngoing(true)
.setContentText(
"Doesn't show heads-up; Importance Default; Groups; Ongoing (cannot "
+ "be dismissed)")
.setProgress(100, 0, false)
.setColor(mContext.getColor(android.R.color.holo_purple))
.setContentInfo("0%")
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(id, notification);
Runnable runnable = new Runnable() {
int mProgress = 0;
@Override
public void run() {
Notification updateNotification = new Notification
.Builder(mContext, IMPORTANCE_DEFAULT_ID)
.setContentTitle("Progress")
.setContentText("Doesn't show heads-up; Importance Default; Groups")
.setProgress(100, mProgress, false)
.setOngoing(true)
.setColor(mContext.getColor(android.R.color.holo_purple))
.setContentInfo(mProgress + "%")
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(id, updateNotification);
mProgress += 5;
if (mProgress <= 100) {
mHandler.postDelayed(this, 1000);
}
}
};
mUpdateRunnables.put(id, runnable);
mHandler.post(runnable);
});
}
private void initNavigationButton(View view) {
view.findViewById(R.id.navigation_button).setOnClickListener(v -> {
int id = mCurrentNotificationId++;
Notification notification = new Notification
.Builder(mContext, IMPORTANCE_HIGH_ID)
.setCategory(Notification.CATEGORY_NAVIGATION)
.setContentTitle("Navigation")
.setContentText("Turn right in 900 ft")
.setColor(mContext.getColor(android.R.color.holo_green_dark))
.setColorized(true)
.setSubText("900 ft")
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(id, notification);
Runnable rightTurnRunnable = new Runnable() {
int mDistance = 800;
@Override
public void run() {
Notification updateNotification = new Notification
.Builder(mContext, IMPORTANCE_HIGH_NO_SOUND_ID)
.setCategory(Notification.CATEGORY_NAVIGATION)
.setContentTitle("Navigation")
.setContentText("Turn right in " + mDistance + " ft")
.setColor(mContext.getColor(android.R.color.holo_green_dark))
.setColorized(true)
.setSubText(mDistance + " ft")
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(id, updateNotification);
mDistance -= 100;
if (mDistance >= 0) {
mHandler.postDelayed(this, 1000);
}
}
};
Runnable exitRunnable = new Runnable() {
int mDistance = 9;
@Override
public void run() {
Notification updateNotification = new Notification
.Builder(mContext, IMPORTANCE_HIGH_NO_SOUND_ID)
.setCategory(Notification.CATEGORY_NAVIGATION)
.setContentTitle("Navigation")
.setContentText("Exit in " + mDistance + " miles")
.setColor(mContext.getColor(android.R.color.holo_green_dark))
.setColorized(true)
.setSubText(mDistance + " miles")
.setSmallIcon(R.drawable.car_ic_mode)
.build();
mManager.notify(id, updateNotification);
mDistance -= 1;
if (mDistance >= 0) {
mHandler.postDelayed(this, 1000);
}
}
};
mUpdateRunnables.put(id, rightTurnRunnable);
mUpdateRunnables.put(id, exitRunnable);
mHandler.postDelayed(rightTurnRunnable, 1000);
mHandler.postDelayed(exitRunnable, 10000);
});
}
}