Skip to content

Commit

Permalink
Change the layout of stopwatch and timer notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackyHawky committed Apr 20, 2024
1 parent dccec59 commit 9029fb9
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Build;
import android.os.SystemClock;
import android.widget.RemoteViews;
Expand Down Expand Up @@ -62,11 +61,10 @@ public Notification build(Context context, NotificationModel nm, Stopwatch stopw

// Compute some values required below.
final boolean running = stopwatch.isRunning();
final String pname = context.getPackageName();
final Resources res = context.getResources();
final long base = SystemClock.elapsedRealtime() - stopwatch.getTotalTime();

final RemoteViews content = new RemoteViews(pname, R.layout.chronometer_notif_content);
final RemoteViews content = new RemoteViews(context.getPackageName(), R.layout.chronometer_notif_content);
content.setTextViewText(R.id.title, context.getString(R.string.stopwatch_channel));
content.setChronometer(R.id.chronometer, base, null, running);

final List<Action> actions = new ArrayList<>(2);
Expand All @@ -78,7 +76,7 @@ public Notification build(Context context, NotificationModel nm, Stopwatch stopw
.putExtra(Events.EXTRA_EVENT_LABEL, eventLabel);

@DrawableRes final int icon1 = R.drawable.ic_fab_pause;
final CharSequence title1 = res.getText(R.string.sw_pause_button);
final CharSequence title1 = context.getText(R.string.sw_pause_button);
final PendingIntent intent1 = Utils.pendingServiceIntent(context, pause);
actions.add(new Action.Builder(icon1, title1, intent1).build());

Expand All @@ -89,7 +87,7 @@ public Notification build(Context context, NotificationModel nm, Stopwatch stopw
.putExtra(Events.EXTRA_EVENT_LABEL, eventLabel);

@DrawableRes final int icon2 = R.drawable.ic_sw_lap;
final CharSequence title2 = res.getText(R.string.sw_lap_button);
final CharSequence title2 = context.getText(R.string.sw_lap_button);
final PendingIntent intent2 = Utils.pendingServiceIntent(context, lap);
actions.add(new Action.Builder(icon2, title2, intent2).build());
}
Expand All @@ -98,7 +96,7 @@ public Notification build(Context context, NotificationModel nm, Stopwatch stopw
final int lapCount = DataModel.getDataModel().getLaps().size();
if (lapCount > 0) {
final int lapNumber = lapCount + 1;
final String lap = res.getString(R.string.sw_notification_lap_number, lapNumber);
final String lap = context.getString(R.string.sw_notification_lap_number, lapNumber);
content.setTextViewText(R.id.state, lap);
content.setViewVisibility(R.id.state, VISIBLE);
} else {
Expand All @@ -111,7 +109,7 @@ public Notification build(Context context, NotificationModel nm, Stopwatch stopw
.putExtra(Events.EXTRA_EVENT_LABEL, eventLabel);

@DrawableRes final int icon1 = R.drawable.ic_fab_play;
final CharSequence title1 = res.getText(R.string.sw_start_button);
final CharSequence title1 = context.getText(R.string.sw_start_button);
final PendingIntent intent1 = Utils.pendingServiceIntent(context, start);
actions.add(new Action.Builder(icon1, title1, intent1).build());

Expand All @@ -121,17 +119,16 @@ public Notification build(Context context, NotificationModel nm, Stopwatch stopw
.putExtra(Events.EXTRA_EVENT_LABEL, eventLabel);

@DrawableRes final int icon2 = R.drawable.ic_reset;
final CharSequence title2 = res.getText(R.string.sw_reset_button);
final CharSequence title2 = context.getText(R.string.sw_reset_button);
final PendingIntent intent2 = Utils.pendingServiceIntent(context, reset);
actions.add(new Action.Builder(icon2, title2, intent2).build());

// Indicate the stopwatch is paused.
content.setTextViewText(R.id.state, res.getString(R.string.swn_paused));
content.setTextViewText(R.id.state, context.getString(R.string.swn_paused));
content.setViewVisibility(R.id.state, VISIBLE);
}

final Builder notification = new Builder(
context, STOPWATCH_NOTIFICATION_CHANNEL_ID)
final Builder notification = new Builder(context, STOPWATCH_NOTIFICATION_CHANNEL_ID)
.setLocalOnly(true)
.setOngoing(running)
.setCustomContentView(content)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.best.deskclock.data;

import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
Expand All @@ -23,7 +22,6 @@
import static com.best.deskclock.NotificationUtils.FIRING_NOTIFICATION_CHANNEL_ID;
import static com.best.deskclock.NotificationUtils.TIMER_MODEL_NOTIFICATION_CHANNEL_ID;

import android.annotation.TargetApi;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.PendingIntent;
Expand Down Expand Up @@ -77,30 +75,30 @@ public Notification build(Context context, NotificationModel nm, List<Timer> une

// Compute some values required below.
final boolean running = timer.isRunning();
final Resources res = context.getResources();

final long base = getChronometerBase(timer);
final String pname = context.getPackageName();

final List<Action> actions = new ArrayList<>(2);

final CharSequence titleText;

final CharSequence stateText;
if (count == 1) {
if (running) {
// Single timer is running.
if (TextUtils.isEmpty(timer.getLabel())) {
stateText = res.getString(R.string.timer_notification_label);
} else {
stateText = timer.getLabel();
}
if (TextUtils.isEmpty(timer.getLabel())) {
titleText = context.getString(R.string.timer_notification_label);
} else {
titleText = timer.getLabel();
}

if (running) {
stateText = null;
// Left button: Pause
final Intent pause = new Intent(context, TimerService.class)
.setAction(TimerService.ACTION_PAUSE_TIMER)
.putExtra(TimerService.EXTRA_TIMER_ID, timer.getId());

@DrawableRes final int icon1 = R.drawable.ic_fab_pause;
final CharSequence title1 = res.getText(R.string.timer_pause);
final CharSequence title1 = context.getText(R.string.timer_pause);
final PendingIntent intent1 = Utils.pendingServiceIntent(context, pause);
actions.add(new Action.Builder(icon1, title1, intent1).build());

Expand All @@ -110,21 +108,21 @@ public Notification build(Context context, NotificationModel nm, List<Timer> une
.putExtra(TimerService.EXTRA_TIMER_ID, timer.getId());

@DrawableRes final int icon2 = R.drawable.ic_add;
final CharSequence title2 = res.getText(R.string.timer_plus_1_min);
final CharSequence title2 = context.getText(R.string.timer_plus_1_min);
final PendingIntent intent2 = Utils.pendingServiceIntent(context, addMinute);
actions.add(new Action.Builder(icon2, title2, intent2).build());

} else {
// Single timer is paused.
stateText = res.getString(R.string.timer_paused);
stateText = context.getString(R.string.timer_paused);

// Left button: Start
final Intent start = new Intent(context, TimerService.class)
.setAction(TimerService.ACTION_START_TIMER)
.putExtra(TimerService.EXTRA_TIMER_ID, timer.getId());

@DrawableRes final int icon1 = R.drawable.ic_fab_play;
final CharSequence title1 = res.getText(R.string.sw_resume_button);
final CharSequence title1 = context.getText(R.string.sw_resume_button);
final PendingIntent intent1 = Utils.pendingServiceIntent(context, start);
actions.add(new Action.Builder(icon1, title1, intent1).build());

Expand All @@ -134,23 +132,25 @@ public Notification build(Context context, NotificationModel nm, List<Timer> une
.putExtra(TimerService.EXTRA_TIMER_ID, timer.getId());

@DrawableRes final int icon2 = R.drawable.ic_reset;
final CharSequence title2 = res.getText(R.string.sw_reset_button);
final CharSequence title2 = context.getText(R.string.sw_reset_button);
final PendingIntent intent2 = Utils.pendingServiceIntent(context, reset);
actions.add(new Action.Builder(icon2, title2, intent2).build());
}
} else {
if (running) {
// At least one timer is running.
stateText = res.getString(R.string.timers_in_use, count);
titleText = context.getString(R.string.timers_in_use, count);
} else {
// All timers are paused.
stateText = res.getString(R.string.timers_stopped, count);
titleText = context.getString(R.string.timers_stopped, count);
}

stateText = null;

final Intent reset = TimerService.createResetUnexpiredTimersIntent(context);

@DrawableRes final int icon1 = R.drawable.ic_reset;
final CharSequence title1 = res.getText(R.string.timer_reset_all);
final CharSequence title1 = context.getText(R.string.timer_reset_all);
final PendingIntent intent1 = Utils.pendingServiceIntent(context, reset);
actions.add(new Action.Builder(icon1, title1, intent1).build());
}
Expand All @@ -163,8 +163,7 @@ public Notification build(Context context, NotificationModel nm, List<Timer> une

final PendingIntent pendingShowApp = Utils.pendingActivityIntent(context, showApp);

final Builder notification = new Builder(
context, TIMER_MODEL_NOTIFICATION_CHANNEL_ID)
final Builder notification = new Builder(context, TIMER_MODEL_NOTIFICATION_CHANNEL_ID)
.setOngoing(true)
.setLocalOnly(true)
.setShowWhen(false)
Expand All @@ -183,7 +182,7 @@ public Notification build(Context context, NotificationModel nm, List<Timer> une
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
notification.setCustomContentView(buildChronometer(pname, base, running, stateText))
notification.setCustomContentView(buildChronometer(context.getPackageName(), base, running, titleText, stateText))
.setGroup(nm.getTimerNotificationGroupKey());
} else {
final CharSequence contentTextPreN;
Expand All @@ -198,7 +197,7 @@ public Notification build(Context context, NotificationModel nm, List<Timer> une
contentTextPreN = context.getString(R.string.all_timers_stopped_notif);
}

notification.setContentTitle(stateText).setContentText(contentTextPreN);
notification.setContentTitle(titleText).setContentText(contentTextPreN);

final AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
final Intent updateNotification = TimerService.createUpdateNotificationIntent(context);
Expand Down Expand Up @@ -237,17 +236,21 @@ Notification buildHeadsUp(Context context, List<Timer> expired) {
final PendingIntent intent1 = Utils.pendingServiceIntent(context, reset);

// Generate some descriptive text, a title, and an action name based on the timer count.
final CharSequence titleText;
final String label = timer.getLabel();

final CharSequence stateText;
final int count = expired.size();
final List<Action> actions = new ArrayList<>(2);
if (count == 1) {
final String label = timer.getLabel();
if (TextUtils.isEmpty(label)) {
stateText = context.getString(R.string.timer_times_up);
titleText = context.getString(R.string.timer_notification_label);
} else {
stateText = label;
titleText = label;
}

stateText = context.getString(R.string.timer_times_up);

// Left button: Reset single timer
final CharSequence title1 = context.getString(R.string.timer_stop);
actions.add(new Action.Builder(icon1, title1, intent1).build());
Expand All @@ -259,7 +262,8 @@ Notification buildHeadsUp(Context context, List<Timer> expired) {
final CharSequence title2 = context.getString(R.string.timer_plus_1_min);
actions.add(new Action.Builder(icon2, title2, intent2).build());
} else {
stateText = context.getString(R.string.timer_multi_times_up, count);
titleText = context.getString(R.string.timer_multi_times_up, count);
stateText = null;

// Left button: Reset all timers
final CharSequence title1 = context.getString(R.string.timer_stop_all);
Expand All @@ -268,8 +272,6 @@ Notification buildHeadsUp(Context context, List<Timer> expired) {

final long base = getChronometerBase(timer);

final String pname = context.getPackageName();

// Content intent shows the timer full screen when clicked.
final Intent content = new Intent(context, ExpiredTimersActivity.class);
final PendingIntent contentIntent = Utils.pendingActivityIntent(context, content);
Expand All @@ -279,8 +281,7 @@ Notification buildHeadsUp(Context context, List<Timer> expired) {
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
final PendingIntent pendingFullScreen = Utils.pendingActivityIntent(context, fullScreen);

final Builder notification = new Builder(
context, FIRING_NOTIFICATION_CHANNEL_ID)
final Builder notification = new Builder(context, FIRING_NOTIFICATION_CHANNEL_ID)
.setOngoing(true)
.setLocalOnly(true)
.setShowWhen(false)
Expand All @@ -298,13 +299,13 @@ Notification buildHeadsUp(Context context, List<Timer> expired) {
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
notification.setCustomContentView(buildChronometer(pname, base, true, stateText));
notification.setCustomContentView(buildChronometer(context.getPackageName(), base, true, titleText, stateText));
} else {
final CharSequence contentTextPreN = count == 1
? context.getString(R.string.timer_times_up)
: context.getString(R.string.timer_multi_times_up, count);
: null;

notification.setContentTitle(stateText).setContentText(contentTextPreN);
notification.setContentTitle(titleText).setContentText(contentTextPreN);
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Expand All @@ -319,21 +320,23 @@ Notification buildMissed(Context context, NotificationModel nm, List<Timer> miss

// Compute some values required below.
final long base = getChronometerBase(timer);
final String pname = context.getPackageName();
final Resources res = context.getResources();

final Action action;

final CharSequence titleText;
final String label = timer.getLabel();
final CharSequence stateText;
if (count == 1) {
// Single timer is missed.
if (TextUtils.isEmpty(timer.getLabel())) {
stateText = res.getString(R.string.missed_timer_notification_label);
if (TextUtils.isEmpty(label)) {
titleText = context.getString(R.string.timer_notification_label);
} else {
stateText = res.getString(R.string.missed_named_timer_notification_label,
timer.getLabel());
titleText = label;
}

stateText = res.getString(R.string.missed_named_timer_notification_label, label);

// Reset button
final Intent reset = new Intent(context, TimerService.class)
.setAction(TimerService.ACTION_RESET_TIMER)
Expand All @@ -345,7 +348,9 @@ Notification buildMissed(Context context, NotificationModel nm, List<Timer> miss
action = new Action.Builder(icon1, title1, intent1).build();
} else {
// Multiple missed timers.
stateText = res.getString(R.string.timer_multi_missed, count);
titleText = res.getString(R.string.timer_multi_missed, count);

stateText = null;

final Intent reset = TimerService.createResetMissedTimersIntent(context);

Expand All @@ -363,8 +368,7 @@ Notification buildMissed(Context context, NotificationModel nm, List<Timer> miss

final PendingIntent pendingShowApp = Utils.pendingActivityIntent(context, showApp);

final Builder notification = new Builder(
context, TIMER_MODEL_NOTIFICATION_CHANNEL_ID)
final Builder notification = new Builder(context, TIMER_MODEL_NOTIFICATION_CHANNEL_ID)
.setLocalOnly(true)
.setShowWhen(false)
.setAutoCancel(false)
Expand All @@ -379,11 +383,11 @@ Notification buildMissed(Context context, NotificationModel nm, List<Timer> miss
.setColor(context.getColor(R.color.md_theme_primary));

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
notification.setCustomContentView(buildChronometer(pname, base, true, stateText))
notification.setCustomContentView(buildChronometer(context.getPackageName(), base, true, titleText, stateText))
.setGroup(nm.getTimerNotificationGroupKey());
} else {
final CharSequence contentText = AlarmUtils.getFormattedTime(context, timer.getWallClockExpirationTime());
notification.setContentText(contentText).setContentTitle(stateText);
notification.setContentTitle(titleText).setContentText(contentText);
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Expand All @@ -392,11 +396,15 @@ Notification buildMissed(Context context, NotificationModel nm, List<Timer> miss
return notification.build();
}

@TargetApi(Build.VERSION_CODES.N)
private RemoteViews buildChronometer(String pname, long base, boolean running, CharSequence stateText) {
final RemoteViews content = new RemoteViews(pname, R.layout.chronometer_notif_content);
content.setChronometerCountDown(R.id.chronometer, true);
private RemoteViews buildChronometer(String packageName, long base, boolean running, CharSequence titleText,
CharSequence stateText) {

final RemoteViews content = new RemoteViews(packageName, R.layout.chronometer_notif_content);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
content.setChronometerCountDown(R.id.chronometer, true);
}
content.setChronometer(R.id.chronometer, base, null, running);
content.setTextViewText(R.id.title, titleText);
content.setTextViewText(R.id.state, stateText);
return content;
}
Expand Down
Loading

0 comments on commit 9029fb9

Please sign in to comment.