«

简单的android闹钟

时间:2024-3-2 18:27     作者:韩俊     分类: Android


对service和date,Calendar的使用一直不是很熟练,今天做了一个简单的闹钟来练习一下,主要思路如下

1.设置日期(年月日),为了熟悉DatePickDialog的使用

2.设置时间(小时,分钟),为了熟悉TimePickDialog的使用(发现其实两个是一样的)

3.开始一个service,在service里面监听时间值,时间好了就使用MediaPlayer来播放

首先是MainActivity

package liuije.exercise.alarmclock;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.Intent;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends Activity {
    Activity tActivity;
    DatePickerDialog datePickerDialog;
    TimePickerDialog timePickerDialog;
    TextView t;
    Calendar at;
    Long time;
    boolean thi = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Calendar c = Calendar.getInstance();
        t = (TextView) findViewById(R.id.textView1);
        at = Calendar.getInstance();

        tActivity = this;
        datePickerDialog = new DatePickerDialog(this, new OnDateSetListener() {

            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear,
                    int dayOfMonth) {
                at.set(year, monthOfYear, dayOfMonth);
                t.append(new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA)
                        .format(at.getTime()));
            }
        }, c.get(Calendar.YEAR), c.get(Calendar.MONTH),
                c.get(Calendar.DAY_OF_MONTH));
        // 这里的year,monthofyear和dayofmonth是指出现时显示的时间,是int型的,
        // 但是指定的话需要转换,参数写2的话会出现三月,是因为java月份从0开始

        timePickerDialog = new TimePickerDialog(tActivity,
                new OnTimeSetListener() {

                    @Override
                    public void onTimeSet(TimePicker view, int hourOfDay,
                            int minute) {
                        t.append(hourOfDay + ":" + minute + "n");
                        at.set(Calendar.HOUR_OF_DAY, hourOfDay);
                        at.set(Calendar.MINUTE, minute);
                    }
                }, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), true);
    }

    public void setDate(View v) {
        datePickerDialog.show();
    }

    public void setTime(View v) {
        timePickerDialog.show();
    }

    public void start(View v) {
        Intent intent = new Intent();
        intent.putExtra("time", at.getTimeInMillis());
        // intent.putExtra("time", System.currentTimeMillis());
        thi = true;
        intent.setAction("startAlarmClock");
        tActivity.startService(intent);
    }

}

注意上面datePickDialog的使用,这个组件的事件处理函数返回的月份是比自然月少一的,是因为java的月份是从零开始的。

然后建立Service类,传入时间参数,判断时间到了之后启动闹钟,主要是用的handler和runnable的回调机制:

实现上述回调检查的方法是:首先new 一个handler,然后在一个runnable的run里面使用这个handlerpostdelay自身,然后使用handler的removeCallback可以除掉回调机制

package liuije.exercise.alarmclock;

import java.io.IOException;

import android.app.Service;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

public class ClockService extends Service {
    Long time;
    MediaPlayer alarm;

    public ClockService() {

    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        alarm = MediaPlayer.create(this, R.raw.alarm);
        AssetManager am = getAssets();
        AssetFileDescriptor afd = null;

        // try {
        // afd = am.openFd("alarm.mp3");
        // } catch (IOException e1) {
        // // TODO Auto-generated catch block
        // Log.d("服务", "mes");
        // e1.printStackTrace();
        // }
        // try {
        // alarm.setDataSource(afd.getFileDescriptor());
        // alarm.prepare();
        // } catch (IllegalStateException | IOException e) {
        // Log.d("服务", "me");
        // e.printStackTrace();
        // }
        Log.d("服务", "oncreate");
        final Handler h = new Handler();
        Runnable r = new Runnable() {
            @Override
            public void run() {
                Log.d("时间", "time");
                h.postDelayed(this, 1000);
                if (System.currentTimeMillis() > time) {
                    h.removeCallbacks(this);
                    alarm.start();
                }
            }
        };
        h.post(r);
        // alarm.start();
    }

    @Override
    @Deprecated
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);
        Log.d("服务", "start");
        time = intent.getLongExtra("time", System.currentTimeMillis());
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        Log.d("服务", "onDestroy");
        alarm.stop();
    }

}
service要在manifest里面注册,注册的时候可以指定开启的Action

  <service android:name=".ClockService" >
            <intent-filter>
                <action android:name="startAlarmClock" />
            </intent-filter>
        </service>
这样就实现了一个简单的闹钟,总结一下几个问题

1.Calendar的getInstance()就可以得到代表当前时间的一个Calendar的对象

2.Calendar的getTime可以返回Date对象,使用SimpleDateFormat可以格式化这个Date

3.SimpleDateFormat的初始化使用的是(String,Locale)两个构造函数的,这样的Locale可以传Locale.CHINA

4.在上面格式化输出的时候年必须传小写y,日期传大写D的话会出错,日期会显示那个是一年中的第几天,比如165天,传小写的就行

5.service使用Context的startService之后调用了Service的OnCreate和OnStart,

标签: android

热门推荐