简单实现 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<AlarmItem> adapterList = new ArrayList<AlarmItem>(); 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() {@Overridepublic 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() {@Overridepublic 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( ":", "" );//將當前時間中的":"替換為""即為idadapter.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() {@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {kai=isChecked;}} );timePicker.setOnTimeChangedListener( new TimePicker.OnTimeChangedListener() {@Overridepublic 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 );
}
}
} );
}
}
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
*/
/**
-
要實現手指在屏幕上左右滑動的事件需要實例化對象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<AlarmItem> 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
<?xml version="1.0" encoding="utf-8"?> <LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ImageButtonandroid:id="@+id/cancel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/cross_48px" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_weight="1"android:gravity="center"android:text="鬧鐘設置"android:textSize="25dp" /><ImageButtonandroid:id="@+id/duigou"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/check_48px" /> </LinearLayout><TimePickerandroid:id="@+id/timePicker"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:timePickerMode="spinner" /><LinearLayoutandroid:id="@+id/layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:background="@drawable/boder"android:layout_marginTop="80dp"><TextViewandroid:id="@+id/repetition"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="left"android:paddingLeft="30dp"android:text="重復"android:textSize="30dp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1" /><TextViewandroid:id="@+id/textRepetition"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="30dp"android:textSize="30dp"android:text=">"/> </LinearLayout> <LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:background="@drawable/boder"android:layout_marginTop="30dp"><TextViewandroid:id="@+id/kaiqi"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="left"android:paddingLeft="30dp"android:text="開啟"android:textSize="30dp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1" /><Switchandroid:id="@+id/open1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="true"android:layout_marginTop="5dp"android:layout_marginRight="30dp"/> </LinearLayout>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"?> <TimePickerandroid:id="@+id/time"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginTop="100dp"android:gravity="center"></TimePicker>總結
以上是生活随笔為你收集整理的简单实现 Android 闹钟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式【2.1】-- 简单工厂模式怎么
- 下一篇: Redisson(1)分布式锁——如何解