今天做了一个有关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错误信息并逐一排查错误,不被表面现象迷惑

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

  1. Android开发之短信验证码示例

    在说Android中的短信验证码这个知识点前,我们首先来了解下聚合数据 聚合数据介绍 聚合数据是一家国内最大的基础数据API提供商,专业从事互联网数据服务.免费提供从天气查询.空气质量.地图坐标到金融 ...

  2. Android开发之短信

    短信主要界面:会话列表,会话详情,新建短信. 联系人主要界面:联系人列表,编辑联系人. 创建首页.首页由TabActivity表现. 在Android4.1中,TabActivity处于保护状态. T ...

  3. Android简易实战教程--第十三话《短信备份和还原~三》

    之前写过短信备份的小案例,哪里仅仅是虚拟了几条短信信息.本篇封装一个业务类,且直接通过内容提供者,访问本系统的短信信息,再提供对外接口.如果想要短信备份和短信还原,直接复制这段代码即可.对于您调用这个 ...

  4. Android项目实战--手机卫士18--读取用户的短信内容以及短信备份

    我们今天要说的就是我们手机卫士里面的高级工具里面的短信备份功能啦,其实这个软件备份的功能也很简单,就是把用户的短信读出来,然后写到一个xml或者数据库里面, 但我们这里的是读取到xml里面的. 首先我 ...

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

    各种手机助手里面都包含了短信备份这一项.短信的本分主要包含四项:内容body.事件date.方式type.号码address. 短信备份~一.使用一种很笨的方式来保存短信到xml文件中,而且保存在外部 ...

  6. Android通讯:短信

    Android通讯之短信功能实现: 使用android.telephony.SmsManager对象,可以发送短信和彩信.// 构造回调函数,短信发送结束后,会发出对应的Intent请求Intent ...

  7. android学习十四(android的接收短信)

    收发短信是每一个手机主要的操作,android手机当然也能够接收短信了. android系统提供了一系列的API,使得我们能够在自己的应用程序里接收和发送短信. 事实上接收短信主要是利用我们前面学过的 ...

  8. XmlSerializer 短信备份

    package com.itheima.mobileguard.utils; import java.io.File; import java.io.FileNotFoundException; im ...

  9. android自动获取短信验证码

    前言:android应用的自动化测试必然会涉及到注册登录功能,而许多的注册登录或修改密码功能常常需要输入短信验证码,因此有必要能够自动获得下发的短信验证码.主要就是实时获取短信信息.android上获 ...

随机推荐

  1. 通过判断cookie过期方式向Memcached中添加,取出数据(Java)

    应用场景:在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了数据库负载.缓存是解决这个问题的好办法.但是ASP.NET中的虽然已经可以实现对页面局部进行缓存,但还是不够 ...

  2. 游戏音频技术备忘 (四) Wwise Unreal Engine 集成代码浅析 (一)

    在Engine\Plugins\Wwise\Source下为主要Wwise相关代码,AkAudio文件夹下为运行时相关代码,AudiokineticTools下为编辑器工具相关代码,Audiokine ...

  3. 日志组件 logback

    一.简介 Logback是由log4j创始人设计的又一个开源日志组件.logback当前分成三个模块:logback-core,logback- classic和logback-access.logb ...

  4. Leaflet+heatmap实现离线地图加载和热力图应用

    本人博客主页:http://www.cnblogs.com/webbest/ 2017年春节已经过完,新一年的奋斗也刚刚开始.今年要经历的挑战也是大大的...不扯了. 年底前软件项目相对较多,恰巧在年 ...

  5. Vue框架Element的事件传递broadcast和dispatch方法分析

    前言 最近在学习饿了么的Vue前端框架Element,发现其源码中大量使用了$broadcast和$dispatch方法,而Element使用的是Vue2.0版本,众所周知在Vue 1.0升级到2.0 ...

  6. 理解redis高可用方案

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  7. java-4-类和对象

    一.以下代码为何无法通过编译?哪儿出错了? 错误:只定义了一个有参数的构造函数.而在主函数中定义的Foo类对象调用的是无参数的构造函数. 更改后: 二.多当个类之间有继承关系时,创建子类对象会导致父类 ...

  8. CreateWindow的出错解决

    CreateWindow返回NULL,而且GetLastError()也返回0,代码如下: WNDCLASSEX wc = {  sizeof( WNDCLASSEX ), CS_CLASSDC, N ...

  9. angular、vue使用感受

    最近开始学习并使用vue.js,并使用vue+node开发了一个移动端APP来练手,下面想聊聊我对于vue的粗浅看法,并将它和angular进行一些对比: 1.vue是一个轻量.高效的前端组件化框架, ...

  10. 软件测试作业1 — 令我印象最深的BUG

    回顾从大一到大三的学习生活,我在学习过程中遇到过许多BUG,刚开始和罗凯老师学习C++时从来没有接触过编程,那时候导致程序不能运行的原因多是语法错误和拼写错误,到了大一下学期,错误多出现在循环与条件跳 ...