zoukankan      html  css  js  c++  java
  • Android 解决双卡双待手机解析短信异常

    开发中,难免会遇到各种各样的适配问题,尤其是经过深度修改定制过的系统,有的无论是软硬件上都有很大的区别,这里不得不提到一种奇葩的机型,没错,那就是双卡双待的手机(比如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;
            }
        }



     

  • 相关阅读:
    Redis 外网无法访问
    设计模式单例模式
    网易笔试问答(20210328)新生代转移到老年代的情况
    网易笔试(20210327)最长摇摆子数组长度
    网易笔试(20210327)吉利数(子数组中数组和为6的倍数的最大子数组和)
    360笔试(20210328)射气球
    解决TFS 错误:[TF15013 请求的 Team Foundation Server 未向代理服务器注册]
    TFS 常用命令
    生成安全的用于加密的随机数
    一种新的验证码(改进版)
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/3668306.html
Copyright © 2011-2022 走看看