Android开发遇到短信备份失败

今天做了一个有关ContentProvider的短信备份的小案例,遇到短信备份失败,费了一番周折后终于找到了问题所在

该案例是将短信写到一个xml文件然后保存在手机存储中实现短信的备份功能,关键实现代码如下

public class SmsUtils {
    public static void backUpSms(List<SmsInfo> smsInfos, Context context) {
        try {
            XmlSerializer serializer = Xml.newSerializer();
            File file = new File(Environment.getExternalStorageDirectory(), "sms.xml");
            //初始化序列化器,指定xml数据写入到哪个文件,并且指定文件的编码方式
            FileOutputStream os = new FileOutputStream(file);
            serializer.setOutput(os, "utf-8");
            serializer.startDocument("utf-8", true);
            //构建根节点
            serializer.startTag(null, "smss");
            for (SmsInfo info : smsInfos) {
                //构建父节点开始号标签
                serializer.startTag(null, "sms");
                serializer.attribute(null, "id", info.getId() + "");
                //构建子节点body
                serializer.startTag(null, "body");
                serializer.text(info.getBody());
                serializer.endTag(null, "body");
                //构建子节点address
                serializer.startTag(null, "address");
                serializer.text(info.getAddress());
                serializer.endTag(null, "address");
                //构建子节点type
                serializer.startTag(null, "type");
                serializer.text(info.getType() + "");
                serializer.endTag(null, "type");
                //构建子节点date
                serializer.startTag(null, "date");
                serializer.text(info.getDate() + "");
                serializer.endTag(null, "date");
                //父节点结束标签
                serializer.endTag(null, "sms");
            }
            serializer.endTag(null, "smss");
            serializer.endDocument();
            os.close();
            Toast.makeText(context, "备份成功", Toast.LENGTH_LONG).show();

        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(context, "备份失败", Toast.LENGTH_LONG).show();
        }
    }
}

下面是Logcat打印的信息

07-13 16:44:18.195 26990-26990/wp.contentresolver D/StubController: holdAndGetPermissionType permissionType:4 uid:10382 pid:26990
07-13 16:44:18.195 26990-26990/wp.contentresolver D/StubController: addRequestCount, mRequestCount =1 mPhoneIDRequestCount: 0 mLocationRequestCount: 0 permissionType is: 4
07-13 16:44:18.195 26990-26990/wp.contentresolver D/StubController: holdForGetPermissionSelection  mRequestCount:1
07-13 16:44:18.200 26990-26990/wp.contentresolver D/StubController: beforeShowDialogCheckResult:1
07-13 16:44:18.200 26990-26990/wp.contentresolver D/StubController: minusRequestCount, mRequestCount =0 mPhoneIDRequestCount: 0 mLocationRequestCount: 0 permissionType is: 4
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err: java.lang.IllegalArgumentException: Illegal character (d83d)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at org.kxml2.io.KXmlSerializer.reportInvalidCharacter(KXmlSerializer.java:144)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at org.kxml2.io.KXmlSerializer.writeEscaped(KXmlSerializer.java:130)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at org.kxml2.io.KXmlSerializer.text(KXmlSerializer.java:536)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at wp.contentresolver.SmsUtils.backUpSms(SmsUtils.java:56)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at wp.contentresolver.MainActivity.click(MainActivity.java:36)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at java.lang.reflect.Method.invoke(Method.java:515)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at android.view.View.performClick(View.java:4446)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at android.view.View$PerformClick.run(View.java:18480)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at android.os.Handler.handleCallback(Handler.java:733)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at android.os.Looper.loop(Looper.java:136)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5315)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at java.lang.reflect.Method.invoke(Method.java:515)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:680)
07-13 16:44:18.220 26990-26990/wp.contentresolver W/System.err:     at dalvik.system.NativeStart.main(Native Method)

由于Logcat上没有明显的错误信息,盲目的在真机上测试了多遍,都是以失败告终,代码检查了多遍也都没有问题,于是感觉是手机系统的问题,毕竟前面有过这样的情况,

就拿同学的手机测试了一下,结果显示备份成功了,猜想是正确的吗?  --当然不是,看着Logcat上的错误信息,继续了探究,询问了导员后,开始了错误的排查,问题最终就是定位在将短信写入xml上,

首先将增强for循环去掉,只写了一个简单的头尾节点,结果成功了,又依次增加了几个子节点,将text写成固定的内容,运行起来备份又成功了,因此,可以知道自己的真机可以正常的写xml文件

又将节点中text属性固定的内容改成了动态的读取短信的内容(serializer.text(smsInfos.get(0).getBody());),这样真机也可以正常的读取短信内容并可以将其写入xml中,

最后就是for循环的问题,因为写单独的节点可以正常读取,而读取全部信息就失败,所以可以说明是其中某个信息有问题,仔细查看了一下真机上的信息,发现里面有表情,于是将所有带表情的信息都删除了,

又重新运行了一下备份,结果成功了,问题终于被解决了,不是手机系统的问题,原来是编码的转换问题,短信中的那种表情(自带的除外)不能正常的转换utf-8格式字符,导致备份失败,后来又结合了错误日志,

上面报了一个java.lang.IllegalArgumentException: Illegal character (d83d)的信息,意思是非法参数异常,下面还在body节点处报了一个错误,所以可以得出,是信息内容的问题

所以,以后一定要仔细查看Logcat错误信息并逐一排查错误,不被表面现象迷惑

时间: 2024-08-02 11:03:22

Android开发遇到短信备份失败的相关文章

Android开发删除短信

本人一直有一个需求,想要手机自动拦截黑名单里联系人的信息并自动删除这些短信,手机管家之类的软件可以拦截但是没找到能删除这些短信的,于是就萌生了想自己写一个android软件的想法. 加上物联网的兴起,安卓设备开发肯定前景很好. 随后又得知 安卓开发可以用java语言,就用eclipse,呵呵,本人还是有些java基础的,于是乎,本人就开始扑腾了. 把eclipse sdk adt搭建好之后,本人就开始了开发这款自动拦截并删除黑名单短信的软件.都已经实现. 在编写过程中,删除短信的模块倒是坑了我挺

Qt for Android 开发的短信程序

http://book.zhulang.com/299065/734548.html http://book.zhulang.com/299065/734549.html http://book.zhulang.com/299065/734550.html http://book.zhulang.com/299065/734551.html http://book.zhulang.com/299065/734552.html http://book.zhulang.com/299065/7345

Android开发短信备份小例子

主要是使用内容提供者ContentProvider #1.在activity_main.xml布局文件中添加写sdcard权限,并添加读短信的权限 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_par

Android简易实战教程--第八话《短信备份~一》

各种手机助手里面都包含了短信备份这一项.短信的本分主要包含四项:内容body.事件date.方式type.号码address. 短信备份~一.使用一种很笨的方式来保存短信到xml文件中,而且保存在外部存储.后续会有:短信备份~二(xml序列化器):短信备份~三(内容提供者获取短信xml备份):短信备份~四(json方式备份数据库短信).备份的方式越来越高效,比较不同存储方式. 很显然,初次介绍短信备份,以一种简单笨拙的方式,且不涉及内容提供者,虚拟10条短信. 短信的保存,要以对象的形式保存.因

自制Android中的短息备份器源码

短信的实体bean package com.examp.backsms.domain; public class SmsInfo { private String address; private String date; private String type; private String body; public SmsInfo() { } public SmsInfo(String address, String date, String type, String body) { thi

手机卫士07_自定义吐司_桌面小火箭_短信备份_接口和回调_应用程序信息,

1,自定义吐司显示风格 ①创建一个布局文件(代码注册的View看不出效果,所以还是定义布局文件比较好) 这里的背景是.9图片会根据包裹内容来拉伸 ②在显示自定义吐司的界面,显示的吐司通过View.inflate()创建 ③在设置中心增加一条修改归属地显示风格. {"半透明","活力橙","卫士蓝","金属灰","苹果绿"}; 点击之后弹出一个单选对话框. builder.setSingleChoiceIte

android 访问SMS短信收件箱

访问 SMS收件箱是另一个常见的需求.首先,需要将读取 SMS 的权限 <uses-permission android:name="android.permission.READ_SMS"/> 添加到描述文件中.添加此权限后就可以读取SMS收件箱中的 短消息了. 要读取 SMS 消息,必须对SMS收件箱执行查询,下面是我们的 代码清单. 布局文件 <?xml version="1.0" encoding="utf-8"?>

短信备份(原)

昨天在学习回调的时候,发现了其独特的魅力之处,它将业务代码逻辑和我们的工具类耦合性大大降低了. 应用场景:在实际开发中,经常会随着用户的需求的改变而对对话框的样式进行相应修改,在短信的备份过程中,往往需要给用户显示一个对话框,以提示用户进度. 常见的回调的步骤分为4步: //1,定义一个接口 //2,定义业务逻辑的抽象2个方法 //3,传递一个实现了第一步接口的实现类的对象进来(实现了未实现的抽象方法(将抽象的逻辑具体话)) //4,在合适的地方去调用实现类对象中,已经实现好的方法 代码如下:

android 添加手机短信,获取手机短信,删除手机短信和修改手机短信

注意添加权限: <uses-permission android:name="android.permission.READ_SMS"></uses-permission> <uses-permission android:name="android.permission.WRITE_SMS"></uses-permission> 代码如下: //更新短信 private void UpdateSMS() { /* u