Android 节日短信送祝福(功能篇:1-数据库操作类与自定义ContentProvider)
首先,还是展示一下部分目录结构:
在节日短信送祝福的功能实现方面,为了能够方便直观展示实现过程,小编我以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)的更多相关文章
- Android 节日短信送祝福(功能篇:2-短信历史记录Fragment的编写)
因为用于展示短信记录的是一个ListView,但是为了方便,可以直接继承自ListFragment,就可以免去写ListView对应的布局了,只需要写其item对应的布局即可. item_sended ...
- Android 节日短信送祝福(UI篇:3-选择短信与发送短信的Activity的实现)
一.ChooseMsgActivity的实现 1.布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/ ...
- Android获取短信验证码
Android开发中关于短息验证码的设计层出不穷,越来越多的应用为了更好的提高软件的安全性,开始使用通过服务器向用户发送验证码的方式,来保护用户个人信息的安全性.无论是用户注册时的信息验证还是当用户发 ...
- Android之——短信的备份与还原
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47091281 眼下,Android手机中的一些软件能够实现手机短信的备份与还原操作 ...
- 完整的Android手机短信验证源码
短信验证功能我分两个模块来说,短信验证码的后台和代码实现短信验证码的功能. 一.短信验证码的后台 1.注册Mob账号:http://www.mob.com/#/login 2.注册成功之后, ...
- android 发送短信的两种方式,以及接收报告和发送报告
android发送短信,以及接收报告和发送报告 android中发送短信其实有两种方式,这个和打电话类似,大家可以了解一下: 一.调起系统发短信功能 ...
- Android开发——短信电话拦截/接听电话
1.短信拦截 首先需要声明的是,Android4.4版本以上,如果想做到短信拦截,必须成为default sms,把所有短信相关的功能都包揽了,然后再做短信拦截.但这种做法,适配性和兼容性的工作是非常 ...
- 用Tasker实现收到Android手机短信自动转发到邮箱
发送短信到邮箱的原理与 <用Tasker实现收到Android手机短信自动转发到邮箱>有些类似. 发送短信到邮箱是利用Ifttt这个服务将短信转发到邮箱中.Ifttt服务的可扩展性很强, ...
- 利用短信通知的方式在Tasker中实现收到Android手机短信自动转发到邮箱
利用短信的通知实现短信内容转发到微信 code[class*="language-"] { padding: .1em; border-radius: .3em; white-sp ...
随机推荐
- 20亿与20亿表关联优化方法(超级大表与超级大表join优化方法)
记得5年前遇到一个SQL.就是一个简单的两表关联.SQL跑了几乎相同一天一夜,这两个表都非常巨大.每一个表都有几十个G.数据量每一个表有20多亿,表的字段也特别多. 相信大家也知道SQL慢在哪里了,单 ...
- 对AWS的计费有点糊涂
对AWS的计费有点糊涂 今天收到亚马逊的账单,就两笔 1. US West (Oregon) Region Elastic IP Addresses $0.005 per Elastic IP ...
- http 协议上传文件multipart form-data boundary 说明--转载
原文地址:http://xixinfei.iteye.com/blog/2002017 含义 ENCTYPE="multipart/form-data" 说明: 通过 http 协 ...
- 手动挂接NFS
环境: 单板:s3c2440 内核:Linux-2.6.22.6 U-boot1.16 初始根文件系统Yaffs2 前提条件 1. 开发板上要烧写好文件系统 2. 能正常开机进入Linux系统 3. ...
- 【Codeforces Round #452 (Div. 2) B】Months and Years
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 闰,平,平 平,闰,平 平,平,闰 平,平,平 4种情况都考虑到就好. 可能有重复的情况. 但是没关系啦. [代码] #includ ...
- 设计模式六大原则(二):里氏替换原则(Liskov Substitution Principle)
里氏替换原则(LSP)由来: 最早是在 妖久八八 年, 由麻神理工学院得一个女士所提出来的. 定义: 1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 ...
- 有趣的Ruby-学习笔记4
Ruby块 块.在我看来就是插入一段可变的函数 block_name{ statement1 statement2 .......... } 看起来不知道是什么,只是别急,继续往下看. 块函数通过yi ...
- RocketMQ集群消费的那些事
说明 RocketMQ集群消费的时候,我们经常看到类似注释里面 (1,(2 的写法,已经有时候有同学没注意抛异常的情况就是(3 模拟的情况.那么这3种情况到底是怎么样的呢?你是否都了然于心呢?下面我们 ...
- Python 极简教程(六)运算符
运算符,我们日常生活中使用的加减乘除,都是运算符的一种.当然这种一般我们称为算术运算符,用于处理数字运算的. 但是在计算机语言中,还有很多的运算符.用于处理不用的情况. 主要有以下几类: 算术运算符 ...
- 【习题 6-6 UVA - 12166 】Equilibrium Mobile
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举一个秤砣的重量不变. 某一个秤砣的重量不变之后. 所有秤砣的重量就固定了. 因为它的兄弟节点的重量要和它一样. 则父亲节点的重量 ...