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 (Y
    1){
    mediaPlayer = MediaPlayer.create( this, R.raw.b );
    }else if (Y2){
    mediaPlayer = MediaPlayer.create( this, R.raw.c );
    }else if (Y
    3){
    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"?>

更多相关文章

  1. Android呼出电话流程(原)
  2. SharePreferences
  3. Android学习 之 Activity和Window之间的关系
  4. android得到已安装和未安装apk的信息
  5. 一个侧屏滑动操作的实例(仿遇见)之三:代码分析
  6. android 中 intent 重点
  7. Android(安卓)滑动悬浮置顶指南
  8. greenDao框架使用心得
  9. [置顶] [Android基础]Android中如何使用Intent传递对象

随机推荐

  1. RelativeLayout参数意义
  2. [Android UI] Activity Maintheme (Andro
  3. Android RatingBar自定义替换系统图片
  4. Android(安卓)声明自身为应用市场
  5. [1] Android主要源代码组成
  6. Android SDK 国内镜像
  7. Android P窗口机制之Window加载流程
  8. shape 的使用xml
  9. asdsad
  10. 从零开始学习Android开发