简单实现 Android(安卓)闹钟
Android 闹钟
比如:一次闹钟响过之后开关变为关的状态;直接点击开关不能实现开关闹钟的作用,需要在点击item的菜单中进行更改;未知原因闹钟不准时,不能及时响应,求大神讲解
话不多说,看代码
MainActivity
import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class MainActivity extends Activity implements View.OnClickListener {
private ImageButton add;private ListView alarm;private Switch open;private Boolean kai;public String aaa;public String clockTime;public int id;private String myhour;private String myminute;private List adapterList = new ArrayList();public AlarmItemAdapter adapter;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate( savedInstanceState ); setContentView( R.layout.main ); init(); adapter = new AlarmItemAdapter( this, R.layout.alarm_item, adapterList ); alarm.setAdapter( adapter );//关联适配器 readSavedAlarmList();//读取闹钟列表}private void init() { add = (ImageButton) findViewById( R.id.add ); alarm = (ListView) findViewById( R.id.alarm ); add.setOnClickListener( this ); alarm.setOnItemClickListener( new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, final int position, long id) { ShowListItem( position ); } } );}public void ShowListView() { if (aaa != null && clockTime != null) { AlarmItem alarmItem = new AlarmItem( aaa, clockTime, kai ); adapterList.add( alarmItem ); adapter.notifyDataSetChanged(); //通知数据集更改 int id = Integer.parseInt( myhour + myminute ); // id为当前设置闹钟的时间 openAlarm( id ); saveAlarmList();//保存闹钟列表 }}private void openAlarm(int id) { AlarmManager alarmManager = (AlarmManager) getSystemService( ALARM_SERVICE ); PendingIntent pi = PendingIntent.getBroadcast( MainActivity.this, id, new Intent( MainActivity.this, AlarmReceiver.class ), 0 ); Toast.makeText( this, String.valueOf( id ), Toast.LENGTH_SHORT ).show(); Calendar c = Calendar.getInstance(); c.setTimeInMillis( System.currentTimeMillis() ); c.set( Calendar.HOUR_OF_DAY, Integer.parseInt( myhour ) ); c.set( Calendar.MINUTE, Integer.parseInt( myminute ) ); if (kai.equals( true )) { if (aaa.equals( "只响一次" )) { if (c.getTimeInMillis() > System.currentTimeMillis()) {//获取时间大于当前时间,按设置事件进行闹钟 alarmManager.set( AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi ); } else {//否则,第二天这个时间进行闹钟 alarmManager.set( AlarmManager.RTC_WAKEUP, c.getTimeInMillis() + 24 * 60 * 60 * 1000, pi ); } } else if (aaa.equals( "每天" )) { alarmManager.setRepeating( AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), 24 * 60 * 60 * 1000, pi ); } }}public void ShowListItem(final int position) { AlertDialog.Builder builder = new AlertDialog.Builder( this ); builder.setTitle( "操作选项" ); builder.setItems( new CharSequence[]{"删除闹钟", "开启/关闭闹钟"}, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case 0: deleteAlarm( position ); break; case 1: switchAlarm( position ); break; } } } ); builder.show();}private void switchAlarm(final int position) { open = (Switch) findViewById( R.id.open ); if (adapter.getItem( position ).getKai() == false) { adapter.getItem( position ).setKai( true ); //开启闹钟 int id = Integer.parseInt( adapter.getItem( position ).getClock().replace( ":", "" ) ); //开关为开的情况下设置闹钟,id相同会覆盖掉之前的 AlarmManager alarmManager = (AlarmManager) getSystemService( ALARM_SERVICE ); PendingIntent pi = PendingIntent.getBroadcast( MainActivity.this, id, new Intent( MainActivity.this, AlarmReceiver.class ), 0 ); Calendar c = Calendar.getInstance(); c.setTimeInMillis( System.currentTimeMillis() ); String hour= String.valueOf(adapter.getItem( position ).getClock().charAt( 0 )) + adapter.getItem( position ).getClock().charAt( 1 ) ; String minute=String.valueOf( adapter.getItem( position ).getClock().charAt( 3 ) )+adapter.getItem( position ).getClock().charAt( 4 ); Toast.makeText( this, "hour"+hour+"miute"+minute, Toast.LENGTH_SHORT ).show(); c.set( Calendar.HOUR_OF_DAY, Integer.parseInt( hour ) ); c.set( Calendar.MINUTE, Integer.parseInt( minute ) ); if (kai.equals( true )) { if (aaa.equals( "只响一次" )) { if (c.getTimeInMillis() > System.currentTimeMillis()) {//获取时间大于当前时间,按设置事件进行闹钟 alarmManager.set( AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi ); } else {//否则,第二天这个时间进行闹钟 alarmManager.set( AlarmManager.RTC_WAKEUP, c.getTimeInMillis() + 24 * 60 * 60 * 1000, pi ); } } else if (aaa.equals( "每天" )) { alarmManager.setRepeating( AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), 24 * 60 * 60 * 1000, pi ); } } } else { adapter.getItem( position ).setKai( false ); // 关闭闹钟 int id = Integer.parseInt( adapter.getItem( position ).getClock().replace( ":", "" ) ); //开关为关的情况下取消闹钟 AlarmManager alarmManager = (AlarmManager) getSystemService( ALARM_SERVICE ); PendingIntent sender = PendingIntent.getBroadcast ( MainActivity.this, id, new Intent( MainActivity.this, AlarmReceiver.class ), 0 ); alarmManager.cancel( sender ); } adapter.notifyDataSetChanged(); //通知数据集更改 saveAlarmList();//更改后进行保存}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {//从SetAlarmClock返回执行 super.onActivityResult( requestCode, resultCode, data ); aaa = data.getExtras().getString( "重复" ); myhour = data.getExtras().getString( "hour" ); myminute = data.getExtras().getString( "minute" ); kai = data.getExtras().getBoolean( "kaiqi" ); clockTime = myhour + ":" + myminute; ShowListView();}@Overridepublic void onClick(View v) { Intent intent = new Intent(); intent.setClass( MainActivity.this, SetAlarmClock.class ); this.startActivityForResult( intent, 1 );}/** * 双击退出 */private long FirstTime = 0;@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { long Time = System.currentTimeMillis(); if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { if (Time - FirstTime > 2000) { Toast.makeText( this, "再按一次退出程序", Toast.LENGTH_SHORT ).show(); FirstTime = System.currentTimeMillis(); } else { finish(); System.exit( 0 ); } return true; } return super.onKeyDown( keyCode, event );}/** * 保存闹钟列表 */public void saveAlarmList() { SharedPreferences.Editor editor = getSharedPreferences( "alarmClock", Context.MODE_PRIVATE ).edit(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < adapter.getCount(); i++) { sb.append( adapter.getItem( i ).getWeek() + "/" + adapter.getItem( i ).getClock() + "/" + adapter.getItem( i ).getKai() ).append( "," ); } if (sb.length() > 1) { String content = sb.toString().substring( 0, sb.length() - 1 ); // 去掉最后一个逗号 editor.putString( "clock", content ); } else { // 如果长度为空,也要提交一个空的上去 editor.putString( "clock", null ); } // 记得提交 editor.commit();}/** * 读取闹钟列表 */private void readSavedAlarmList() { // 实例化共享首选项 SharedPreferences sp = getSharedPreferences( "alarmClock", Context.MODE_PRIVATE ); String content = sp.getString( "clock", null ); if (content != null) { String[] timeStrings = content.split( "," ); // 遍历每一个字符串,并将其添加到适配器中 for (String s : timeStrings) { if (timeStrings != null) { String[] myclock = s.split( "/" ); String chongfu = myclock[0]; String shijian = myclock[1]; boolean b = Boolean.parseBoolean( myclock[2] ); AlarmItem alarmItem = new AlarmItem( chongfu, shijian, b ); adapter.add( alarmItem ); } } }}private void deleteAlarm(int position) { AlarmItem al = adapter.getItem( position ); String id = adapter.getItem( position ).getClock().replace( ":", "" );//将当前时间中的":"替换为""即为id adapter.remove( al ); saveAlarmList();//删除闹钟之后进行保存 AlarmManager alarmManager = (AlarmManager) getSystemService( ALARM_SERVICE ); PendingIntent sender = PendingIntent.getBroadcast ( MainActivity.this, Integer.parseInt( id ), new Intent( MainActivity.this, AlarmReceiver.class ), 0 ); alarmManager.cancel( sender );}
}
SetAlarmClock
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
public class SetAlarmClock extends AppCompatActivity implements View.OnClickListener {
private ImageButton cancel,duigou;private LinearLayout layout;private TextView textView;private TimePicker timePicker;private Switch open;public String aaa;//获取重复时间private Boolean kai=true;//获取是否开启闹钟private String myhour,myminute;@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate( savedInstanceState ); setContentView( R.layout.set_alarm_clock ); init();}private void init() { cancel=(ImageButton)findViewById( R.id.cancel ); duigou=(ImageButton)findViewById( R.id.duigou ); timePicker=(TimePicker)findViewById( R.id.timePicker ); layout=(LinearLayout) findViewById( R.id.layout ); textView=(TextView)findViewById( R.id.textRepetition ); open=(Switch)findViewById( R.id.open1 ); cancel.setOnClickListener( this ); duigou.setOnClickListener( this ); layout.setOnClickListener( this ); timePicker.setIs24HourView( true ); open.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { kai=isChecked; } } ); timePicker.setOnTimeChangedListener( new TimePicker.OnTimeChangedListener() { @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { if (hourOfDay<10){ myhour="0"+hourOfDay; }else { myhour= String.valueOf( hourOfDay ); } if (minute<10){
// clockTime=hourOfDay+":"+“0”+minute;
myminute=“0”+minute;
}else {
// clockTime = hourOfDay + “:” + minute;
myminute=String.valueOf( minute );
}
}
} );
}
@Overridepublic void onClick(View v) { switch (v.getId()){ case R.id.cancel: Intent intent1= new Intent(); intent1.setClass( this,MainActivity.class ); startActivity( intent1 ); break; case R.id.duigou: if (myhour==null && myminute==null){ Toast.makeText( this, "请设置闹钟时间",Toast.LENGTH_LONG).show(); return; }else if(aaa==null) { Toast.makeText( this, "请设置闹钟重复",Toast.LENGTH_LONG).show(); return; }else { Intent intent=getIntent(); intent.putExtra( "重复",aaa ); intent.putExtra( "hour",myhour); intent.putExtra( "minute",myminute); intent.putExtra( "kaiqi",kai ); setResult( 2,intent ); finish(); } break; case R.id.layout: final AlertDialog.Builder builder=new AlertDialog.Builder( this); final String[] data = new String[]{"只响一次","每天"}; builder.setTitle("重复"); builder.setItems( data, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { textView.setText( data[which] ); aaa=textView.getText().toString(); } } ); builder.show(); break; default: break; }}
}
RingActivity
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.Random;
public class RingActivity extends AppCompatActivity {
/**
* 进入页面响铃,进入当前界面播放音乐
* 手势滑动关闭当前Activity
* 步骤,
* a、实例化GestureDetector对象
* b、实例化 GestureDetector.OnGestureListener 手势监听对象
* c、覆写onTouchEvent方法,在onTouchEvent方法中将event对象传给gestureDetector.onTouchEvent(event);处理。
* @param savedInstanceState
*/
final int Right =0;final int Left =1;private GestureDetector gestureDetector;//要想使用滑动手势必须要GestureDetector对向private TimePicker timePicker;private MediaPlayer mediaPlayer;
/**
-
要实现手指在屏幕上左右滑动的事件需要实例化对象GestureDetector,new GestureDetector(MainActivity.this,onGestureListener);
-
首先实现监听对象GestureDetector.OnGestureListener,根据x或y轴前后变化坐标来判断是左滑动还是右滑动
-
并根据不同手势滑动做出事件处理doResult(int action),
然后覆写onTouchEvent方法,在onTouchEvent方法中将event对象传给gestureDetector.onTouchEvent(event);处理。
*/@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
// requestWindowFeature( Window.FEATURE_NO_TITLE);//去除顶部通知栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
/标题是属于View的,所以窗口所有的修饰部分被隐藏后标题依然有效,需要去掉标题/
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView( R.layout.ring );
music();
timePicker=(TimePicker)findViewById( R.id.time ) ;
timePicker.setEnabled( false );
gestureDetector=new GestureDetector( this, onGestureListener );
}private void music() {
Random random=new Random();
int Y=random.nextInt(5);
if (Y0) {
mediaPlayer = MediaPlayer.create( this, R.raw.a );
}else if (Y1){
mediaPlayer = MediaPlayer.create( this, R.raw.b );
}else if (Y2){
mediaPlayer = MediaPlayer.create( this, R.raw.c );
}else if (Y3){
mediaPlayer = MediaPlayer.create( this, R.raw.d );
}else {
mediaPlayer = MediaPlayer.create( this, R.raw.e );
}
mediaPlayer.start();//开始播放音乐
mediaPlayer.setOnCompletionListener( new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.start();
mediaPlayer.setLooping( true );//设置音乐循环播放
}
} );
}
/**- //需要传入一个Context和一个手势监听OnGestureListener
- //下面是源码
public GestureDetector(Context context, OnGestureListener listener) {
this(context, listener, null);
}
*/
/**
- 在此实例化OnGestureListener监听的实例
*/
private GestureDetector.OnGestureListener onGestureListener =
new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
//e1就是初始状态的MotionEvent对象,e2就是滑动了过后的MotionEvent对象
//velocityX和velocityY就是滑动的速率
float x = e2.getX() - e1.getX();
//滑动后的x值减去滑动前的x值 就是滑动的横向水平距离(x)
// float y = e2.getY() - e1.getY();//滑动后的y值减去滑动前的y值 就是滑动的纵向垂直距离(y)
//如果滑动的横向距离大于100,表明是右滑了,那么就执行下面的方法,可以是关闭当前的activity
if (x > 500) {
doResult(Right);
}
//如果滑动的横向距离大于500,表明是左滑了(因为左滑为负数,所以距离大于500就是x值小于-500)
if (x < -500) {
doResult(Left);
}
return true;
}
};
/**
- 将MotionEvent事件处理交给gestureDetector对象
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
Toast.makeText(this,“向右滑动关闭闹铃”,Toast.LENGTH_LONG).show();//手指从屏幕抬起了
break;
default:
break;
}
return gestureDetector.onTouchEvent(event);
}
public void doResult(int action) {
switch (action) { case Right: finish(); mediaPlayer.stop(); break; default: break; }
}
}
AlarmItemAdapter
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import java.util.List;
public class AlarmItemAdapter extends ArrayAdapter {
private int resourceId;public AlarmItemAdapter(Context context, int resource, List objects) { super( context, resource, objects ); this.resourceId=resource;}@Overridepublic long getItemId(int position) { return super.getItemId( position );}@Overridepublic AlarmItem getItem(int position) { return super.getItem( position );}@Overridepublic View getView(final int position, View convertView, ViewGroup parent) { AlarmItem alarmItem =getItem( position ); View view; final ViewHolder viewHolder; if (convertView==null){ view= LayoutInflater.from( getContext() ).inflate( this.resourceId,null ); viewHolder=new ViewHolder(); viewHolder.colock=(TextView) view.findViewById( R.id.colock ); viewHolder.week=(TextView)view.findViewById( R.id.week ); viewHolder.kai=(Switch)view.findViewById( R.id.open ); view.setTag( viewHolder );//将viewHolder对象存储在view }else { view=convertView; viewHolder=(ViewHolder)view.getTag();//重新获取viewHolder } viewHolder.week.setText( alarmItem.getWeek() ); viewHolder.colock.setText( alarmItem.getClock() ); viewHolder.kai.setChecked( alarmItem.getKai() );
// viewHolder.kai.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
// @Override
// public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//// callSwitch.click( position,isChecked );
// viewHolder.kai.setChecked( isChecked );
// MainActivity.saveAlarmList();
// }
// } );
return view;
}
class ViewHolder{
TextView week;
TextView colock;
Switch kai;
}
// public interface CallSwitch{
// void click( int position ,boolean isChecked);
// }
// private CallSwitch callSwitch;
// public void setCallSwitch(CallSwitch callSwitch){
// this.callSwitch=callSwitch;
// }
}
AlarmItem
/**
-
用来存储子项数据
*/
public class AlarmItem {
private String week;
private String clock;
private Boolean kai;public AlarmItem(String week, String clock , Boolean kai){
this.week=week;
this.clock=clock;
this.kai=kai;
}public void setKai(Boolean kai) {
this.kai = kai;
}public String getWeek(){
return this.week;
}
public String getClock(){
return this.clock;
}
public Boolean getKai(){
return this.kai;
}
}
AlarmReceiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
intent = new Intent( context, RingActivity.class );
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
context.startActivity( intent );
}
}
接下来就是布局文件了
set_alarm_clock.xml
<?xml version="1.0" encoding="utf-8"?>
main.xml
<?xml version="1.0" encoding="utf-8"?>
alarm_item.xml
<?xml version="1.0" encoding="utf-8"?>
ring.xml
<?xml version="1.0" encoding="utf-8"?>
更多相关文章
- Android呼出电话流程(原)
- SharePreferences
- Android学习 之 Activity和Window之间的关系
- android得到已安装和未安装apk的信息
- 一个侧屏滑动操作的实例(仿遇见)之三:代码分析
- android 中 intent 重点
- Android(安卓)滑动悬浮置顶指南
- greenDao框架使用心得
- [置顶] [Android基础]Android中如何使用Intent传递对象