各位好,又几天没见了,我是一个Android菜鸟,这几天项目要做个定时提醒业务,在网上看了很多资料,大多数都是关于AlarmManager去实现(虽然我个人觉得用它去实现不够强大,和健壮,但是没办法,短时间内我找不到更好的办法,毕竟开发工作才2个月不到,Android开发的朋友如果有更好的方法请告诉我),这几天由于事前很多,没写博客对学的东西进行总结,每天下来都是空空的,感觉没学到什么东西,很是恐慌。今天特意抽出时间来总结下。


一.首先我们先对AlarmManager讲解下

AlarmManager这个类实现系统警告服务,可以设定一个时间来完成指定的事情,只要在程序中设置了警报服务,就可以通过调用onReceive()方法执行你要做的事情,即使是待机状态,也不会影响运行。可以通过Context.getSystemService()方法来获得该服务。

代码如下:

AlarmManager mAlarmManager

1.公共方法


public void cancel (PendingIntent operation)

取消报警

 

public void set (int type, long triggerAtTime, PendingIntent operation)

设置警报

public void setInexactRepeating (int type, long triggerAtTime, long interval, PendingIntent operation)

设置不精准重复周期

不精准重复周期:有很多类似的警报,类型范围比较大的时候,这些警报就会合并为一个警报,这样可以不用每次都执行警报,是一种节能型

参数的意思

 

public void setRepeating (int type, long triggerAtTime, long interval, PendingIntent operation)

设置精准重复周期

这里有四个参数

第一个参数:即警报的类型,一般取值是AlarmManager.RTC和AlarmManager.RTC_WAKEUP,如果为RTC表示为一个正常的定时器,如果是RTC_WAKEUP则除了有定时器外还可以有震动或者响铃。另外就是RTC在手机睡眠的时候不发射警报,而RTC_WAKEUP则在睡眠的时候也会发射警报

第二个参数:第一次运行时要等待的时间,也就是执行延迟时间,单位是毫秒。例如:现在7点,你设置8点提醒,那么就是7点到8点的时差

第三个参数:表示执行的时间间隔,单位是毫秒,也就是每过多久发射一次警报,一般都是以天为单位

第四个参数:一个PendingIntent对象,即到时间后要执行的操作

public void setTime (long millis)

android.permission.SET_TIME)

 

public void setTimeZone (String timeZone)

android.permission.SET_TIME_ZONE)

2.Type

AlarmManager.RTC                  硬件闹钟,不唤醒手机(也可能是其它设备)休眠;当手机休眠时不发射闹钟。

AlarmManager.RTC_WAKEUP   硬件闹钟,当闹钟发躰时唤醒手机休眠;

AlarmManager.ELAPSED_REALTIME      真实时间流逝闹钟,不唤醒手机休眠;当手机休眠时不发射闹钟。

AlarmManager.ELAPSED_REALTIME_WAKEUP     真实时间流逝闹钟,当闹钟发躰时唤醒手机休眠;



3.PendingIntent 对象

在使用AlarmManager时一般都会用到PendingIntent,所以在这里进行扩展

PendingIntent与Intent和相似,Intent是意图的意思,想要做什么,而PendingIntent相对于它来说,就是计划将要做什么


代码和类的结构:

1.新建两个类,一个继承Activity,一个继承broadcastReceiver

代码详细:

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
<span style="white-space:pre">	</span><TimePicker android:id="@+id/timePicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <Button android:id="@+id/repeating_button"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/timePicker"
        android:text="设置重复闹铃" />

    <Button android:id="@+id/close_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="关闭"
            android:layout_below="@+id/repeating_button"
            android:layout_alignLeft="@+id/repeating_button" />

</RelativeLayout>

Activity代码

package com.example.Alarm;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast;

import java.util.Calendar;
import java.util.TimeZone;

public class MyActivity extends Activity implements TimePicker.OnTimeChangedListener,View.OnClickListener{

    private TimePicker mTimePicker;
    private Button mButton;
    private Button close_Button;

    private int mHour = -1;
    private int mMinute = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 初始化
        initView();
        // 获取当前时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8"));

        if(mHour == -1 && mMinute == -1) {
            mHour = calendar.get(Calendar.HOUR_OF_DAY);
            mMinute = calendar.get(Calendar.MINUTE);
        }
        mTimePicker.setCurrentHour(mHour);
        mTimePicker.setCurrentMinute(mMinute);

        mTimePicker.setOnTimeChangedListener(this);
        mButton.setOnClickListener(this);
        close_Button.setOnClickListener(this);
    }
    private void initView(){
        mTimePicker = (TimePicker)findViewById(R.id.timePicker);
        mButton = (Button)findViewById(R.id.repeating_button);
        close_Button= (Button) findViewById(R.id.close_button);

    }

    @Override
    public void onTimeChanged( TimePicker timePicker, int hour, int minute) {
        mHour = hour;
        mMinute = minute;
    }
    private PendingIntent sender;
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.repeating_button:
                Intent intent = new Intent(MyActivity.this, AlarmBroadcastReceiver.class);
                sender = PendingIntent.getBroadcast(MyActivity.this, 0, intent, 0);

                long firstTime = SystemClock.elapsedRealtime();  	// 开机之后到现在的运行时间(包括睡眠时间)
                long systemTime = System.currentTimeMillis();      //当前时间点

                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(System.currentTimeMillis());
                calendar.setTimeZone(TimeZone.getTimeZone("GMT+8")); // 设置时区,避免时区误差
                calendar.set(Calendar.MINUTE, mMinute);
                calendar.set(Calendar.HOUR_OF_DAY, mHour);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);

                // 选择的每天定时时间
                long selectTime = calendar.getTimeInMillis();

                // 如果当前时间大于设置的时间,那么就从第二天的设定时间开始
                if(systemTime > selectTime) {
                    Toast.makeText(MyActivity.this, "设置的时间小于当前时间", Toast.LENGTH_SHORT).show();
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                    selectTime = calendar.getTimeInMillis();
                }

                // 计算现在时间到设定时间的时间差
                long time = selectTime - systemTime;
                firstTime += time;

                // 进行闹铃注册
                AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
                manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                       5000, 24*60*60*1000,sender);
                Toast.makeText(MyActivity.this, "设置重复闹铃成功! ", Toast.LENGTH_LONG).show();
                break;
            case R.id.close_button:
                close();
                break;
        }
    }
    public  void close(){
        AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
        manager.cancel(sender);
        Toast.makeText(this,"关闭成功",Toast.LENGTH_LONG).show();
    }
}

broadcast代码

package com.example.Alarm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class AlarmBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
//我这里只是提醒,当然你可以做自己想要做的事
        Toast.makeText(context, "你设置的时间到了", Toast.LENGTH_LONG).show();
    }
}

以上是全部代码和解析,如有不对的地方还请指出,上面只是一个例子,了解之后可以实现不同的事情

(学习就是一个分享与探讨,大家一起努力)