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;
@Override
protected 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();//更改后进行保存
}
@Override
protected 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();
}
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass( MainActivity.this,
SetAlarmClock.class );
this.startActivityForResult( intent, 1 );
}
/**
* 双击退出
*/
private long FirstTime = 0;
@Override
public 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;
@Override
protected 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 );
}
}
} );
}
@Override
public 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 );//设置音乐循环播放
}
} );
}
/**
/**
/**
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;
}
@Override
public long getItemId(int position) {
return super.getItemId( position );
}
@Override
public AlarmItem getItem(int position) {
return super.getItem( position );
}
@Override
public 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
main.xml
alarm_item.xml
ring.xml