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

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

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

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

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

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

反射方式获取短信

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

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

1
2
3
private static SmsMessage createFromPduGsm(byte[] pdu) throws SecurityException, IllegalArgumentException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        return createFromPdu(pdu, com.android.internal.telephony.gsm.SmsMessage);
    }

解析CDMA类型的短信

1
2
3
private static SmsMessage createFromPduCdma(byte[] pdu) throws SecurityException, IllegalArgumentException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
    return createFromPdu(pdu, com.android.internal.telephony.cdma.SmsMessage);
}

解析GSM或者CDMA类型的短信

1
2
3
4
5
6
7
8
9
10
11
private static SmsMessage createFromPdu(byte[] pdu, String className) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<!--?--> clazz = Class.forName(className);
        Object object = clazz.getMethod(createFromPdu, byte[].class).invoke(clazz.newInstance(), pdu);
        if (null != object) {
            Constructor<!--?--> constructor = SmsMessage.class.getDeclaredConstructor(Class.forName(com.android.internal.telephony.SmsMessageBase));
            constructor.setAccessible(true);
            return (SmsMessage) constructor.newInstance(object);
        } else {
            return null;
        }
    }

Android 解决双卡双待手机解析短信异常的更多相关文章

  1. 【Android】Android解析短信操作

    目录结构: contents structure [-] 获取短信 发送短信 1.获取短信 在AndroidManifest.xml中,添加权限: <uses-permission androi ...

  2. Android短彩信源码解析-短信发送流程(三)

    3.短信pdu的压缩与封装 相关文章: ------------------------------------------------------------- 1.短信发送上层逻辑 2.短信发送f ...

  3. 利用Android Lost通过互联网或短信远程控制安卓设备

    利用Android Lost通过互联网或短信远程控制安卓设备 作者:Jack Wallen| 杰克·瓦伦翻译:PurpleEndurer.2014-11-15第1版 使用智能手机要考虑的一个至关重要的 ...

  4. 2.5 使用ARDUINO做主控,手机发送短信控制开关LED

    需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...

  5. Web项目中手机注册短信验证码实现的全流程及代码

    最近在做只能净化器的后台用户管理系统,需要使用手机号进行注册,找了许久才大致了解了手机验证码实现流程,今天在此和大家分享一下. 我们使用的是榛子云短信平台, 官网地址:http://smsow.zhe ...

  6. 使用Python往手机发送短信(基于twilio模块)

    官网是https://www.twilio.com twilio的一句话介绍——提供SDK帮你连接世界上所有人,你可以很方便的调用他们提供的接口来给指定手机发短信,打电话. 首先在twilio的官网注 ...

  7. Java 实现手机发送短信验证码

    Java 实现手机发送短信验证码 采用引入第三方工具的方式,网上查了半天,发现简单的实现方式便是注册一个中国网建的账号,新建账号的时候会附带赠几条免费短信,彩信 ,之后想要在使用就得花钱了.简单的操作 ...

  8. Android安卓电话拦截及短信过滤

    package com.focus.manager; import java.lang.reflect.Method; import Android .app.Activity; import And ...

  9. Android短彩信源码解析-短信发送流程(二)

    转载请注明出处:http://blog.csdn.net/droyon/article/details/11699935 2,短彩信发送framework逻辑 短信在SmsSingleRecipien ...

随机推荐

  1. 快速发展的Swift是否将淘汰Objective-C?

    随便拉上一个果粉说说这一年来苹果公司的成就,Apple Watch肯定排第一,再下来是iPhone破销量纪录及苹果30亿美元收购Beats Electronics,消息灵通的人说不定还会提到Apple ...

  2. JS简单仿QQ聊天工具的制作

    刚接触JS,对其充满了好奇,利用刚学到的一点知识,写了一个简单的仿QQ聊天的东西,其中还有很多的不足之处,有待慢慢提高. 功能:1.在输入框中输入内容,点击发送,即可在上方显示所输入内容. 2.点击‘ ...

  3. 菜鸟Android之路(上)

    自己为什么要学android 本人作为应届毕业生,自己进入社会前做过好多梦,可是呢,现实还是打败了无邪!!面对社会的压力和残酷的竞争力自己如何生成下去??我自己对自己说:第一步 先养活自己,才能走好以 ...

  4. python is == 的区别

    要点: is 判断是否是同一个对象.是通过id来判断的    == 是通过值来判断的    为了提高内存利用率对一些简单的对象,如一些数值较小的int对象,python采用重用对象内存的方法 例如指向 ...

  5. Cloud Insight 现在已经支持监控 Cassandra 啦!

    Cassandra 是什么? Apache Cassandra 以其可扩展性和容错分布式数据库系统而被人所熟知.Cassandra 起源于Facebook 最初创建于 Amazon Dynamo 和谷 ...

  6. 自己写的一个android小应用 手电筒

    简洁 小巧 免费 无广告 代码奉上 active类 private boolean isopent = false; private Camera camera; @Override protecte ...

  7. [LeetCode] 303. Range Sum Query - Immutable (Easy)

    303. Range Sum Query - Immutable class NumArray { private: vector<int> v; public: NumArray(vec ...

  8. BZOJ3132: 上帝造题的七分钟

    3132: 上帝造题的七分钟 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 483  Solved: 222[Submit][Status] Desc ...

  9. 还能输入多少字?(JS动态计算)

    <div class="m-form ovh"> <div class="hd"> <span class="fr&qu ...

  10. linux下出现+ ls --color=auto -l --color=auto...++ echo -ne '\033]0;root@imon-2:~'等

    [root@imon-2 ~]# cd /root/ + cd /root/ ++ echo -ne '\033]0;root@imon-2:~' [root@imon-2 ~]# ll + ls - ...