Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者-示例(监听短信)
2015-07-26 16:04
871 查看
五、ContentProvider 内容提供者
续上一博文(Android核心基础-5.Android 数据存储与访问-4.ContentProvider 内容提供者)前面讲了内容提供者ContentProvider和监听数据修改的ContentObserver
本讲将在上一博文的理论指导下,书写一个示例“短信的监听”
8.1 先导篇
我们启动模拟器->打开短信。发现log打印了一行如下:07-26 10:40:20.208: I/ActivityManager(1007): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.mms/.ui.ConversationList bnds=[192,417][256,481] u=0} from pid 1146
从日志中我们看到系统启动的短信应用程序的包名是
com.android.mms
根据这个包名我们去系统目录下查找
data/data/com.android.mms
很遗憾的发现没有数据库文件,那么我们发送/接收的短信数据都储存在哪里呢?
继续追查下去,去下载官方的源码(github地址:https://github.com/CyanogenMod/android_packages_providers_TelephonyProvider),我们发现打开的“短信”应用程序只是展示界面,其数据是存储在另外一个程序中(con.android.providers.telephony)通过然后ContentProvider进行增删改查的操作。
找到
data/data/com.android.providers.telephony/databases
目录下的mmssms.db导出到电脑,用SQLite Expert Professional 3打开
我们发送的短信都存储在sms表中
从github上下载telephonyprovider, 从清单文件中获取Uri
在程序中对指定Uri注册ContentObserver, 当收发短信时就会执行onChange()
查询到最后一条数据就是短信记录
8.2 创建程序
程序不需要Activity,但是我们为了讲解示例,我们就暂且创建了Activitypackage net.dxs.smshack; import java.util.Date; import android.app.Activity; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Handler; public class MainActivity extends Activity { private static final Uri uri = Uri.parse("content://sms");//手机短信内容提供者的Uri @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //注册ContentObserver getContentResolver().registerContentObserver(uri, true, new ContentObserver(new Handler()) { private Date date; @Override public void onChange(boolean selfChange) {//收发短信时查询出最后一条数据 Cursor cursor = getContentResolver().query(uri, new String[] { "address", "date", "type", "body" }, null, null, "_id DESC LIMIT 1"); if (cursor.moveToNext()) { String address = cursor.getString(0); Date newDate = new Date(cursor.getLong(1)); if (newDate.equals(date)) return; date = newDate; String type = cursor.getInt(2) == 1 ? "收" : "发"; String body = cursor.getString(3); System.out.println(address + ", " + newDate + ", " + type + ", " + body); // 通过短信发送到自己的手机 // 发送邮件 // 提交到服务器 } } }); } }
程序中的地址Uri uri = Uri.parse(“content://sms”)
是根据我们下载的源码的清单文件:知道android:authorities=”sms”//授权/主机名
和android:name=”SmsProvider”知道是SmsProvider.java文件的代码查看
最后得到的Uri
<provider android:name="SmsProvider" android:authorities="sms"//授权/主机名 android:multiprocess="false"//是否允许多进程同时使用 android:exported="true"//应用程序可以被其他应用使用 android:singleUser="true"//单用户 android:readPermission="android.permission.READ_SMS" //读权限 android:writePermission="android.permission.WRITE_SMS" />//写权限
注意:我们的程序要添加对应的用户权限
<uses-permission android:name="android.permission.READ_SMS" />
把我们的程序安装至模拟器,这个时候发送短信
将看到打印:
07-26 14:43:49.698: I/System.out(14329): 1 501-099-0415, Sun Jul 26 14:43:49 格林尼治标准时间+0800 2015, 发, 这是发送的内容
至此,我们短信监听就算是完成了。
8.3 写在最后
mmssms库的表addr
android_metadata
attachments
canonical_addresse
drm
part
pdu
pending_msgs
rate
raw
sms
sr_pending
threads
words
其中我们关心的表为:sms,其字段为:
_id
thread_id
address
person
date
date_sent
protocol
read
status
type
reply_path_present
subject
body
service_center
locked
error_code
seen
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories