Android 解决双卡双待手机解析短信异常

简介:

http://blog.csdn.net/t12x3456/article/details/17339657

开发中,难免会遇到各种各样的适配问题,尤其是经过深度修改定制过的系统,有的无论是软硬件上都有很大的区别,这里不得不提到一种奇葩的机型,没错,那就是双卡双待的手机(比如XT800, A60, S8600 , Lenovo A750,中兴V889D等).由于是双SIM卡,而且两个卡槽支持的运营商或者网络制式不一定相同,比如一个卡槽支持WCDMA,另一个却只支持GSM ,导致用正常方法解析短信很容易遇到异常


想深入了解双卡双待手机短信发送与接收流程的话,请看我之前关于 MMS的分析:

Android 短信模块分析(四) MMS之短信的发送与接收


这里先看下解决方案,这里需要以反射的方式解析不同类型的短信,并且对于不同机型,需对应地进行调整适配:


获取短信信息,注意:为解决双卡双待手机解析短信异常问题,使用Java反射机制,优先解析GSM类型的短信,假如解析失败才按CDMA类型的短信进行解析)

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static SmsMessage[] getSmsMessage(Intent intent) {  
  2.         SmsMessage[] msgs = null;  
  3.         Object messages[] = (Object[]) intent.getSerializableExtra("pdus");  
  4.         int len = 0;  
  5.         if (null != messages && (len = messages.length) > 0) {  
  6.             msgs = new SmsMessage[len];  
  7.             try {  
  8.                 for (int i = 0; i < len; i++) {  
  9.                     SmsMessage message = null;  
  10.                     if ("GSM".equals(intent.getStringExtra("from"))) { // 适配MOTO XT800双卡双待手机  
  11.                         message = createFromPduGsm((byte[]) messages[i]);  
  12.                     } else if ("CDMA".equals(intent.getStringExtra("from"))) { // 适配MOTO XT800双卡双待手机  
  13.                         message = createFromPduCdma((byte[]) messages[i]);  
  14.                     } else {  
  15.                         message = SmsMessage.createFromPdu((byte[]) messages[i]); // 系统默认的解析短信方式  
  16.                     }  
  17.                     if (null == message) { // 解决双卡双待类型手机解析短信异常问题  
  18.                         message = createFromPduGsm((byte[]) messages[i]);  
  19.                         if (null == message) {  
  20.                             message = createFromPduCdma((byte[]) messages[i]);  
  21.                         }  
  22.                     }  
  23.                     if (null != message) {  
  24.                         msgs[i] = message;  
  25.                     }  
  26.                 }  
  27.             } catch (Exception e) {  
  28.                 e.printStackTrace();  
  29.                 msgs = getSmsMessageByReflect(intent); // 解决双卡双待手机解析短信异常问题  
  30.             } catch (Error er) {  
  31.                 er.printStackTrace();  
  32.                 msgs = getSmsMessageByReflect(intent); // 解决双卡双待手机解析短信异常问题  
  33.             }  
  34.         }  
  35.         return msgs;  
  36.     }  


反射方式获取短信

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.      * 使用Java反射机制获取短信信息(解决双卡双待手机解析短信异常问题,优先解析GSM类型的短信,假如解析失败才按CDMA类型的短信进行解析) 
  3.      *  
  4.      * @param intent 
  5.      * @return 
  6.      */  
  7.     private static SmsMessage[] getSmsMessageByReflect(Intent intent) {  
  8.         SmsMessage[] msgs = null;  
  9.         Object messages[] = (Object[]) intent.getSerializableExtra("pdus");  
  10.         int len = 0;  
  11.         if (null != messages && (len = messages.length) > 0) {  
  12.             msgs = new SmsMessage[len];  
  13.             try {  
  14.                 for (int i = 0; i < len; i++) {  
  15.                     SmsMessage message = createFromPduGsm((byte[]) messages[i]);  
  16.                     if (null == message) {  
  17.                         message = createFromPduCdma((byte[]) messages[i]);  
  18.                     }  
  19.                     if (null != message) {  
  20.                         msgs[i] = message;  
  21.                     }  
  22.                 }  
  23.             } catch (SecurityException e) {  
  24.                 e.printStackTrace();  
  25.             } catch (IllegalArgumentException e) {  
  26.                 e.printStackTrace();  
  27.             } catch (ClassNotFoundException e) {  
  28.                 e.printStackTrace();  
  29.             } catch (NoSuchMethodException e) {  
  30.                 e.printStackTrace();  
  31.             } catch (IllegalAccessException e) {  
  32.                 e.printStackTrace();  
  33.             } catch (InvocationTargetException e) {  
  34.                 e.printStackTrace();  
  35.             } catch (InstantiationException e) {  
  36.                 e.printStackTrace();  
  37.             }  
  38.         }  
  39.         return msgs;  
  40.     }  



通过Java反射机制解析GSM类型的短信:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private static SmsMessage createFromPduGsm(byte[] pdu) throws SecurityException, IllegalArgumentException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {  
  2.         return createFromPdu(pdu, "com.android.internal.telephony.gsm.SmsMessage");  
  3.     }  

解析CDMA类型的短信

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private static SmsMessage createFromPduCdma(byte[] pdu) throws SecurityException, IllegalArgumentException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {  
  2.     return createFromPdu(pdu, "com.android.internal.telephony.cdma.SmsMessage");  
  3. }  

解析GSM或者CDMA类型的短信

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private static SmsMessage createFromPdu(byte[] pdu, String className) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {  
  2.         Class<?> clazz = Class.forName(className);  
  3.         Object object = clazz.getMethod("createFromPdu"byte[].class).invoke(clazz.newInstance(), pdu);  
  4.         if (null != object) {  
  5.             Constructor<?> constructor = SmsMessage.class.getDeclaredConstructor(Class.forName("com.android.internal.telephony.SmsMessageBase"));  
  6.             constructor.setAccessible(true);  
  7.             return (SmsMessage) constructor.newInstance(object);  
  8.         } else {  
  9.             return null;  
  10.         }  
  11.     }  

相关文章
|
21天前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
51 1
|
27天前
|
缓存 Kubernetes 网络协议
阿里云DNS常见问题之在手机上使用阿里的私人dns失败如何解决
阿里云DNS(Domain Name System)服务是一个高可用和可扩展的云端DNS服务,用于将域名转换为IP地址,从而让用户能够通过域名访问云端资源。以下是一些关于阿里云DNS服务的常见问题合集:
|
2月前
|
监控 安全 Android开发
【新手必读】Airtest测试Android手机常见的设置问题
【新手必读】Airtest测试Android手机常见的设置问题
|
4月前
|
XML Java Android开发
Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信)
Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信)
82 0
|
3月前
|
存储 算法 安全
AVB数据解析:Android verified boot 2.0 vbmeta 数据结构解析
AVB数据解析:Android verified boot 2.0 vbmeta 数据结构解析
132 0
|
1月前
|
编译器 开发工具 Android开发
Android 12 新特性深度解析
【2月更文挑战第15天】 随着移动操作系统的不断进化,Android 12带来了一系列创新功能与性能提升。本文将深入剖析Android 12的核心新特性,包括隐私仪表盘、通知管理、设备控制以及性能优化等方面,为开发者和用户提供全面的更新指南。
|
3月前
|
JSON Java Android开发
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
Android网络和数据交互: 请解释Android中的JSON解析库,如Gson。
24 0
|
3月前
|
安全 网络协议 Linux
【公网远程手机Android服务器】安卓Termux搭建Web服务器
【公网远程手机Android服务器】安卓Termux搭建Web服务器
64 0
|
4月前
|
Android开发 容器
[Android]View的事件分发机制(源码解析)
[Android]View的事件分发机制(源码解析)
36 0
|
4月前
|
传感器 物联网 Android开发
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
67 1

推荐镜像

更多