您的位置:首页 > 移动开发 > Android开发

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,但是我们为了讲解示例,我们就暂且创建了Activity

package 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息