有点不太明白大伙说的不能设置多个闹铃,为什么非要计算闹铃和当前时间的差值呢...android闹铃给了我们个误区啊!
上一篇的闹铃多个是可以的哇,这不就设置了多个呢
接着上一篇内容直接改的:安卓系统没有塞班那么牛K,关机是没有闹铃的,而且开机后闹铃也是需要重新设置的,我们需要做的事就是设置闹铃的时候存起来,开机之后取出来.
下面来分析下我们该怎么去完成这个功能:
1.首先要准备好一个数据库.
2.开机广播监听,重新设置即可
简单吧,现在来看下:
开机广播类AlarmInitReceiver:
package com.glacier.demo;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import com.glacier.db.DbHelper;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
/**
* 开机重新设置闹铃广播
* @author wangyubin
*
*/
public class AlarmInitReceiver extends BroadcastReceiver {
Cursor cursor;
private Calendar calendar;
@Override
public void onReceive(Context context, Intent intent1) {
// TODO Auto-generated method stub
String action = intent1.getAction();
//如果是开机广播的话就重新设计闹铃
if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
setAlarmTime(context);
}
}
/**
* 重新设置内容
* @param context 上下文
*/
private void setAlarmTime(Context context) {
calendar = Calendar.getInstance();
// 得到当前时间并设置到日历里面
calendar.setTimeInMillis(System.currentTimeMillis());
DbHelper dbHelper = new DbHelper(context);
Date date = new Date();
//查询数据库存储的闹铃
cursor = dbHelper.query();
while (cursor.moveToNext()) {
String timer = cursor.getString(0);
System.out.println(timer);
try {
if (ConverToDate(timer).getTime() > date.getTime()) {
System.out.println(timer.split(" ")[0].split("-")[0] + "/"
+ timer.split(" ")[0].split("-")[1] + "/"
+ timer.split(" ")[0].split("-")[2] + " "
+ timer.split(" ")[1].split(":")[0] + ":"
+ timer.split(" ")[1].split(":")[1]);
//这边读取年月日时分,也可以读取存进来的long值
calendar.set(
Integer.valueOf(timer.split(" ")[0].split("-")[0]),
Integer.valueOf(timer.split(" ")[0].split("-")[1])-1,
Integer.valueOf(timer.split(" ")[0].split("-")[2]),
Integer.valueOf(timer.split(" ")[1].split(":")[0]),
Integer.valueOf(timer.split(" ")[1].split(":")[1]),
0);
Intent intent = new Intent(context, AlamrReceiver.class);
// 设置intent的动作,识别当前设置的是哪一个闹铃,有利于管理闹铃的关闭
intent.setAction(timer);
// 用广播管理闹铃
PendingIntent pi = PendingIntent.getBroadcast(context, 0,
intent, 0);
// 获取闹铃管理
AlarmManager am = (AlarmManager) context
.getSystemService(Activity.ALARM_SERVICE);
// 设置闹钟
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
pi);
// 设置闹钟重复时间
am.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 10 * 1000, pi);
} else {
//过期的闹铃将不进行设置(可以重数据库中删除)
dbHelper.delete(timer);
System.out.println("当前这个闹铃已过期");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(null!=cursor){
cursor.close();
}
if(null!=dbHelper){
dbHelper.close();
}
}
public static Date ConverToDate(String strDate) throws Exception {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");
return df.parse(strDate);
}
}
闹铃储存帮助类DbHelper:
package com.glacier.db;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* 闹铃储存帮助类
* @author wangyubin
*
*/
public class DbHelper extends SQLiteOpenHelper {
private final static String DB_NAME = "alarm.db";
private final static int DB_VERSION = 1;
private SQLiteDatabase database;
private Cursor cursor;
/**
* 主数据库
*
* @param context
*/
public DbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE IF NOT EXISTS " + "ALARM" + "("
+ "ID VARCHAR(20)," + "DATE TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
/**
* 判断是否存在
*
* @param id
* @return
*/
public boolean isExist(String id) {
database = getReadableDatabase();
cursor = database.query("ALARM", new String[] { "ID" }, "ID like ?",
new String[] { id }, null, null, null);
return cursor.moveToNext();
}
/**
* 查询所有数据
*
* @return
*/
public Cursor query() {
database = getReadableDatabase();
cursor = database.query("ALARM", null, null, null, null, null, null);
return cursor;
}
/**
* 删除数据
*
* @param id
*/
public void delete(String i
1.系统消息
MSG_IDLE------Minigui窗口空闲无事件发生的时候,会一直不停的发送该消息给主窗口
MSG_TIMER----定时器消息,如果系统在MSG_CREATE建立窗口的时候创建了一个定时器SetTImer(hWnd,id,10ms*number),那么会根据设定的时间,一到时间就会发送该消息过来,可以利用这个来进行看门狗的复位.
MSG_FDEVENT-----文件描述符监视
2.对话框消息:
MSG_COMMAND-----
MSG_INITDIALOG----
MSG_ISDIALOD----
MSG_SETTEXT
MSG_GETTEXT
MSG_FONTCHANGED
3.窗口绘制消息:
MSG_PAINT--------该消息在需要进行窗口重绘的时发送到窗口过程,书上说要用return 0,不要break;但是我测试的时候发现还是要用break;不然会一直打印该消息,如果该消息中包含了InvalidataRect(TRUE),重置了无效区域,那么该消息也会产生,并且还会产生MSG_ERASEBKGND消息。这样我们就能够更新窗口的背景图片了。
MSG_ERASEBKGND-----更新窗口背景图片,只要有InvalidataRect()重置了无效区域的时候,才会发送该消息,和MSG_PAINT一样。
顺序是:定义了InvalidataRect()无效区域----->处理MSG_ERASEBKGND----->重绘窗口MSG_PAINT-->重绘结束.
4.窗口创建和销毁消息:
MSG_CREATE----该主窗口一开始创建好的时候会发送该消息过来,表示主窗口创建好了
MSG_NCCREATE----
MSG_DISTROY-----
MSG_CLOSE------
5.键盘和鼠标的消息:
MSG_CHAR-----
MSG_LBUTTONDOWN----鼠标左键按下,可以模拟触摸屏
MSG_LBUTTONUP---------鼠标左键释放
MSG_MOUSEMOVE-------
6.鼠标或键盘后处理消息:
MSG_KILLFOCUS----
MSG_MOUSEMOVEIN----
MSG_SETCURSOR-----
MSG_SETFOCUS------
效果图由于网站占时不能上传,以后补上。
NinePointLineView.java
import org.demo.utils.MLog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class NinePointLineView extends View {
Paint linePaint = new Paint();
Paint whiteLinePaint = new Paint();
Paint textPaint = new Paint();
// 由于两个图片都是正方形,所以获取一个长度就行了
Bitmap defaultBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.lock);
int defaultBitmapRadius = defaultBitmap.getWidth() / 2;
// 初始化被选中图片的直径、半径
Bitmap selectedBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.indicator_lock_area);
int selectedBitmapDiameter = selectedBitmap.getWidth();
int selectedBitmapRadius = selectedBitmapDiameter / 2;
// 定义好9个点的数组
PointInfo[] points = new PointInfo[9];
// 相应ACTION_DOWN的那个点
PointInfo startPoint = null;
// 屏幕的宽高
int width, height;
// 当ACTION_MOVE时获取的X,Y坐标
int moveX, moveY;
// 是否发生ACTION_UP
boolean isUp = false;
// 最终生成的用户锁序列
StringBuffer lockString = new StringBuffer();
public NinePointLineView(Context context) {
super(context);
this.setBackgroundColor(Color.WHITE);
initPaint();
}
public NinePointLineView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setBackgroundColor(Color.WHITE);
initPaint();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
MLog.i("onMeasure");
// 初始化屏幕大小
width = getWidth();
height = getHeight();
if (width != 0 && height != 0) {
initPoints(points);
}
MLog.i("width、height = " + width + "、" + height);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
MLog.i("onLayout");
super.onLayout(changed, left, top, right, bottom);
}
private int startX = 0, startY = 0;
@Override
protected void onDraw(Canvas canvas) {
canvas.drawText("用户的滑动顺序:" + lockString, 0, 40, textPaint);
if (moveX != 0 && moveY != 0 && startX != 0 && startY != 0) {
// 绘制当前活动的线段
drawLine(canvas, startX, startY, moveX, moveY);
}
drawNinePoint(canvas);
super.onDraw(canvas);
}
// 记住,这个DOWN和MOVE、UP是成对的,如果没从UP释放,就不会再获得DOWN;
// 而获得DOWN时,一定要确认消费该事件,否则MOVE和UP不会被这个View的onTouchEvent接收
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean flag = true;
if (isUp) {// 如果已滑完,重置每个点的属性和lockString
finishDraw();
// 当UP后,要返回false,把事件释放给系统,否则无法获得Down事件
flag = false;
} else {// 没滑完,则继续绘制
handlingEvent(event);
// 这里要返回true,代表该View消耗此事件,否则不会收到MOVE和UP事件
flag = true