首页 > 代码库 > 赵雅智_android短信窃听及android短信源码解析

赵雅智_android短信窃听及android短信源码解析

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

短信存在位置

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



短信数据库分析


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

sms表:短信表


表结构分析:

address:短信发送者电话号码

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

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

body:短信内容


thread表:线程表


dataL:日期

message_count:短信发送的条数

snippet:最后一条短信内容

read:短信读取状态

android短信源代码分析

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


定义了短信有关的uri的urimatch操作,例如已读,未读,草稿箱,收件箱,发件箱



步骤

  • 在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 implements
		OnCheckedChangeListener {
	private RadioGroup rg;
	private FragmentManager fragmentManager;
	// 存放的标志符号
	private String tags[] = { "collection", "contacts", "group" };

	@Override
	protected 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();// 隐藏
			}
		}

	}

	@Override
	public 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给模拟器发送短信:


客户端显示如下:


涉及知识点:

contentprovider内容解析器
contentprovider内容观察者
handler

系统自带短信源码:http://download.csdn.net/detail/zhaoyazhi2129/7491105

短信备份

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