最近在看Android app 的时候,发现闹钟app 还是挺有趣的,于是写了一个练手。下面上图片
发现最新的Android系统已经不能使用旧版的通知 了,否则,闹铃不会响。所以修改了源码,支持android 10 。下面展示主要代码
if (Alarms.ALARM_KILLED.equals(intent.getAction())) {
// The alarm has been killed, update the notification
updateNotification(context, (Alarm)
intent.getParcelableExtra(Alarms.ALARM_INTENT_EXTRA),
intent.getIntExtra(Alarms.ALARM_KILLED_TIMEOUT, -1));
return;
} else if (Alarms.CANCEL_SNOOZE.equals(intent.getAction())) {
Alarms.saveSnoozeAlert(context, -1, -1);
return;
} else if (!Alarms.ALARM_ALERT_ACTION.equals(intent.getAction())) {
// Unknown intent, bail.
return;
}
Alarm alarm = null;
// Grab the alarm from the intent. Since the remote AlarmManagerService
// fills in the Intent to add some extra data, it must unparcel the
// Alarm object. It throws a ClassNotFoundException when unparcelling.
// To avoid this, do the marshalling ourselves.
final byte[] data = intent.getByteArrayExtra(Alarms.ALARM_RAW_DATA);
if (data != null) {
Parcel in = Parcel.obtain();
in.unmarshall(data, 0, data.length);
in.setDataPosition(0);
alarm = Alarm.CREATOR.createFromParcel(in);
}
if (alarm == null) {
Log.v("wangxianming", "Failed to parse the alarm from the intent");
// Make sure we set the next alert if needed.
Alarms.setNextAlert(context);
return;
}
// Disable the snooze alert if this alarm is the snooze.
Alarms.disableSnoozeAlert(context, alarm.id);
// Disable this alarm if it does not repeat.
if (!alarm.daysOfWeek.isRepeatSet()) {
Alarms.enableAlarm(context, alarm.id, false);
} else {
// Enable the next alert if there is one. The above call to
// enableAlarm will call setNextAlert so avoid calling it twice.
Alarms.setNextAlert(context);
}
// Intentionally verbose: always log the alarm time to provide useful
// information in bug reports.
long now = System.currentTimeMillis();
// Always verbose to track down time change problems.
if (now > alarm.time + STALE_WINDOW) {
Log.v("wangxianming", "Ignoring stale alarm");
return;
}
// Maintain a cpu wake lock until the AlarmAlert and AlarmKlaxon can
// pick it up.
AlarmAlertWakeLock.acquireCpuWakeLock(context);
/* Close dialogs and window shade */
Intent closeDialogs = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.sendBroadcast(closeDialogs);
// Decide which activity to start based on the state of the keyguard.
Class c = AlarmAlert.class;
KeyguardManager km = (KeyguardManager) context.getSystemService(
Context.KEYGUARD_SERVICE);
if (km.inKeyguardRestrictedInputMode()) {
// Use the full screen activity for security.
c = AlarmAlertFullScreen.class;
}
// Play the alarm alert and vibrate the device.
Intent playAlarm = new Intent(context,AlarmAlertFullScreen.class);
playAlarm.putExtra(Alarms.ALARM_INTENT_EXTRA, alarm);
playAlarm.addFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(playAlarm);
// Trigger a notification that, when clicked, will show the alarm alert
// dialog. No need to check for fullscreen since this will always be
// launched from a user action.
Intent notify = new Intent(context, AlarmAlert.class);
notify.putExtra(Alarms.ALARM_INTENT_EXTRA, alarm);
PendingIntent pendingNotify = PendingIntent.getActivity(context,
alarm.id, notify, 0);
// Use the alarm's label or the default label as the ticker text and
// main text of the notification.
String label = alarm.getLabelOrDefault(context);
// Notification n = new Notification(R.drawable.stat_notify_alarm,
// label, alarm.time);
// n.setLatestEventInfo(context, label,
// context.getString(R.string.alarm_notify_text),
// pendingNotify);
Notification.Builder builder = new Notification.Builder(context);
Notification n = builder.setContentTitle(label)
.setSmallIcon(R.drawable.stat_notify_alarm)
.setContentText(context.getString(R.string.alarm_notify_text))
.setContentIntent(pendingNotify).build();
n.flags |= Notification.FLAG_SHOW_LIGHTS
| Notification.FLAG_ONGOING_EVENT;
n.defaults |= Notification.DEFAULT_LIGHTS;
// NEW: Embed the full-screen UI here. The notification manager will
// take care of displaying it if it's OK to do so.
Intent alarmAlert = new Intent(context, c);
alarmAlert.putExtra(Alarms.ALARM_INTENT_EXTRA, alarm);
alarmAlert.setFlags(FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_NO_USER_ACTION);
n.fullScreenIntent = PendingIntent.getActivity(context, alarm.id, alarmAlert, 0);
// Send the notification using the alarm id to easily identify the
// correct notification.
NotificationManager nm = getNotificationManager(context);
nm.notify(alarm.id, n);
这里主要使用广播接收者,来监听系统时间。如果时间到则发送通知,唤醒系统响铃。
如有需要可以私信 A18125287959