Android开发之闹钟

闹钟开发:
1、需要时间选择器TimePicker
2、需要Calendar类对日期时间进行操作
3、需要AlarmManager//闹钟管理实质是一个全局定时器, 是Android中常用的一种系统级别的提示服务,在指定时间或周期性启动其它组件(包括Activity,Service,BroadcastReceiver)。
4、PendingIntent的理解
PendingIntent 可以看作是对intent的包装,通常通过getActivity,getBroadcast ,getService来得到pendingintent的实例,当前activity并不能马上启动它所包含的intent,而是在外部执行 pendingintent时,调用intent的。正由于pendingintent中 保存有当前App的Context,使它赋予外部App一种能力,使得外部App可以如同当前App一样的执行pendingintent里的 Intent, 就算在执行时当前App已经不存在了,也能通过存在pendingintent里的Context照样执行Intent。另外还可以处理intent执行后的操作。常和alermanger 和notificationmanager一起使用。
Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据,而Pendingintent,一般用在 Notification上,可以理解为延迟执行的intent,PendingIntent是对Intent一个包装。
PendingIntent参数
public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags)
public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags)
第一个参数为当前Activity.this
第二个参数为请求码,可通过第二个参数判断是哪个PendingIntent。(一般认为没有作用)
第三个参数较为复杂:
FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的PendingIntent对象,那么就将先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。
FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null。
FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
FLAG_UPDATE_CURRENT:如果系统中有一个和你描述的PendingIntent对等的PendingInent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。
FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT的区别在于能否新new一个Intent,FLAG_CANCEL_CURRENT能够新new一个Intent,而FLAG_UPDATE_CURRENT则不能,只能使用第一次的Intent。 还有一个问题就是怎么区分PendingIntent,主要取消的时候要用到,requestCode可以区分,但系统还是根据Intent的Action去区分的,如果Intent设置了Class,classData,取消的时候Intent一定要设置要相同的,不然取消不掉就可能出现取消后,Alarm还会响的问题

1、TimePicker与Calendar的用法
TimePicker一个可以选取时间的控件,对其设置监听获得所选的时间

1MainActivity.this.tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { 2@Override 3public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { 4MainActivity.this.calendar = Calendar.getInstance(); //获得一个Calendar的实例 5MainActivity.this.calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); //HOUR_OF_DAY是24小时制 6MainActivity.this.calendar.set(Calendar.MINUTE, minute); 7MainActivity.this.calendar.set(Calendar.SECOND, 0); 8//先保存起来,更新textview时可以用 9MainActivity.this.hourofday = hourOfDay; 10MainActivity.this.minute = minute; 11 12} 13});

2、AlarmManager的用法
MainActivity.this.alarmManager = (AlarmManager) MainActivity.this.getSystemService(ALARM_SERVICE); //获得一个AlarmManager服务


1MainActivity.this.set.setOnClickListener(new View.OnClickListener() { 2@Override 3public void onClick(View v) { 4/*AlarmManager.RTC,硬件闹钟,不唤醒休眠; 5AlarmManager.RTC_WAKEUP,硬件闹钟,唤醒休眠; 6AlarmManager.ELAPSED_REALTIME,真实时间流逝闹钟,不唤醒休眠; 7AlarmManager.ELAPSED_REALTIME_WAKEUP,真实时间流逝闹钟,唤醒休眠;*/ 8Intent intent = new Intent(MainActivity.this, AlarmBroadcastReceiver.class); 9intent.setAction("com.example.hxdn.naozhong"); 10PendingIntent operation = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 11MainActivity.this.alarmManager.set(AlarmManager.RTC_WAKEUP, MainActivity.this.calendar.getTimeInMillis(), operation); //
//参数1:解释在上面。参数二:传入时间毫秒参数三:传入PendingIntent 12MainActivity.this.tv.setText("闹钟时间:" + MainActivity.this.hourofday + "时" + MainActivity.this.minute + "分" + "00秒"); 13Toast.makeText(MainActivity.this, "闹钟设置完毕!", Toast.LENGTH_LONG); 14} 15}); 16MainActivity.this.cancle.setOnClickListener(new View.OnClickListener() { 17@Override 18public void onClick(View v) { 19Intent intent = new Intent(MainActivity.this, AlarmBroadcastReceiver.class); 20intent.setAction("com.example.hxdn.naozhong"); //要与上面设置的一样,否则会出现取消掉闹钟还是响的问题。 21PendingIntent operation = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 22MainActivity.this.alarmManager.cancel(operation); 23MainActivity.this.tv.setText("当前闹钟未设置"); 24Toast.makeText(MainActivity.this, "闹钟已删除!", Toast.LENGTH_SHORT).show(); 25} 26});

机制:
通过TimePicker设置时间由Calendar获得时间,包装一个PendingIntent(即使当前Activity销毁仍然可以启动广播从而启动AlarmActivity弹出提示框和震动),由alarmManager设置。
注意点:
记得注册BroadcastReceiver和AlamActivity!
震动需要权限!

接下来贴出全部的代码:
布局代码:
1 7 8 12 18 22

MainActivity.java
1 package com.example.hxdn.naozhong; 2 3 import android.app.AlarmManager; 4 import android.app.PendingIntent; 5 import android.content.Intent; 6 import android.support.v7.app.AppCompatActivity; 7 import android.os.Bundle; 8 import android.util.Log; 9 import android.view.Menu; 10 import android.view.MenuItem; 11 import android.view.View; 12 import android.widget.Button; 13 import android.widget.TextView; 14 import android.widget.TimePicker; 15 import android.widget.Toast; 16 17 import java.util.Calendar; 18 19 public class MainActivity extends AppCompatActivity { 20 21private static final String TAG = "MMM"; 22private Button set = null; 23private Button cancle = null; 24private TextView tv = null; 25private TimePicker tp = null; //时间选择器 26private Calendar calendar = null; //日期操作 27private AlarmManager alarmManager = null; //闹钟管理AlarmManager实质上是一个全局的定时器, 28private int hourofday; 29private int minute; 30 31// 是Android中常用的一种系统级别的提示服务,在指定时间或周期性启动其它组件(包括Activity,Service,BroadcastReceiver)。 32@Override 33protected void onCreate(Bundle savedInstanceState) { 34super.onCreate(savedInstanceState); 35setContentView(R.layout.activity_main); 36init(); 37initAction(); 38} 39 40@Override 41public boolean onCreateOptionsMenu(Menu menu) { 42// Inflate the menu; this adds items to the action bar if it is present. 43getMenuInflater().inflate(R.menu.menu_main, menu); 44return true; 45} 46 47@Override 48public boolean onOptionsItemSelected(MenuItem item) { 49// Handle action bar item clicks here. The action bar will 50// automatically handle clicks on the Home/Up button, so long 51// as you specify a parent activity in AndroidManifest.xml. 52int id = item.getItemId(); 53 54//noinspection SimplifiableIfStatement 55if (id == R.id.action_settings) { 56return true; 57} 58 59return super.onOptionsItemSelected(item); 60} 61 62private void initAction() { 63MainActivity.this.tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { 64@Override 65public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { 66MainActivity.this.calendar = Calendar.getInstance(); 67MainActivity.this.calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); //HOUR_OF_DAY是24小时制 68MainActivity.this.calendar.set(Calendar.MINUTE, minute); 69MainActivity.this.calendar.set(Calendar.SECOND, 0); 70//更新textview 71MainActivity.this.hourofday = hourOfDay; 72MainActivity.this.minute = minute; 73 74} 75}); 76MainActivity.this.set.setOnClickListener(new View.OnClickListener() { 77@Override 78public void onClick(View v) { 79/*AlarmManager.RTC,硬件闹钟,不唤醒休眠; 80AlarmManager.RTC_WAKEUP,硬件闹钟,唤醒休眠; 81AlarmManager.ELAPSED_REALTIME,真实时间流逝闹钟,不唤醒休眠; 82AlarmManager.ELAPSED_REALTIME_WAKEUP,真实时间流逝闹钟,唤醒休眠;*/ 83Intent intent = new Intent(MainActivity.this, AlarmBroadcastReceiver.class); 84intent.setAction("com.example.hxdn.naozhong"); 85PendingIntent operation = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 86MainActivity.this.alarmManager.set(AlarmManager.RTC_WAKEUP, MainActivity.this.calendar.getTimeInMillis(), operation); 87MainActivity.this.tv.setText("闹钟时间:" + MainActivity.this.hourofday + "时" + MainActivity.this.minute + "分" + "00秒"); 88Toast.makeText(MainActivity.this, "闹钟设置完毕!", Toast.LENGTH_LONG); 89} 90}); 91MainActivity.this.cancle.setOnClickListener(new View.OnClickListener() { 92@Override 93public void onClick(View v) { 94Intent intent = new Intent(MainActivity.this, AlarmBroadcastReceiver.class); 95intent.setAction("com.example.hxdn.naozhong"); 96PendingIntent operation = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 97MainActivity.this.alarmManager.cancel(operation); 98MainActivity.this.tv.setText("当前闹钟未设置"); 99Toast.makeText(MainActivity.this, "闹钟已删除!", Toast.LENGTH_SHORT).show(); 100} 101}); 102} 103 104public void init() { 105set = (Button) findViewById(R.id.set); 106cancle = (Button) findViewById(R.id.cancle); 107tv = (TextView) findViewById(R.id.tv); 108tp = (TimePicker) findViewById(R.id.tp); 109MainActivity.this.alarmManager = (AlarmManager) MainActivity.this.getSystemService(ALARM_SERVICE); 110} 111 112public void onStart() 113{ 114Log.i(TAG, "onStart() executed "); 115super.onStart(); 116} 117public void onPause() 118{ 119Log.i(TAG, "onPause() executed "); 120super.onPause(); 121 122} 123public void onDestroy() 124{ 125Log.i(TAG,"onDestroy() executed "); 126super.onDestroy(); 127} 128 }

AlarmActivity.java
1 package com.example.hxdn.naozhong; 2 3 import android.app.Activity; 4 import android.app.AlertDialog; 5 import android.content.Context; 6 import android.content.DialogInterface; 7 import android.os.Bundle; 8 import android.os.Vibrator; 9 import android.util.Log; 10 11 import java.text.SimpleDateFormat; 12 import java.util.Date; 13 14 /** 15* Created by hxdn on 2015/9/20. 16*/ 17 public class AlarmActivity extends Activity { 18private Vibrator vibrator=null; 19@Override 20protected void onCreate(Bundle savedInstanceState) 21{ 22super.onCreate(savedInstanceState); 23Log.i("MMM", "wocao1"); 24vibrator=(Vibrator)getSystemService(Context.VIBRATOR_SERVICE); 25long patten[]={100,800,100,800}; 26vibrator.vibrate(patten,2); 27Log.i("MMM","wocao2"); 28new AlertDialog.Builder(AlarmActivity.this).setIcon(R.mipmap.ic_launcher). 29setTitle("闹钟提醒"). 30setMessage("当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())) 31.setNegativeButton("关闭", new DialogInterface.OnClickListener() { 32@Override 33public void onClick(DialogInterface dialog, int which) { 34vibrator.cancel(); 35AlarmActivity.this.finish(); 36} 37}).show(); 38 39} 40 }


AlarmBroadCReceiver.java
package com.example.hxdn.naozhong; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; /** * Created by hxdn on 2015/9/20. */ public class AlarmBroadcastReceiver extends BroadcastReceiver {public void onReceive(Context context,Intent intent) { Intent intent1=new Intent(context,AlarmActivity.class); intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent1); } }

AndroidManifest.xml
1 2 4 5 10 12 13 14 17 18 19 20 21 22 23 26 27 28


【Android开发之闹钟】转载于:https://www.cnblogs.com/hsshy/p/4830176.html

    推荐阅读