android 提示对话框闹钟怎么在桌面弹出对话框

Android 闹钟详解 - CSDN博客
Android 闹钟详解
最近再做一个项目需要用到Android中的闹钟提醒,在这个过程中遇到很多问题,今天在这里总结分享给大家,希望能对读者有所帮助:
我们都知道Android总共有三种内置的闹钟类型,如下:
(1)set(int type,long startTime,PendingIntent pi);
该方法用于设置一次性闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟执行时间,第三个参数表示闹钟响应动作。
(2)setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
该方法用于设置重复闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟首次执行时间,第三个参数表示闹钟两次执行的间隔时间,第三个参数表示闹钟响应动作。
(3)setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
该方法也用于设置重复闹钟,与第二个方法相似,不过其两个闹钟执行的间隔时间不是固定的而已。
在项目中用到了第一种和第二种,第三种没有涉及到。
现在先说一下前两种闹钟最基本的用法(摘自于网络),再详细讲述我在项目中遇到的问题和最终是如何解决的。
为了测试的方便直接在Android studio中自动生成activity的oncreate方法里测试了:
一、(1)在指定时长后执行某项操作
代码如下:
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent =new Intent(this, AlarmReceiver.class);
PendingIntent sender= PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar calendar= Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());//将时间设定为系统目前的时间
calendar.add(Calendar.SECOND, 5);//系统时间推迟五秒钟,如果为-5,那么就是比系统时间提前五秒钟
AlarmManager alarm=(AlarmManager)getSystemService(ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
}Toast.makeText(context, &short alarm&, Toast.LENGTH_LONG).show();
为了测试的方便我们定义了一个广播接收器,代码如下:
public class AlarmReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, &short alarm&, Toast.LENGTH_LONG).show();
这段代码什么时候执行呢?我们先讲讲在上面activity中用到的令人非常头疼的PendingIntent,最令人头疼的就是第二个和第四个参数了,暂且定为0(稍后会讲)
PendingIntent sender:是闹钟的执行动作,比如发送一个广播、给出提示等等。PendingIntent是Intent的封装类。需要注意的是,如果是通过启动服务来实现闹钟提示的话,PendingIntent对象的获取就应该采用Pending.getService( Context &c,int i,Intent intent,int j)方法;如果是通过广播来实现闹钟提示的话PendingIntent对象的获取就应该采用PendingIntent.getBroadcast(Context
c,int i,Intent intent,int j)方法;如果是采用Activity的方式来实现闹钟提示的话,PendingIntent对象的获取就应该采用PendingIntent.getActivity(Context c,int i,Intent intent,int j)方法。如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。
从某种意义上来说PendingIntent 其实就是一个延迟的Intent,它将Intent进行了封装,为什么说是延迟呢,是因为当达到某种条件后他才会触发Intent的动作。在本例中就是到运行之后的五秒钟触发Intent的动作,也就是发送一条广播了,提示闹钟设定成功了。至此,上面的例子也就解释的差不多了。顺便把
AlarmManager类型如下:
AlarmManager.RTC,硬件闹钟,不唤醒手机(也可能是其它设备)休眠;当手机休眠时不发射闹钟。
AlarmManager.RTC_WAKEUP,硬件闹钟,当闹钟发射时唤醒手机休眠;
AlarmManager.ELAPSED_REALTIME,真实时间流逝闹钟,不唤醒手机休眠;当手机休眠时不发射闹钟。
AlarmManager.ELAPSED_REALTIME_WAKEUP,真实时间流逝闹钟,当闹钟发射时唤醒手机休眠;
RTC闹钟和ELAPSED_REALTIME最大的差别就是前者可以通过修改手机时间触发闹钟事件,后者要通过真实时间的流逝,即使在休眠状态,时间也会被计算。
(2)周期性的执行某项操作
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent =new Intent(this, AlarmReceiver.class);
PendingIntent sender= PendingIntent.getBroadcast(this, 0, intent, 0);
long firstime = SystemClock.elapsedRealtime();
AlarmManager am=(AlarmManager)getSystemService(ALARM_SERVICE);
//5秒一个周期,不停的发送广播
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstime, 5 * 1000, sender);
}public class AlarmReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, &short alarm&, Toast.LENGTH_LONG).show();
上面的例子是一个周期性的,每五秒发送一条广播
二、在实际项目中遇到的以下问题及解决办法
项目中有这么一个需求,有很多不同的日程需要不同周期的提醒,如下:
在实际编码中可能你会想到以下的一个循环
switch (repeatType) {
//repeatType闹钟周期重复的类型
case NEVER: //永不
AlarmManager manager1 = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent1 = new Intent(this, AlarmReceiver.class);
PendingIntent pi1 = PendingIntent.getBroadcast(this, 0, intent2, 0);
manager.set(AlarmManager.RTC_WAKEUP, startTime,intervalTime1 , pi1);
case EVERY_DAY: //每天
AlarmManager manager2 = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent2 = new Intent(this, AlarmReceiver.class);
PendingIntent pi2 = PendingIntent.getBroadcast(this, 0, intent2, 0);
manager.setRepeating(AlarmManager.RTC_WAKEUP, startTime,intervalTime2, pi2);//如果当前时间大于了开始时间,则还会提醒了
case EVERY_WEEK:
AlarmManager manager3 = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent3 = new Intent(this, AlarmReceiver.class);
PendingIntent pi3 = PendingIntent.getBroadcast(this, 0, intent3, 0);
manager3.setRepeating(AlarmManager.RTC_WAKEUP,startTime,intervalTime3,pi3);//如果当前时间大于了开始时间,则还会提醒了
case TWO_WEEK:
AlarmManager manager4 = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent4 = new Intent(this, AlarmReceiver.class);
PendingIntent pi4 = PendingIntent.getBroadcast(this, 0, intent4, 0);
manager4.setRepeating(AlarmManager.RTC_WAKEUP,startTime,intervalTime4,pi4);
case EVERY_MONTH: //每月
AlarmManager manager5 = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent5 = new Intent(this, AlarmReceiver.class);
PendingIntent pi5 = PendingIntent.getBroadcast(this, 0, intent5, 0);
manager5.setRepeating(AlarmManager.RTC_WAKEUP,startTime,intervalTime5,pi5);
}上面的intervalTime对应的是间隔时间也就日、周、两周、月…………
这样的思路是没有问题的,但是这样做会出现两个问题:
第一问题:假设现在是八点,你设定的闹钟是七点,那么程序一运行接着就会触发闹钟,这一点需要避免,直接加个判断语句,现在的时间要小于设定时间的时候才能触发闹钟
第二个问题:闹钟的覆盖。Android中的闹钟如果是一样的话,后面的闹钟会覆盖掉前面的闹钟,例如设定了八点和七点的闹钟,那么八点的闹钟会覆盖掉七点的闹钟,最后只会响应一个八点的闹钟。那么怎么区分出不同的闹钟呢,那么就是我们将要讲的&PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, 0);里面的第二个参数了,这个参数来区分不同的闹钟,我们只需要传进去一个不同的整形值就不再覆盖之前的闹钟了,可以取一个全局变量i,然后这样定义&PendingIntent
pi1 = PendingIntent.getBroadcast(this, i++, intent2, 0);,这样就避免了闹钟的覆盖。那么接着问题又来了,我们假设要取消其中的一个周期闹钟,我们应该怎么办呢?
我采用的方法如下
结合上面的讲解,这样定义一个PendingIntent:
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra(&alarm_type&, ++alarmCount + &&);
PendingIntent pi = PendingIntent.getBroadcast(this, alarmCount, intent, 0);
manager.setRepeating(AlarmManager.RTC_WAKEUP,startTime,intervalTime,pi);
然后当时间到了之后会发送一条广播,我们在广播接收器里取消闹钟,注意和上面的代码对比一下,要取消的是同一个闹钟
public class AlarmReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(context, Integer.parseInt(intent.getStringExtra(&alarm_type&)), intent, 0);
manager.cancel(pi);
通过上面的办法就可以取消想要取消的闹钟
后来在结合的代码的时候,主管提出新的要求了:如果两个不同的事件定在同一个时间提醒,如果按照上面的办法会同时弹出两个对话框提醒(因为是两个不同的闹钟),现在要做的就是要合并到一个闹钟,采用列表的形式提醒用户这两个事件到了时间提醒了,也就是一个闹钟。在这个过程中又遇到了一个问题,纠结了我一下午才解决出来,最后只是一个参数的问题,上代码吧:
private void setAlarmTime(long startTime, ArrayList&Agenda& oneListAgenda) {
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
String[] titleArray = new String[oneListAgenda.size()];
for (int i = 0; i & oneListAgenda.size(); i++) {
titleArray[i] = oneListAgenda.get(i).getAg_title();
intentReceiver.putExtra(&titleArray&, titleArray);
PendingIntent pi = PendingIntent.getBroadcast(this, alarmCount, intentReceiver,0);
manager.set(AlarmManager.RTC_WAKEUP, startTime, pi);
上面的titleArray数组存着相同时间的日程,这样会出现什么问题呢?
假设设定了一个事件,接着执行了这段代码,接着PendingIntent就会被注册了,如果设定同一个时间的另一个事件,再运行这段代码的时候,这样titleArray里面就是两个值,但是我在广播接收器里取出这个数组的时候,却变成了一个值,究其原因就是PendingIntent 的最后一个参数问题,运行到此处时重新注册一个PendingIntent 就可以了,设置如下: PendingIntent pi = PendingIntent.getBroadcast(this, alarmCount, intentReceiver, PendingIntent.FLAG_UPDATE_CURRENT);
上面就是我在项目中遇到的问题,希望对像我一样刚入门的人有所帮助!
本文已收录于以下专栏:
相关文章推荐
实现简单的闹钟功能,具有添加闹钟,删除闹钟和修改闹钟的功能,具有不难看的ui
android 闹钟网上基本实现的是用AlarmManager
来说说AlarmManager吧用它的好处是 在设定好提醒时间后 到点app会接收到触发广播
接收到广播事件后我们可以做一些处理
本文主要描述了如何控制Android闹钟,简介清晰
public static void wakeUpAndUnlock(Context context){
KeyguardManager km= (KeyguardManager) c...
对应AlarmManage有一个AlarmManagerServie服务程序,该服务程序才是正真提供闹铃服务的,它主要维护应用程序注册下来的各类闹铃并适时的设置即将触发的闹铃给闹铃设备(在系统中,li...
在这篇文章中,你会学习到在Android 5.0中如何使用JobScheduler API。JobScheduler API允许开发者在符合某些条件时创建执行在后台的任务。
直接上代码
 // 安卓原生系统闹钟action
    private static final String ALARM_ALERT_ACTION = &com.android.deskclock...
android AlarmManager重复闹钟不准确
我以前写了个复杂闹钟的demo,参见Android闹钟【复杂版】【大明进化十五】 .但是里面的bug有一些,好多人留言,所以我就看看源码,找找原因?顺便把源码代码整理出来,弄成一个完整的可以运行的ap...
1.首先闹钟分两种,一种是一次性的,还有一种就是周期性的。2.简易的通知。package com.thm.thm_android_alarm_import android.a...
他的最新文章
讲师:何宇健
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)android 设置闹钟及通知示例
作者:夜的千章
字体:[ ] 类型:转载 时间:
本篇文章主要介绍了android 设置闹钟及通知示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
简单说一下这次demo内容,首先做一个设置一次性闹钟,先得到alarmManager,打开一个时间对话框,在里面设置闹钟的时间,时间一到发送广播,然后广播接受者接到跳转到新的activity播放音乐。接着是一个反复闹钟,最后是一个简单的通知,具体代码如下:
import android.app.AlarmM
import android.app.N
import android.app.NotificationM
import android.app.PendingI
import android.app.TimePickerD
import android.content.C
import android.content.I
import android.support.v7.app.AppCompatA
import android.os.B
import android.support.v7.app.NotificationC
import android.view.V
import android.widget.TimeP
import java.util.C
public class MainActivity extends AppCompatActivity {
private AlarmManager alarmM
private PendingIntent pendingI
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取闹钟管理者
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
public void setAlarm(View view){
//获取当前系统的时间
Calendar calendar=Calendar.getInstance();
int hour=calendar.get(Calendar.HOUR_OF_DAY);
int minute=calendar.get(Calendar.MINUTE);
//弹出时间对话框
TimePickerDialog timePickerDialog=new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker timePicker, int i, int i1) {
Calendar c=Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY,i);
c.set(Calendar.MINUTE,i1);
Intent intent=new Intent();
intent.setAction("com.zking.g150820_android28_alarm_notification.RING");
//将来时态的跳转 ang eng ing ong
PendingIntent pendingIntent=PendingIntent.getBroadcast(MainActivity.this,0x101,intent,0);
//设置闹钟
alarmManager.set(AlarmManager.RTC_WAKEUP,c.getTimeInMillis(),pendingIntent);
//时间一到,发送广播(闹钟响了)
//广播接受者中(跳转Activity)
// 跳转Activity,在这个Activity中播放音乐
},hour,minute,true);
timePickerDialog.show();
public void setAlarmCycle(View view){
//获取当前系统的时间
Calendar calendar=Calendar.getInstance();
int hour=calendar.get(Calendar.HOUR_OF_DAY);
int minute=calendar.get(Calendar.MINUTE);
//弹出时间对话框
TimePickerDialog timePickerDialog=new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
public void onTimeSet(TimePicker timePicker, int i, int i1) {
Calendar c=Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY,i);
c.set(Calendar.MINUTE,i1);
Intent intent=new Intent();
intent.setAction("com.zking.g150820_android28_alarm_notification.RING");
//将来时态的跳转 ang eng ing ong
pendingIntent = PendingIntent.getBroadcast(MainActivity.this,0x101,intent,0);
//设置闹钟
alarmManager.set(AlarmManager.RTC_WAKEUP,c.getTimeInMillis(),pendingIntent);
//设置周期闹钟
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,c.getTimeInMillis(),5000, pendingIntent);
//时间一到,发送广播(闹钟响了)
//广播接受者中(跳转Activity)
// 跳转Activity,在这个Activity中播放音乐
},hour,minute,true);
timePickerDialog.show();
public void cancelCycle(View view){
alarmManager.cancel(pendingIntent);
public void sendNotification(View view){
//实例化通知管理器
NotificationManager notificationManager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//实例化通知
NotificationCompat.Builder builder=new NotificationCompat.Builder(this);
builder.setContentTitle("今日大事件");
builder.setContentText("骑士击败勇士夺冠");
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
builder.setAutoCancel(true);
builder.setSmallIcon(android.R.drawable.ic_media_play);
builder.setContentIntent(PendingIntent.getActivity(this,0x102,new Intent(this,RingActivity.class),0));
Notification notification=builder.build();
//发送通知
notificationManager.notify(0x101,notification);
布局文件(xml):
&LinearLayout xmlns:android="/apk/res/android"
xmlns:tools="/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".ghq_android_28.MainActivity"&
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="设置闹钟(一次)"
android:onClick="setAlarm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="设置闹钟(周期)"
android:onClick="setAlarmCycle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="取消周期"
android:onClick="cancelCycle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送通知"
android:onClick="sendNotification"
&/LinearLayout&
广播接受者代码:
public class RingReceived extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (".ghq_android_28_alarm_notification.RING".equals(intent.getAction())){
//跳转到Activity
Intent intent1=new Intent(context,RingActivity.class);
//给Intent设置标志位
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
闹钟播放activity代码:
public class RingActivity extends AppCompatActivity {
private MediaPlayer mediaP
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ring);
mediaPlayer = MediaPlayer.create(this, R.raw.love);
mediaPlayer.start();
public void stop(View view){
mediaPlayer.stop();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具Android 开发第五弹:简易时钟(闹钟)
这次是一个时钟类应用,目前依旧是主要的功能,长得还是很挫。当然了,核心功能是有的&&
闹钟之前的准备
布局的话,不管是采用FrameLayout或者LinearLayout都可以。
我这里采用了FrameLayout,然后加上一个TabHost,之前在看到有同学提问在WF中这种多个栏目的用什么控件,我的答案是在WF、F、Windows App、ASP.NET以及安卓上都是Tab开头的控件。
&framelayout android:layout_height="match_parent" android:layout_width="match_parent" tools:context=".MainActivity" xmlns:android="/apk/res/android" xmlns:tools="/tools"&
&framelayout android:id="@android:id/tabcontent" android:layout_height="match_parent" android:layout_width="match_parent"&
&/framelayout&
&/framelayout&
定义好了TabHost之后就可以在MainAcitivity类中实例化它们了。
private static TabHost tabH
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabHost = (TabHost)findViewById(R.id.tabHost);
tabHost.setup();
tabHost.addTab(tabHost.newTabSpec(tabAlarm).
setIndicator(闹钟).setContent(R.id.tabAlarm));
tabHost.addTab(tabHost.newTabSpec(tabTime).
setIndicator(时钟).setContent(R.id.tabTime));
tabHost.addTab(tabHost.newTabSpec(tabTimer).
setIndicator(计时器).setContent(R.id.tabTimer));
tabHost.addTab(tabHost.newTabSpec(tabStopWatch).
setIndicator(秒表).setContent(R.id.tabStopWatch));
如果你想调整&闹钟&与&时钟&这些的先后顺序,直接在代码中调整代码执行顺序即可。
首先呢,别的不管,我为大家准备了非常好听的铃声,可惜铃声只能放源码里而不能放博客上&&
现在来写一个AlarmView类,到时候在布局文件中可以直接使用它。
AlarmView类应该扩展LinearLayout,因为前面说到的,AlarmView是用作布局的。
private AlarmManager alarmM
public AlarmView(Context context) {
super(context);
public AlarmView(Context context, AttributeSet attrs) {
super(context, attrs);
public AlarmView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
private void init(){
alarmManager = (AlarmManager)getContext().getSystemService(Context.ALARM_SERVICE);
实例化一个闹钟管理类,后面就通过它来使用闹钟服务。
核心部分都在这里了,注释都加了,大家慢慢看吧:
protected void onFinishInflate(){
super.onFinishInflate();
// 实例化按钮和列表
btnAddAlarm = (Button)findViewById(R.id.btnAddAlarm);
lvAlarmList = (ListView)findViewById(R.id.lvAlarmList);
// 实例化适配器
adapter = new ArrayAdapter(getContext(),
android.R.layout.simple_list_item_1);
// 为列表添加适配器
lvAlarmList.setAdapter(adapter);
// 保存闹钟列表
readSavedAlarmList();
// 添加闹钟的监听事件
btnAddAlarm.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// 添加闹钟
addAlarm();
// 闹钟列表的监听事件
lvAlarmList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView parent, View view,
final int position, long id) {
// 单击其中一项会调出对话框,其中有&删除&和&全部删除&两项可以选择
new AlertDialog.Builder(getContext()).setTitle(操作选项).setItems(
new CharSequence[]{删除, 全部删除}, new DialogInterface.
OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch (which) {
// 对话框中的项索引从0开始,删除选中项
deleteAlarm(position);
// 删除所有项,实际App中并不常用,只是因为测试过程中添加了太多闹钟。
deleteAllAlarm();
).setNegativeButton(取消, null).show();
// 为对话框添加一个取消的按钮
上面用到的addAlarm方法,这里也列出来了。注意弹出的时间选择对话框会因安卓版本而不同,我GIF中的是 5.0的。
// 添加闹钟
void addAlarm(){
// 实例化一个Calendar类,并取当前时间
Calendar c = Calendar.getInstance();
// 弹出时间选择对话框
new TimePickerDialog(getContext(),new TimePickerDialog.OnTimeSetListener(){
public void onTimeSet(TimePicker view, int hourOfDay, int minute){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,hourOfDay);
calendar.set(Calendar.MINUTE,minute);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND,0);
// 当前时间
Calendar currentTime = Calendar.getInstance();
// 如果设置的闹钟时间比当前时间还小,你不能将闹钟定在过去咯?所以令其往前加一天
if(calendar.getTimeInMillis() &= currentTime.getTimeInMillis()){
calendar.setTimeInMillis(calendar.getTimeInMillis() + 24*60*60*1000);
// 实例化一个AlarmData类
AlarmData ad = new AlarmData(calendar.getTimeInMillis());
// 为适配器添加数据
adapter.add(ad);
// 将数据设置到闹钟管理中
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
ad.getTime(),
// 闹钟时间
5*60*1000,
PendingIntent.getBroadcast(getContext(),
ad.getId(),
new Intent(getContext(),
AlarmReceiver.class),
// 添加之后记得保存闹钟列表
saveAlarmList();
},c.get(Calendar.HOUR_OF_DAY),c.get(Calendar.MINUTE), true).show();
下面的是保存闹钟列表的方法,并没有什么难度,重点在最后的if判断。
// 保存闹钟列表
private void saveAlarmList(){
Editor editor = getContext().getSharedPreferences(
AlarmView.class.getName(),
Context.MODE_PRIVATE).edit();
StringBuffer sb = new StringBuffer();
for(int i = 0; i & adapter.getCount(); i++){
sb.append(adapter.getItem(i).getTime()).append(,);
if(sb.length() & 1){
String content = sb.toString().substring(0,sb.length()-1);
// 去掉最后一个逗号
editor.putString(KEY_ALARM, content);
System.out.println(content);
// 调试使用
// 如果长度为空,也要提交一个空的上去
editor.putString(KEY_ALARM, null);
// 记得提交
应用不能每次关掉后数据就没有了,需要将它们保存起来,因此也需要能够加载保存的数据。
// 读取保存的闹钟列表,在每次加载应用的时候会调用它
private void readSavedAlarmList(){
// 实例化共享首选项
SharedPreferences sp = getContext().getSharedPreferences(
AlarmView.class.getName(), Context.MODE_PRIVATE);
String content = sp.getString(KEY_ALARM, null);
if(content != null){
String[] timeStrings = content.split(,);
// 遍历每一个字符串,并将其添加到适配器中
for(String str : timeStrings){
adapter.add(new AlarmData(Long.parseLong(str)));
删除闹钟的方法,重点在于:1,在AlarmManager中取消闹钟;2,不能在for循环中动态计算适配器大小。
// 删除闹钟,传入一个position位置,删除指定项
private void deleteAlarm(int position){
// 根据传入的位置参数实例化一个AlarmData
AlarmData ad = adapter.getItem(position);
// 从适配器中移除
adapter.remove(ad);
// 删除后记得再次保存列表
saveAlarmList();
// 记得在闹钟管理中将其取消掉,否则删除后闹钟依旧会激活
alarmManager.cancel(PendingIntent.getBroadcast(getContext(),ad.getId(),
new Intent(getContext(), AlarmReceiver.class),0));
// 删除所有闹钟
private void deleteAllAlarm(){
// 获取适配器中的闹钟数量
int adapterCount =adapter.getCount();
// 为adapter的个数进行计数
// 因为每次删除后适配器的数量都会改变,所以需要在上面一次性计算好,不能将其放到for循环中计算
for(int i = 0; i & adapterC i++){
// 此处括号中不能填i,因为每次移除后第二项又变成第一项
ad = adapter.getItem(0);
// 每次从第1个开始移除
adapter.remove(ad);
saveAlarmList();
// 移除后重新保存列表
alarmManager.cancel(PendingIntent.getBroadcast(getContext(),ad.getId(),
new Intent(getContext(),AlarmReceiver.class),0));
// 取消闹钟的广播
最后就要设置一个AlarmData类,其中设置方法获取闹钟的请求码。
private static class AlarmData{
private String timeLabel = ;
private long time = 0;
public AlarmData(long time){
this.time =
date = Calendar.getInstance();
date.setTimeInMillis(time);
timeLabel = String.format(%d月%d日 %d:%d,
date.get(Calendar.MONTH)+1,
date.get(Calendar.DAY_OF_MONTH),
date.get(Calendar.HOUR_OF_DAY),
date.get(Calendar.MINUTE));
public long getTime(){
public String getTimeLabel(){
return timeL
// 设置唯一的请求码
public int getId(){
return (int)(getTime()/1000/60);
// 重载头String()方法
public String toString(){
return getTimeLabel();
PlayAlarmAty
现在来写一个PlayAlarmAty类,它得扩展自Activity。
private MediaP
Button btnAlarmP
Button btnAlarmR
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alarm_player_aty);
mp = MediaPlayer.create(this,R.raw.ringtone);
mp.start();
btnAlarmPause = (Button)findViewById(R.id.btnAlarmPause);
btnAlarmPause.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onPause();
btnAlarmReset = (Button)findViewById(R.id.btnAlarmReset);
btnAlarmReset.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onDestroy();
protected void onPause() {
super.onPause();
mp.pause();
mp.release();
protected void onDestroy() {
super.onDestroy();
mp.stop();
mp.release();
其对应的布局是:
这是在闹钟激活是需要弹出的界面,所以你需要一个接收器。
AlarmReceiver
AlarmReceiver类需要扩展自BroadcastReceiver,重载onReceive方法:
public void onReceive(Context context, Intent intent) {
System.out.println(闹钟执行了!);
// 作调试用
// 闹钟管理
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// 取消闹钟
am.cancel(PendingIntent.getBroadcast(context, getResultCode(),
new Intent(context, AlarmReceiver.class), 0));
// 实例化一个Intent,启动该Activity
Intent i = new Intent(context, PlayAlarmAty.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
别放了在清单文件中添加它们&&(在application下)
哦对了,忘了说,需要用到的string都放在strings.xml,这个就不贴出来了。
因为还是比较长的,所以就分成3篇来写好了。
准备的铃声挺好听的,至少比代码好听,哈哈&&不管是需要铃声还是需要代码的,直接评论留邮箱吧,我就不上传到CSDN资源了。代码会继续更新的,注释也会继续更新&&
项目也上传到Github了,欢迎大家贡献代码啊&&传送门 。

我要回帖

更多关于 android 提示对话框 的文章

 

随机推荐