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

在节日短信送祝福的功能实现方面,为了能够方便直观展示实现过程,小编我以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. 1.18 Python基础知识 - Python内置函数

    官方地址:https://docs.python.org/3.5/library/functions.html abs(x): 返回数字的绝对值 all(iterable): 如果迭代器的所有元素都为 ...

  2. 实际感受美丽的Linux(多组视频)

    1.Fedora 上使用google earth 2.体验桌面-GNOME 2.2.9 3.体验桌面-KDE4.4 永中Office使用演示(和MS Office 2003很相似哦) 4.在Fedor ...

  3. buildroot使用

    buildroot是一套自动化构建工具,比yocto简单. 项目地址:http://www.buildroot.org/ 培训资料地址:http://free-electrons.com/ 附带lin ...

  4. element-UI实现el-table-column百分比自定义分配

    1.把el-table-column的属性width换位min-width就支持百分比显示了.

  5. hello word-python 入门

    今天正式开始学习python,先写一个最今经典的例子 helloword #!/usr/bin/python3.2 print("hello work!") 知识点: #!usr/ ...

  6. 4.Windows下安装ZooKeeper

    转自:https://www.cnblogs.com/mstmdev/p/5612791.html 官方主页: https://zookeeper.apache.org/     选择合适的镜像地址下 ...

  7. Java基础学习总结(53)——HTTPS 理论详解与实践

    前言 在进行 HTTP 通信时,信息可能会监听.服务器或客户端身份伪装等安全问题,HTTPS 则能有效解决这些问题.在使用原始的HTTP连接的时候,因为服务器与用户之间是直接进行的明文传输,导致了用户 ...

  8. 洛谷 P1206 [USACO1.2]回文平方数 Palindromic Squares

    P1206 [USACO1.2]回文平方数 Palindromic Squares 题目描述 回文数是指从左向右念和从右向左念都一样的数.如12321就是一个典型的回文数. 给定一个进制B(2< ...

  9. [D3] Animate Transitions in D3 v4

    D3 makes it easy to add meaningful animations to your data visualizations. Whether it’s fading in ne ...

  10. 关于python的深浅拷贝、赋值

    https://blog.csdn.net/weixin_39750084/article/details/81435454