首先,还是展示一下部分目录结构: 

在节日短信送祝福的功能实现方面,为了能够方便直观展示实现过程,小编我以Java文件为基础,一个一个来展示,免得到时候这个java文件写点,一下又跳到另外一个java文件写点,毕竟这不像教学视频那样直观。


因为在功能方面涉及到了显示已经发送短信的历史记录,那么,毫无疑问,要用到数据库,但是在定义SQLiteOpenHelper之前先定义一个”已经发送的短信的实体类”(SendedMsg):

SendedMsg.java

public class SendedMsg {
private int id;
private String content;
private String numbers;//发送的联系人号码(可能有多个联系人的号码,拼接成一个String)
private String names;//发送的联系人名单(可能有多个联系人,拼接成一个String)
private String festivalName;
private Date date;
private String dateStr;//主要为了方便
private DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm"); public static final String TABLE_NAME="tb_sended_msg";
public static final String COLUMN_CONTENT="content";
public static final String COLUMN_NUMBERS="numbers";
public static final String COLUMN_NAMES="names";
public static final String COLUMN_FESTIVAL_NAME="festival_name";
public static final String COLUMN_DATE="date_str"; public Date getDate() {
return date;
} public void setDate(Date date) {
this.date = date;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public String getNumbers() {
return numbers;
} public void setNumbers(String numbers) {
this.numbers = numbers;
} public String getNames() {
return names;
} public void setNames(String names) {
this.names = names;
} public String getFestivalName() {
return festivalName;
} public void setFestivalName(String festivalName) {
this.festivalName = festivalName;
} public String getDataStr() {
dateStr=df.format(date);
return dateStr;
}
}

可以注意到,在实体类中还定义了一些常量,这是为了避免在对数据库进行操作时出错,可以直接引用。

SmsDBOpenHelper.java(单例模式)

public class SmsDBOpenHelper extends SQLiteOpenHelper{
private static final String DB_NAME="sms.db";
private static final int DB_VERSION=; private static SmsDBOpenHelper mHelper; private SmsDBOpenHelper(Context context) {
super(context.getApplicationContext(), DB_NAME, null, DB_VERSION);
} //传入的context有可能是一个Activity
//所以在构造方法中用context.getApplicationContext()尽量得到Application的context
//避免造成内存泄露的问题
public static SmsDBOpenHelper getInstance(Context context) {
if(mHelper==null) {
synchronized (SmsDBOpenHelper.class) {
if(mHelper==null) {
mHelper=new SmsDBOpenHelper(context);
}
}
}
return mHelper;
} @Override
public void onCreate(SQLiteDatabase db) {
String sql="create table "+ SendedMsg.TABLE_NAME+" ( "+
"_id integer primary key autoincrement, "+
SendedMsg.COLUMN_DATE+" integer, "+
SendedMsg.COLUMN_FESTIVAL_NAME+" text,"+
SendedMsg.COLUMN_CONTENT+" text,"+
SendedMsg.COLUMN_NAMES+" text,"+
SendedMsg.COLUMN_NUMBERS+" text )";
db.execSQL(sql);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}

注意:在建表的时候,有一个”_id”的主键,这是因为在后面会讲到一个用于展示短信历史记录的Fragment,里面会涉及CursorAdapter,而CursorAdapter里面会用到一个cursor,该cursor必须要有个名为 _id的列

在私有构造方法中的context.getApplicationContext()这点是值得注意与学习的。

接着是自定义的ContentProvider.java

public class SmsProvider extends ContentProvider{
private static final String AUTHORITY="com.just.sms.provider.SmsProvider";
public static final Uri URI_SMS_ALL=Uri.parse("content://"+AUTHORITY+"/sms"); private static UriMatcher mMatcher; private static final int SMS_ALL=;//表示访问表中的所有数据
private static final int SMS_ONE=;//表示访问表中的单条数据 //在静态代码块中完成mMatcher的初始化及uri的添加
static {
mMatcher=new UriMatcher(UriMatcher.NO_MATCH); //addURI接收三个参数,可以分别把权限、路径和一个自定义代码传进去
//*:表示匹配任意长度的任意字符;#:表示匹配任意长度的数字
mMatcher.addURI(AUTHORITY,"sms",SMS_ALL);
mMatcher.addURI(AUTHORITY,"sms/#",SMS_ONE);
} private SmsDBOpenHelper mHelper;
private SQLiteDatabase mDB; @Override
public boolean onCreate() {
mHelper=SmsDBOpenHelper.getInstance(getContext());
return true;
} @Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
int match=mMatcher.match(uri);
switch (match) {
case SMS_ALL:
break;
case SMS_ONE://本案例用不到,但展示一下代码逻辑
long id=ContentUris.parseId(uri);//从路径中中获取id
selection="_id = ?";
selectionArgs=new String[]{String.valueOf(id)};
break;
default:
throw new IllegalArgumentException("Wrong URI:"+uri.toString());
}
mDB=mHelper.getReadableDatabase();
Cursor cursor=mDB.query(SendedMsg.TABLE_NAME,projection,selection,selectionArgs,null,null,sortOrder); //用来在后台检测数据的变化,如果有变化就会有返回(因为在SmsHistoryFragment中使用了Loader)
cursor.setNotificationUri(getContext().getContentResolver(),URI_SMS_ALL); return cursor;
} @Override
public Uri insert(Uri uri, ContentValues values) {
int match=mMatcher.match(uri);
if(match!=SMS_ALL) {
throw new IllegalArgumentException("Wrong URI:"+uri.toString());
}
mDB=mHelper.getWritableDatabase(); //第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值NULL,一般我们用不到这个功能,直接传入null 即可
long rowId=mDB.insert(SendedMsg.TABLE_NAME,null,values);
if(rowId>) {//如果添加数据成功
notifyDataSetChanged();
return ContentUris.withAppendedId(uri,rowId);//为传入的uri加上id
}
return uri;
} private void notifyDataSetChanged() {
getContext().getContentResolver().notifyChange(URI_SMS_ALL,null);//通知监听器关于数据更新的信息
} @Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return ;
} @Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return ;
} @Override
public String getType(Uri uri) {
return null;
}
}

一定要记得在AndroidMainfest.xml中注册

<provider
android:name=".db.SmsProvider"
android:authorities="com.just.sms.provider.
SmsProvider">
</provider>

在ContentProvider中呢,需要注意两行代码(是不可或缺的)。 
一个是query方法中的:

cursor.setNotificationUri(getContext().getContentResolver(),URI_SMS_ALL);

另一个是notifyDataSetChanged方法中的:

getContext().getContentResolver().notifyChange(URI_SMS_ALL,null);

这两行代码的作用可以先暂时搁置一下,等到后面讲SmsHistoryFragment的时候再联系起来说明一下。

Android 节日短信送祝福(功能篇:1-数据库操作类与自定义ContentProvider)的更多相关文章

  1. Android 节日短信送祝福(功能篇:2-短信历史记录Fragment的编写)

    因为用于展示短信记录的是一个ListView,但是为了方便,可以直接继承自ListFragment,就可以免去写ListView对应的布局了,只需要写其item对应的布局即可. item_sended ...

  2. Android 节日短信送祝福(UI篇:3-选择短信与发送短信的Activity的实现)

    一.ChooseMsgActivity的实现 1.布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/ ...

  3. Android获取短信验证码

    Android开发中关于短息验证码的设计层出不穷,越来越多的应用为了更好的提高软件的安全性,开始使用通过服务器向用户发送验证码的方式,来保护用户个人信息的安全性.无论是用户注册时的信息验证还是当用户发 ...

  4. Android之——短信的备份与还原

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47091281 眼下,Android手机中的一些软件能够实现手机短信的备份与还原操作 ...

  5. 完整的Android手机短信验证源码

    短信验证功能我分两个模块来说,短信验证码的后台和代码实现短信验证码的功能. 一.短信验证码的后台      1.注册Mob账号:http://www.mob.com/#/login 2.注册成功之后, ...

  6. android 发送短信的两种方式,以及接收报告和发送报告

               android发送短信,以及接收报告和发送报告          android中发送短信其实有两种方式,这个和打电话类似,大家可以了解一下:    一.调起系统发短信功能    ...

  7. Android开发——短信电话拦截/接听电话

    1.短信拦截 首先需要声明的是,Android4.4版本以上,如果想做到短信拦截,必须成为default sms,把所有短信相关的功能都包揽了,然后再做短信拦截.但这种做法,适配性和兼容性的工作是非常 ...

  8. 用Tasker实现收到Android手机短信自动转发到邮箱

    发送短信到邮箱的原理与 <用Tasker实现收到Android手机短信自动转发到邮箱>有些类似.  发送短信到邮箱是利用Ifttt这个服务将短信转发到邮箱中.Ifttt服务的可扩展性很强, ...

  9. 利用短信通知的方式在Tasker中实现收到Android手机短信自动转发到邮箱

    利用短信的通知实现短信内容转发到微信 code[class*="language-"] { padding: .1em; border-radius: .3em; white-sp ...

随机推荐

  1. DIV+CSS两种盒子模型(W3C盒子与IE盒子)

    在辨析两种盒子模型之前.先简单说明一下什么叫盒子模型. 原理: 先说说我们在网页设计中常听的属性名:内容(content).填充(padding).边框(border).边界(margin), CSS ...

  2. lightSlider 好图片轮播插件 支持移动端

    http://jquery-plugins.net/jquery-lightslider-lightweight-responsive-content-slider https://github.co ...

  3. 在一台机子上,安装,运行两mysql数据库实例

    为了方便测试,想要用到两个mysql数据库实例.以windows系统为例 当然安装第一个mysql数据库,很简单没什么说的.但是再要安装,运行mysql安装程序时,会提示,修复,卸载,重新安装. 这时 ...

  4. 巧用数据流让 Word 文档在线阅读

            常常写博客或空间日记的朋友,对网络编辑器(如图1,是CSDN的博客编辑器)并不陌生.也比較easy做出非常绚烂的排版.但这次在做一个BS的项目,客户一直在用Office的软件中的Wor ...

  5. ListView Item 点击展开隐藏问题

    public class ListAdapter extends BaseAdapter {     private Context mContext;     private View mLastV ...

  6. Delphi部份函数,命令,属性中文说明

    Abort 函数 引起放弃的意外处理 Abs 函数 绝对值函数 AddExitProc 函数 将一过程添加到运行时库的结束过程表中 Addr 函数 返回指定对象的地址 AdjustLineBreaks ...

  7. h5背景

    1.背景属性复习: background-image background-color background-repeat background-position background-attachm ...

  8. 洛谷 P2693 [USACO1.3]号码锁 Combination Lock

    P2693 [USACO1.3]号码锁 Combination Lock 题目描述 农夫约翰的奶牛不停地从他的农场中逃出来,导致了很多损害.为了防止它们再逃出来,他买了一只很大的号码锁以防止奶牛们打开 ...

  9. C#调用天气预报网络服务

    本程序通过调用网络上公开的天气预报网络服务来显示某个地区三天的天气,使用到的网络服务地址:http://www.webxml.com.cn/WebServices/WeatherWebService. ...

  10. 网络IO

    1.前言 在网络编程中,阻塞.非阻塞.同步.异步经常被提到.unix网络编程第一卷第六章专门讨论五种不同的IO模型,Stevens讲的非常详细,我记得去年看第一遍时候,似懂非懂,没有深入理解.网上有详 ...