系统代码下载地址:https://github.com/android

短信存在位置

找到android系统数据库:data-data-com.android.providers.telephony-databases-mmssms.db

赵雅智_android短信窃听及android短信源码解析_第1张图片

赵雅智_android短信窃听及android短信源码解析_第2张图片


短信数据库分析


将mmssms.db表导出,通过SQLiteexpert查看,如下图

sms表:短信表

赵雅智_android短信窃听及android短信源码解析_第3张图片

表结构分析:

address:短信发送者电话号码

person:联系人编号,如果电话薄里有联系人则显示编号,没有联系人则显示null

read:读取状态,0为未读,1为已读

body:短信内容


thread表:线程表


dataL:日期

message_count:短信发送的条数

snippet:最后一条短信内容

read:短信读取状态

android短信源代码分析

在android系统的短信代码中,AndroidMenifest.xml定义了提供外接查询的接口

定义了短信有关的uri的urimatch操作,例如已读,未读,草稿箱,收件箱,发件箱 赵雅智_android短信窃听及android短信源码解析_第4张图片


步骤

  • 在AndroidMenifest.xml添加访问权限
  • 得到内容解析器
  • 注册观察者
    • uri
    • 观察者
      • handler
        • 当消息来的时候进行监听
        • 从数据库查找数据,显示出来
      • 构造器
      • 当数据库改变时

主要代码

AndroidMenifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.android_readsms"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="17" />    <!-- 短信读取权限 -->    <uses-permission android:name="android.permission.READ_SMS"/>    <uses-permission android:name="android.permission.WRITE_SMS"/>    <instrumentation android:targetPackage="com.example.android_readsms" android:name="android.test.InstrumentationTestRunner"></instrumentation>    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.example.android_readsms.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <uses-library android:name="android.test.runner"/>    </application></manifest>


MainActivity.java
package com.example.android_readconcats;import java.util.List;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.widget.RadioButton;import android.widget.RadioGroup;import android.widget.RadioGroup.OnCheckedChangeListener;import com.example.android_readphone.fragment.CollectionFragment;import com.example.android_readphone.fragment.ConcactsFragment;import com.example.android_readphone.fragment.GroupFragment;public class MainActivity extends FragmentActivity implementsOnCheckedChangeListener {private RadioGroup rg;private FragmentManager fragmentManager;// 存放的标志符号private String tags[] = { "collection", "contacts", "group" };@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取FragmentManager对象fragmentManager = getSupportFragmentManager();rg = (RadioGroup) findViewById(R.id.radioGroup1);rg.setOnCheckedChangeListener(this);initMain();}/** * 初始化第一个界面 */private void initMain() {// 获取FragmentTransaction对象FragmentTransaction transaction = fragmentManager.beginTransaction();// 添加收藏transaction.add(R.id.show_content, new CollectionFragment(),"collection");// 提交transaction.commit();}/** * 替换面板 */private void replaceMain(String tag) {// 获取FragmentTransaction对象FragmentTransaction transaction = fragmentManager.beginTransaction();if ("contacts".equals(tag)) {// 替换联系人transaction.replace(R.id.show_content, new ConcactsFragment(),"contacts");} else if ("group".equals(tag)) {// 替换添加分组transaction.replace(R.id.show_content, new GroupFragment(), "group");} else if ("collection".equals(tag)) {// 替换添加分组transaction.replace(R.id.show_content, new CollectionFragment(),"collection");}// 提交transaction.commit();}/** * 替换面板 */private void replaceMains(String tag) {Fragment fragmentTag = fragmentManager.findFragmentByTag(tag);if (fragmentTag == null) {if ("contacts".equals(tag)) {fragmentManager.beginTransaction().add(R.id.show_content, new ConcactsFragment(),"contacts").commit();} else if ("group".equals(tag)) {fragmentManager.beginTransaction().add(R.id.show_content, new GroupFragment(), "group").commit();} else if ("collection".equals(tag)) {fragmentManager.beginTransaction().add(R.id.show_content, new CollectionFragment(),"collection").commit();}} else {// 判断是否真的添加了if (fragmentTag.isAdded()) {fragmentManager.beginTransaction().show(fragmentTag).commit();// 显示}}// 拿到已经添加的所有片段List<Fragment> fList = fragmentManager.getFragments();// 遍历所有的片段for (Fragment fragment : fList) {// 判断tag是否是要显示的片段if (!tag.equals(fragment.getTag())) {fragmentManager.beginTransaction().hide(fragment).commit();// 隐藏}}}@Overridepublic void onCheckedChanged(RadioGroup group, int checkId) {switch (checkId) {case R.id.rb_collection:replaceMain("collection");break;case R.id.rb_contacts:replaceMain("contacts");break;case R.id.tb_group:replaceMain("group");break;default:break;}}}

运行效果

使用DDMS的Emulator Control给模拟器发送短信:

客户端显示如下: 赵雅智_android短信窃听及android短信源码解析_第5张图片

涉及知识点:

contentprovider内容解析器 contentprovider内容观察者 handler
系统自带短信源码: http://download.csdn.net/detail/zhaoyazhi2129/7491105

短信备份

  1. 读取系统里的短信
  2. 将读取出来的短信写成一个xml文件(短信备份)
  3. 写好的xml文件上传到服务器
  4. 从服务器上下载下来,将xml文件解析出来
  5. 插入到自己创建的数据库中(短信恢复)

更多相关文章

  1. Android中音乐文件的信息详解【安卓源码解析二】
  2. Android 之 调用短信界面
  3. 接收短信启动相应服务
  4. Android 个人记账程序源码
  5. android中Handler源码的分析文章
  6. android camera 源码分析

随机推荐

  1. Android getDimensionPixelSize, 代码中
  2. Android学习系列之三
  3. Android编译系统简要介绍和学习计划
  4. Android(安卓)网络通信——Volley
  5. android如何支持多屏幕
  6. 《Android 开发工程师面试指南》
  7. 分享两种最简单的Android打渠道包的方法
  8. 如何监控android的流量信息
  9. Android 程序适应多种多分辨率
  10. Android IPC原理分析小结