有点不太明白大伙说的不能设置多个闹铃,为什么非要计算闹铃和当前时间的差值呢...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