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

在节日短信送祝福的功能实现方面,为了能够方便直观展示实现过程,小编我以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. 汉化 Hirens.BootCD 中的 XP 系统

    汉化 Hirens.BootCD 中的 XP 系统 1. 在中文版 XPSP3 镜像中提取所需的文件 原系统为没有作 server pack 的 Windows XP Professional ,在W ...

  2. zenDiscovery和master选举

    上一篇通过 ElectMasterService源码,分析了master选举的原理的大部分内容:master候选节点ID排序保证选举一致性及通过设置最小可见候选节点数目避免brain split.节点 ...

  3. 阅读笔记——Servlet

    什么是Servlet Servlet是用java编写的运行在web服务器中的程序,因此它可以调用服务器端的类,它也可以被调用,它本身就是一个类. Servlet的工作原理 servlet由web服务器 ...

  4. ArcGIS 10 影像、栅格数据格式批量转换

    转自原文 ArcGIS 10 影像.栅格数据格式批量转换 在做三维场景的时候,经常会涉及多种不同格式DEM数据或者影像的转换,如ASCII.GRID.IMG.TIFF等等,遇到大数据量时,我们就需要批 ...

  5. ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第二篇:第一个页面

    摘要      本文首先一步一步完成Demo的第一个页面——首页.然后根据实现过程,说明一下其中用到的与ASP.NET MVC相关的概念与原理. 让第一个页面跑起来      现在,我们来实现公告系统 ...

  6. 前台Ajax发送数据给后台

    前台发ajax请求给后台 前台代码 let data= [{receiveAdd:receiveAddVal, sendAdd:sendAddVal,distance:distance,goodsNa ...

  7. 推荐一款优雅高效的免费在线APP原型工具

    有段时间没有推荐干货给大伙了,今天是时候把压箱底的东西拿出来分享给大家了! 想要学习原型图绘制的小伙伴可以看过来,适合零基础的小白,五分钟就可以上手,绘制自己想要的产品原型图. 官方介绍:用户只需输入 ...

  8. C#执行sql文件

    C# 执行sql文件 2012-05-11 12:28:57|  分类: App Develop|举报|字号 订阅       /// <summary>         /// 执行sq ...

  9. BZOJ——T2190: [SDOI2008]仪仗队

    Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3216  Solved: 2075[Submit][Status][Discuss] http://w ...

  10. 洛谷 P3131 [USACO16JAN]子共七Subsequences Summing to Sevens

    P3131 [USACO16JAN]子共七Subsequences Summing to Sevens 题目描述 Farmer John's NN cows are standing in a row ...