简单实现 Android 闹钟

Android 闹钟

比如:一次闹钟响过之后开关变为关的状态;直接点击开关不能实现开关闹钟的作用,需要在点击item的菜单中进行更改;未知原因闹钟不准时,不能及时响应,求大神讲解
简单实现 Android 闹钟_第1张图片
简单实现 Android 闹钟_第2张图片

话不多说,看代码

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 (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;
}

@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


你可能感兴趣的:(简单实现 Android 闹钟)