前言:
看過了不少安卓鬧鍾開發的例子,都是點到為止,都不完整,這次整一個看看。
一、鬧鍾的設置不需要數據庫,但是展示鬧鍾列表的時候需要,所以需要數據庫:

public class MySQLiteOpenHelper extends SQLiteOpenHelper{ public SQLiteDatabase sqlitedb; @SuppressLint("SdCardPath") public static String dbPath = "/sdcard/my.db"; public SQLiteDatabase init(){ Log.i("SD卡路徑", SdCardUtil.getSdPath()); File file = new File(dbPath); if(file.exists()){ Log.i("MySQLiteOpenHelper", "數據庫已存在"); } //調用此方法時,判斷數據庫是否存在,不存在則創建 調用OnCreate方法,存在則不調,直接放回數據庫對象 sqlitedb = this.getWritableDatabase(); return sqlitedb; } public MySQLiteOpenHelper(Context context) { super(context, dbPath, null, 1); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase){ }
二、鬧鍾列表需要有增刪查詢,改的問題再說:

public class ClockController { public static void createTable(SQLiteDatabase db){ db.execSQL("CREATE TABLE my_clock (" + " id varchar(16) primary key," + " clock_time varchar(16)," + " repeat_everyday varchar(2)," + " update_time varchar(16))"); } @SuppressLint("SimpleDateFormat") public static String addClock(String dateTime, MySQLiteOpenHelper dbOpenHelper) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); ContentValues values = new ContentValues(); String id = System.currentTimeMillis()+""; values.put("id", id); values.put("clock_time", dateTime); values.put("repeat_everyday","NO"); values.put("update_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); db.insert("my_clock", null, values); return id; } public static boolean deleteClock(Integer id,MySQLiteOpenHelper dbOpenHelper) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); db.delete("my_clock", "id=?", new String[] { id.toString() }); return true; } public static boolean updateClock(Integer id,String isRapeat,MySQLiteOpenHelper dbOpenHelper) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("repeat_everyday", isRapeat); db.update("my_clock", values,"id=?", new String[] { id.toString() }); return true; } public static List<MyClock> getClockList(String queryStr,String[] queryValues, MySQLiteOpenHelper dbOpenHelper){ SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); Cursor cursor = null; if(queryStr==null){ cursor = db.query("my_clock", null, null, null, null, null, null); } List<MyClock> clockList = new ArrayList<MyClock>(); while (cursor.moveToNext()) { clockList.add(new MyClock(cursor.getString(cursor.getColumnIndex("id")), cursor.getString(cursor.getColumnIndex("clock_time")), cursor.getString(cursor.getColumnIndex("repeat_everyday")), cursor.getString(cursor.getColumnIndex("update_time")))); } return clockList; } }
三、鬧鍾的增加即設置鬧鍾:
public class ClockActivity extends Activity{ AlarmManager alarmManager = null; Calendar calendar = Calendar.getInstance(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyApplication.getInstance().addActivity(this); setContentView(R.layout.activity_clock); alarmManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE); /* setRepeating(int type,long startTime,long intervalTime,PendingIntent pi); 該方法用於設置重復鬧鍾,第一個參數表示鬧鍾類型,第二個參數表示鬧鍾首次執行時間,第三個參數表示鬧鍾兩次執行的間隔時間,第三個參數表示鬧鍾響應動作。 */ queryMyClock(null); } public void setClock(View v){ queryMyClock(null); Toast.makeText(WeatherClockActivity.this, "設置鬧鍾", Toast.LENGTH_SHORT).show(); Dialog dialog = new TimePickerDialog(WeatherClockActivity.this, new OnTimeSetListener() { @Override public void onTimeSet(TimePicker timePicker, int hourOfDay, int minute) { Calendar c=Calendar.getInstance();//獲取日期對象 c.setTimeInMillis(System.currentTimeMillis()); //設置Calendar對象 c.set(Calendar.HOUR_OF_DAY, hourOfDay); //設置鬧鍾小時數 c.set(Calendar.MINUTE, minute); //設置鬧鍾的分鍾數 c.set(Calendar.SECOND, 0); //設置鬧鍾的秒數 c.set(Calendar.MILLISECOND, 0); //設置鬧鍾的毫秒數 MySQLiteOpenHelper sqLiteOpenHelper = new MySQLiteOpenHelper(getApplicationContext()); SQLiteDatabase database = sqLiteOpenHelper.init(); if(!DbUtils.tabIsExist("my_clock", sqLiteOpenHelper)){ ClockController.createTable(database); } //String id = ClockController.addClock(new SimpleDateFormat("HH:mm:dd").format(c.getTime()), sqLiteOpenHelper); Intent intent = new Intent(WeatherClockActivity.this, AlarmReceiver.class); //創建Intent對象 // intent.setFlags(Integer.parseInt(id));//作為取消時候的標識 PendingIntent pi = PendingIntent.getBroadcast(WeatherClockActivity.this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); //創建PendingIntent //設置一次性鬧鍾,第一個參數表示鬧鍾類型,第二個參數表示鬧鍾執行時間,第三個參數表示鬧鍾響應動作。 if(c.getTimeInMillis() < System.currentTimeMillis()){ Log.i("clock", "設置時間要推遲24小時,不然立刻會響"); alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis()+24*60*60*1000, pi); }else{ alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi); //設置鬧鍾,當前時間就喚醒 } queryMyClock(null); Toast.makeText(WeatherClockActivity.this, "鬧鍾設置成功", Toast.LENGTH_LONG).show();//提示用戶 } }, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false); dialog.show(); } public void queryMyClock(View v){ MySQLiteOpenHelper sqLiteOpenHelper = new MySQLiteOpenHelper(getApplicationContext()); SQLiteDatabase database = sqLiteOpenHelper.init(); if(!DbUtils.tabIsExist("my_clock", sqLiteOpenHelper)){ ClockController.createTable(database); } ListView listView = (ListView)findViewById(R.id.clocklist); SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(), getClockList(), R.layout.my_clock_list, new String[]{"clock_time",}, new int[]{R.id.my_clock}); listView.setAdapter(adapter); } public List<? extends Map<String, ?>> getClockList(){ MySQLiteOpenHelper db = new MySQLiteOpenHelper(this); List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); Map<String, Object> map = null; List<MyClock> clocks = ClockController.getClockList(null, null, db); for (MyClock myClock : clocks) { map = new HashMap<String, Object>(); map.put("clock_time", myClock.getClock_time()); list.add(map); } return list; } }
1、布局文件:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/setclock" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/setclock" android:onClick="setClock" android:layout_weight="1" /> </LinearLayout> <ListView android:id="@+id/clocklist" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="2dp" > </ListView> </LinearLayout>
2、首頁展示已設置過的鬧鍾列表:
1、首先需要判斷要查詢的表是否存在,不存在則需要創建,判斷表是否存在的方法如下:

public class DbUtils {
/**
* 判斷某張表是否存在
* @param tabName 表名
* @return
*/
public static boolean tabIsExist(String tabName,MySQLiteOpenHelper dbHelper){
boolean result = false;
if(tabName == null){
return false;
}
SQLiteDatabase db = null;
Cursor cursor = null;
try {
db = dbHelper.getReadableDatabase();//此this是繼承SQLiteOpenHelper類得到的
String sql = "select count(*) as c from sqlite_master where type ='table' and name ='"+tabName.trim()+"'";
cursor = db.rawQuery(sql, null);
if(cursor.moveToNext()){
int count = cursor.getInt(0);
if(count>0){
result = true;
}
}
} catch (Exception e) {
LogUtil.initData("判斷表是否存在出現異常", "log.txt");
}
return result;
}
2、列表的展示選擇使用適配器,以上代碼使用第一種方法:
SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(), getClockList(), R.layout.my_clock_list, new String[]{"clock_time",}, new int[]{R.id.my_clock});
getClockList方法返回的是一個List類型,將一個Map類型放置其中,通過key值去填充不同view。具體看代碼實現!
適配ListView的布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/my_clock" android:layout_height="wrap_content" android:layout_width="match_parent" /> </LinearLayout>
另外,適配器還有第二種實現:以下是一個例子,與此代碼無關

public class MyAdapter extends BaseAdapter{ public List<Object> list; public Context context; public WearthAdapter(List<Object> list,Context context) { this.list = list; this.context = context; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View view, ViewGroup parent) { TextView t1 = null,t2=null,t3=null,t4=null,t5=null; if(view==null){ view = LayoutInflater.from(context).inflate(R.layout.weather_day, parent); t1 = (TextView)findViewById(R.id.w_day); t2 = (TextView)findViewById(R.id.w_cond); t3 = (TextView)findViewById(R.id.w_wind); t4 = (TextView)findViewById(R.id.max_tmp); t5 = (TextView)findViewById(R.id.min_tmp); } t1.setText("1"); t2.setText("2"); t3.setText("3"); t4.setText("4"); t5.setText("5"); return view; } }
3、鬧鍾的設置:
調用TimePickerDialog實現,這是一個時間選擇器,通過監聽其選擇的時間進行鬧鍾設置;
鬧鍾設置的主要代碼如下:
1.獲取系統服務:
alarmManager=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
2. 創建PendingIntent,其中AlarmReceiver.class是鬧鍾觸發的實現動作。
Intent intent = new Intent(ClockActivity.this, AlarmReceiver.class); //創建Intent對象
PendingIntent pi = PendingIntent.getBroadcast(WeatherClockActivity.this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
3、 //設置鬧鍾,當前時間就喚醒
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);
4、鬧鍾觸發是震動和響鈴,在 AlarmReceiver中實現:

import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.media.AudioManager; import android.os.Vibrator; import android.util.Log; public class AlarmReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Log.i("clock", "鬧鍾響了........"); Vibrator vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE); vibrator.vibrate(10000); AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); audioManager.setStreamVolume(AudioManager.RINGER_MODE_NORMAL, 5, 0); } }
結束語:
有待改進!