130.短信的备份
来源:互联网 发布:中国的顶级域名 编辑:程序博客网 时间:2024/05/16 16:56
短信备份的原理,是用内容提供者读取短信,然后保存。
android源码中FramWork和Package是java的代码
短信存储在com.android.providers.telephoney的database中,里面有2个文件mmsms.db和一个telephoney.db中,前者是
mmsms.db表的内容如下:
type:1表示接受,2表示发生送
body表示内容
address:电话号码
date:时间
需要权限
<uses-permission android:name="android.permission.READ_SMS"/> <uses-permission android:name="android.permission.WRITE_SMS" />
布局文件
activity_advancetools.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView style="@style/TitleStyle" android:text="高级工具" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button" android:text="电话归属地查询" android:textColor="@color/black" android:drawableLeft="@android:drawable/ic_menu_camera" android:gravity="center_vertical" android:textSize="20sp" android:drawablePadding="5dp" android:padding="10dp" android:clickable="true" android:onClick="numberAddressQuery" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button" android:text="短信备份" android:textColor="@color/black" android:drawableLeft="@android:drawable/ic_menu_camera" android:gravity="center_vertical" android:textSize="20sp" android:drawablePadding="5dp" android:padding="10dp" android:clickable="true" android:onClick="backUpsms" /> </LinearLayout>
Toast的封装UIUtils.java
package com.ldw.safe.utils;import android.app.Activity;import android.widget.Toast;public class UIUtils {public static void showToast(final Activity context,final String msg){if("main".equals(Thread.currentThread().getName())){Toast.makeText(context, msg, 1).show();}else{context.runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(context, msg, 1).show();}});}}}布局的逻辑文件AdvancedToolsActivity.java
package com.ldw.safe.Activity;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.os.Looper;import android.view.View;import android.widget.Toast;import com.ldw.safe.R;import com.ldw.safe.utils.SmsUtils;/* * 高级工具,包含归属地和短信备份 */public class AdvancedToolsActivity extends Activity {@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_advancedtools);}/* * 归属地查询 */public void numberAddressQuery(View v){startActivity(new Intent(this, AddressActivity.class));}/* * 短信备份的功能 */public void backUpsms(View v){new Thread(){public void run() {boolean result = SmsUtils.backUp(AdvancedToolsActivity.this);if(result){//子线程不能刷新UI,这种方法子线程弹出ToastLooper.prepare();Toast.makeText(AdvancedToolsActivity.this, "备份成功", Toast.LENGTH_SHORT).show();Looper.loop();}else{Looper.prepare();Toast.makeText(AdvancedToolsActivity.this, "备份失败", Toast.LENGTH_SHORT).show();Looper.loop();}}}.start();}}生成短信备份的工具文件,获取到内容观察者,读取短信,然后以xml文件的形式输出
SmsUtils.java
package com.ldw.safe.utils;import java.io.File;import java.io.FileOutputStream;import org.xmlpull.v1.XmlSerializer;import android.content.ContentResolver;import android.content.Context;import android.database.Cursor;import android.net.Uri;import android.os.Environment;import android.util.Xml;/* * 短信的工具类,用于短信备份 */public class SmsUtils {public static boolean backUp(Context context){/* * 1.先判断是否有sd卡, * 2.权限是---因此必须使用内容观察者读取 * 3.写短信 *///判断sd卡的状态if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//sd卡存在,获取到内容观察者ContentResolver resolver = context.getContentResolver();// 获取短信的路径Uri uri = Uri.parse("content://sms/");//通过内容观察着,读取短信内容,type:1接受短信,2发送短信Cursor cursor = resolver.query(uri, new String[]{"address", "date", "type", "body"}, null, null, null);//短信的数量int count = cursor.getCount();//写文件try {//创建保存的短信备份的文件的名字File file = new File(Environment.getExternalStorageDirectory(), "smsbackup.xml");FileOutputStream os = new FileOutputStream(file);//xml序列化器,xml解析是pull解析XmlSerializer serializer = Xml.newSerializer();//短信序列化到sd卡,设置编码格式serializer.setOutput(os, "utf-8");// standalone表示当前的xml是否是独立文件 ture表示文件独立。yesserializer.startDocument("utf-8", true);// 设置开始的节点 第一个参数是命名空间。第二个参数是节点的名字serializer.startTag(null, "smss");//设置smss节点上面的属性值 第二个参数是名字。第三个参数是值serializer.attribute(null, "size", String.valueOf(count));//读取短信数据while (cursor.moveToNext()) {System.err.println("----------------------------");System.out.println("address = " + cursor.getString(0));System.out.println("date = " + cursor.getString(1));System.out.println("type = " + cursor.getString(2));System.out.println("body = " + cursor.getString(3));serializer.startTag(null, "sms");serializer.startTag(null, "address");// 设置文本的内容serializer.text(cursor.getString(0));serializer.endTag(null, "address");serializer.startTag(null, "date");serializer.text(cursor.getString(1));serializer.endTag(null, "date");serializer.startTag(null, "type");serializer.text(cursor.getString(2));serializer.endTag(null, "type");serializer.startTag(null, "body");serializer.endTag(null, "body"); //读取短信的内容/** * 加密:第一个参数表示加密种子(密钥) * 第二个参数表示加密的内容 */serializer.text(Crypto.encrypt("123", cursor.getString(3)));serializer.endTag(null, "sms");}cursor.close();serializer.endTag(null, "smss");serializer.endDocument();os.flush();os.close();return true;} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}return false;}}
中间需要调用一个Crypto.java的文件(可以用来加密,github)
package com.ldw.safe.utils;import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import android.util.Base64;/**** ━━━━━━神兽出没━━━━━━* ┏┓ ┏┓* ┏┛┻━━━┛┻┓* ┃ ┃* ┃ ━ ┃* ┃ ┳┛ ┗┳ ┃* ┃ ┃* ┃ ┻ ┃* ┃ ┃* ┗━┓ ┏━┛Code is far away from bug with the animal protecting* ┃ ┃ 神兽保佑,代码无bug* ┃ ┃* ┃ ┗━━━┓* ┃ ┣┓* ┃ ┏┛* ┗┓┓┏━┳┓┏┛* ┃┫┫ ┃┫┫* ┗┻┛ ┗┻┛** ━━━━━━感觉萌萌哒━━━━━━*/public class Crypto {/** * Encrypt plain string and encode to Base64 * * @param seed * @param plain * @return * @throws Exception */public static String encrypt(String seed, String plain) throws Exception {byte[] rawKey = getRawKey(seed.getBytes());byte[] encrypted = encrypt(rawKey, plain.getBytes());return Base64.encodeToString(encrypted, Base64.DEFAULT);}/** * Decrypt Base64 encoded encrypted string * * @param seed * @param encrypted * @return * @throws Exception */public static String decrypt(String seed, String encrypted)throws Exception {byte[] rawKey = getRawKey(seed.getBytes());byte[] enc = Base64.decode(encrypted.getBytes(), Base64.DEFAULT);byte[] result = decrypt(rawKey, enc);return new String(result);}private static byte[] getRawKey(byte[] seed) throws Exception {KeyGenerator keygen = KeyGenerator.getInstance("AES");SecureRandom random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(seed);keygen.init(128, random); // 192 and 256 bits may not be availableSecretKey key = keygen.generateKey();byte[] raw = key.getEncoded();return raw;}private static byte[] encrypt(byte[] raw, byte[] plain) throws Exception {SecretKeySpec keySpec = new SecretKeySpec(raw, "AES");Cipher cipher = Cipher.getInstance("AES");cipher.init(Cipher.ENCRYPT_MODE, keySpec);byte[] encrypted = cipher.doFinal(plain);return encrypted;}private static byte[] decrypt(byte[] raw, byte[] encrypted)throws Exception {SecretKeySpec keySpec = new SecretKeySpec(raw, "AES");Cipher cipher = Cipher.getInstance("AES");cipher.init(Cipher.DECRYPT_MODE, keySpec);byte[] decrypted = cipher.doFinal(encrypted);return decrypted;}}
0 0
- 130.短信的备份
- 短信的备份
- Android短信的备份
- 短信的备份
- 短信备份,插入一条新的短信
- 短信的备份和还原
- 短信备份
- 短信备份
- 短信备份
- 短信备份
- 短信备份
- 短信备份
- Service BroadcastReceiver备份短信的应用
- Android 实现短信的备份恢复
- Android短信的备份和回复
- android基于JSON的短信备份功能
- 备份短信和添加短信
- pys60之短信备份
- 设计模式之单例模式
- 地震干涉法(Seismic Interferometry)
- [HNOI2017]某蒟蒻的酱油记~
- C# 视频格式转换类
- Caffe--windows下的初使用及简单测试
- 130.短信的备份
- vim 及 快捷键
- 【HTML】对与HTML语言详细概述及其使用说明
- 二元位运算
- OpenCV 学习记录5 图像通道分离、对比度和亮度调整
- maven问答录
- java反射知识总结
- 部署ArcGIS API for JS时出的一个小问题及解决过程
- 对象池