备份与还原短信的方法实现

首先实现备份与短信的还原需要记得添加权限:

  <uses-permission android:name="android.permission.READ_SMS"/>
  <uses-permission android:name="android.permission.WRITE_SMS"/>

 短信备份/还原工具类

 

package com.loaderman.sms.utils;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.SystemClock;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.ArrayList;

/**
 * 短信备份/还原工具类
 */

public class SmsUtils {

    //短信备份
    public static void smsBackup(Context ctx, File file, OnSmsCallback callback) throws Exception {
        //1. 读取系统的短信数据库: dta/data/android.provider.telephony/databases/mmssms.db
        //<uses-permission android:name="android.permission.READ_SMS"/>
        //<uses-permission android:name="android.permission.WRITE_SMS"/>
        Cursor cursor = ctx.getContentResolver().query(Uri.parse("content://sms"), new
                String[]{"date",
                "read", "type", "body", "address"}, null, null, null);

        //备份进度 = 当前备份条数*100/短信总个数
        int totalCount = cursor.getCount();//返回当前记录的总个数

        //修改进度条最大值为短信总数
        //dialog.setMax(totalCount);
        //将短信总数回调给上个页面
        callback.onGetTotalCount(totalCount);

        ArrayList<SmsInfo> list = new ArrayList<>();
        if (cursor != null) {

            int progress = 0;//当前备份条数
            while (cursor.moveToNext()) {
                SmsInfo info = new SmsInfo();

                info.address = cursor.getString(cursor.getColumnIndex("address"));//短信号码
                info.date = cursor.getString(cursor.getColumnIndex("date"));//短信时间
                info.read = cursor.getString(cursor.getColumnIndex("read"));//已读未读, 0表示未读,1表示已读
                info.type = cursor.getString(cursor.getColumnIndex("type"));//短信类型, 1表示接收, 2表示发送
                info.body = cursor.getString(cursor.getColumnIndex("body"));//短信内容

                list.add(info);

                progress++;

                //int percent = progress * 100 / totalCount;
                //更新进度条
                //dialog.setProgress(progress);
                //将短信进度回调给上一个页面
                callback.onProgress(progress);

                SystemClock.sleep(500);//模拟耗时
            }
        }

        // System.out.println(list);

        //2. 将短信内容保存在本地, sdcard, 数据库, sp, file
        //放在本地文件中: xxx.backup-->序列化(就是将对象转为可见的字符串), 格式, xml, json
        //json: [{address:110, date:11231232}, {},{}]
        //Gson: google json-->将对象序列化为json或将json反序列化为对象

        Gson gson = new Gson();
        String json = gson.toJson(list);

        //System.out.println("json:" + json);

        FileOutputStream out = new FileOutputStream(file);
        out.write(json.getBytes());
        out.flush();
        out.close();
    }

    //短信还原
    public static void smsRestore(Context ctx, File file, OnSmsCallback callback) throws Exception {
        //1. 从本地文件中读取短信,反序列化为对象集合
        Gson gson = new Gson();

        //初始化类型, 当集合中还有对象时需要通过此种方式来反序列化
        Type type = new TypeToken<ArrayList<SmsInfo>>() {
        }.getType();

        //读取文件流, 反序列化为集合
        ArrayList<SmsInfo> list = gson.fromJson(new FileReader(file), type);

        callback.onGetTotalCount(list.size());

        System.out.println("短信还原:" + list);

        //2. 遍历集合, 插入短信数据库
        ContentResolver resolver = ctx.getContentResolver();

        int progress = 0;
        for (SmsInfo info : list) {
            //插入短信之前,必须判断短信是否存在
            Cursor cursor = resolver.query(Uri.parse("content://sms"), null, "address=? and " +
                    "date=?" +
                    " and body=? and" +
                    " type=? and read=?", new String[]{info.address, info.date, info.body, info
                    .type, info.read}, null);

            if (cursor != null) {
                if (cursor.moveToNext()) {
                    //短信存在, 不需要插入
                    //return ? break? continue?
                    continue;//循环继续
                }

                cursor.close();
            }


            ContentValues values = new ContentValues();
            values.put("address", info.address);
            values.put("date", info.date);
            values.put("body", info.body);
            values.put("type", info.type);
            values.put("read", info.read);

            resolver.insert(Uri.parse("content://sms"), values);

            progress++;
            callback.onProgress(progress);

            SystemClock.sleep(500);
        }
    }

    public static class SmsInfo {
        public String address;
        public String date;
        public String read;
        public String type;
        public String body;

        @Override
        public String toString() {
            return "SmsInfo{" +
                    "address='" + address + '\'' +
                    ", body='" + body + '\'' +
                    '}';
        }
    }

    //声明一个回调接口
    public interface OnSmsCallback {

        //1. 获取短信的总数
        void onGetTotalCount(int totalCount);

        //2. 获取当前备份进度
        void onProgress(int progress);

    }
}

 

 备份短信的方法:

private void smsBackup() {
        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            Toast.makeText(this, "没有找到sdcard!", Toast.LENGTH_SHORT).show();
            return;
        }

        //显示备份进度条
        final ProgressDialog dialog = new ProgressDialog(this);
        dialog.setTitle("正在备份,请稍候...");
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.show();

        new Thread() {
            @Override
            public void run() {
                // SmsCallbackImpl impl = new SmsCallbackImpl();
//                impl.onProgress(10);
//                impl.onGetTotalCount(13);

                //回调-->对象的引用传递到底层, 由底层其他类调用当前对象的方法

                //短信备份
                try {
                    SmsUtils.smsBackup(getApplicationContext(), new File(Environment
                            .getExternalStorageDirectory()
                            .getAbsolutePath() + "/sms11.backup"), new SmsUtils.OnSmsCallback() {
                        @Override
                        public void onGetTotalCount(int totalCount) {
                            System.out.println("获取短信总数啦:" + totalCount);
                            dialog.setMax(totalCount);
                            progressBar.setMax(totalCount);
                        }

                        @Override
                        public void onProgress(int progress) {
                            System.out.println("获取短信进度啦:" + progress);
                            dialog.setProgress(progress);
                            progressBar.setProgress(progress);
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                    //备份失败
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(CommonToolActivity.this, "备份失败!", Toast.LENGTH_SHORT)
                                    .show();
                        }
                    });
                }

                dialog.dismiss();
            }
        }.start();
    }

 还原短信的方法

private void smsRestore() {
        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            Toast.makeText(this, "没有找到sdcard!", Toast.LENGTH_SHORT).show();
            return;
        }

        //显示还原进度条
        final ProgressDialog dialog = new ProgressDialog(this);
        dialog.setTitle("正在还原,请稍候...");
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.show();

        new Thread() {
            @Override
            public void run() {
                try {
                    SmsUtils.smsRestore(getApplicationContext(), new File(Environment
                            .getExternalStorageDirectory()
                            .getAbsolutePath() + "/sms11.backup"), new SmsUtils.OnSmsCallback() {
                        @Override
                        public void onGetTotalCount(int totalCount) {
                            dialog.setMax(totalCount);
                        }

                        @Override
                        public void onProgress(int progress) {
                            dialog.setProgress(progress);
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                    //还原失败
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(CommonToolActivity.this, "还原失败!", Toast.LENGTH_SHORT)
                                    .show();
                        }
                    });
                }

                dialog.dismiss();
            }
        }.start();
    }

    //实现回调接口
//    class SmsCallbackImpl implements SmsUtils.OnSmsCallback {
//
//        @Override
//        public void onGetTotalCount(int totalCount) {
//            System.out.println("获取短信总数啦:" + totalCount);
//        }
//
//        @Override
//        public void onProgress(int progress) {
//            System.out.println("获取短信进度啦:" + progress);
//        }
//    }
}

 

posted on 2017-03-06 08:50  LoaderMan  阅读(381)  评论(0编辑  收藏  举报

导航