前言:

看过了不少安卓闹钟开发的例子,都是点到为止,都不完整,这次整一个看看。

一、闹钟的设置不需要数据库,但是展示闹钟列表的时候需要,所以需要数据库:

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;
}

DbUtils.java

  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;
} }

MyAdapter.java

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); }
}

AlarmReceiver.java

结束语:

有待改进!

Android闹钟开发与展示Demo的更多相关文章

  1. Android UI开发第四十一篇——墨迹天气3.0引导界面及动画实现

    周末升级了墨迹天气,看着引导界面做的不错,模仿一下,可能与原作者的代码实现不一样,但是实现的效果还是差不多的.先分享一篇以前的文章,android动画的基础知识,<Android UI开发第十二 ...

  2. Android应用开发-小巫CSDN博客client之嵌入有米广告

    Android应用开发-小巫CSDN博客client之嵌入有米广告 上一篇博客给大家介绍怎样集成友盟社会化组件,本篇继续带来干货,教大家怎样嵌入广告到应用中去.小巫自称专业对接30年,熟悉各大渠道SD ...

  3. Android实战开发租赁管理软件(适配UI,数据的存储,多线程下载)课程分享

    亲爱的网友,我这里有套课程想和大家分享,假设对这个课程有兴趣的,能够加我的QQ2059055336和我联系. 课程内容简单介绍 我们软件是基于移动设备的.所以我们必定的选择了安卓作为我们的开发工具.课 ...

  4. 【Android 应用开发】GitHub 优秀的 Android 开源项目

    原文地址为http://www.trinea.cn/android/android-open-source-projects-view/,作者Trinea 主要介绍那些不错个性化的View,包括Lis ...

  5. [Android Pro] 开发一流Android SDK

    cp from : https://blog.csdn.net/dd864140130/article/details/53558011 本篇文章已授权微信公众号 guolin_blog (郭霖)独家 ...

  6. Android SDK 开发指南

    Android SDK 开发指南 视频详解 以下视频是对融云 Android SDK 开发使用的详细讲解,您可以在阅读文档时配合学习.   更多视频教程如下: CSDN 融云 Android SDK ...

  7. 从事 Android应用开发4年有余,现在工资7500。很不爽!怎么办?

    最近到某论坛看到一个帖子: 坐标北京,在一个公司从事android应用开发4年有余(毕业至今没换过公司).公司利润越来越大,工资却每年长1000,如今才到7500.琢磨着换工作,又不想扔下这四年来逐步 ...

  8. Android NDK开发Hello Word!

    在之前的博客中已经为大家介绍了,如何在win环境下配置DNK程序,本篇我将带大家实现一个简单的Hello jni程序,让大家真正感受一下NDK开发的魅力.这里我们选择使用C+JAVA开发Android ...

  9. Android NDK开发初识

    神秘的Android NDK开发往往众多程序员感到兴奋,但又不知它为何物,由于近期开发应用时,为了是开发的.apk文件不被他人解读(反编译),查阅了很多资料,其中有提到使用NDK开发,怀着好奇的心理, ...

随机推荐

  1. C++之STL

    5.子类模板访问基类模板在子类模板中访问那些在基类模板中声明且依赖于模板参数的符号,应该在它前面加上作用域限定符"::" 或者显示使用this指针否则,编译器将试图在全局域中寻找该 ...

  2. 用VC6开发嵌入式LINUX程序

    黄山松 (Tom Huang) 发表于博客园http://www.cnblogs.com/tomview/ 首先说明一下,VC6自然不能直接开发LINUX程序,主要使用的是它的编辑环境而已,但是作为一 ...

  3. git 添加远程仓库遇到的问题

    上午在学习廖雪峰老师的 git 教程(http://www.liaoxuefeng.com/),在添加远程仓库这一节中遇到了两个问题: 问题描述: 一.关联自己的远程仓库. fatal: Not a ...

  4. go 字符变量

    go语言变量定义 第一类,通过关键字var来声明,可以在main函数体外 // varStudy //变量在main函数体外声明 package main import ( "fmt&quo ...

  5. POJ 2540 Hotter Colder --半平面交

    题意: 一个(0,0)到(10,10)的矩形,目标点不定,从(0,0)开始走,如果走到新一点是"Hotter",那么意思是离目标点近了,如果是"Colder“,那么就是远 ...

  6. web 小知识

    document.write和innerHTML的区别   document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open.每次写完关 ...

  7. 深入探讨 java.lang.ref 包

    深入探讨 java.lang.ref 包 本文主要探讨了 java.lang.ref 包的使用方法,以及源码解读.并就该包在不同 JVM 上的表现进行了比较与分析.通过阅读本文,读者可以加深对 jav ...

  8. vue组件的配置属性

    vue组件的声明语法: Vue.component('component-name',{ template:'<p>段落{{prop1}} {{prop2}}</p>', da ...

  9. 字符串截取函数substr()

    substr(参数1,参数2[,参数3]); 该系统函数返回被截后的子字符串,它接受2个必选参数,参数1为要截取的字符串,参数2为截取的开始位置,参数3可选,表示截取长度. 例子:substr(&qu ...

  10. Windows系统服务器IIS7.5 Asp.net支持10万请求的设置方法

    问题现象 ECS Windows系统服务器基于IIS搭建的网站由于IIS默认的配置,服务器最多只能处理5000个同时请求,访问量大时很容易导致报错: Error Summary:  HTTP Erro ...