天天看點

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

plaincopy

Android 解決雙卡雙待手機解析短信異常
Android 解決雙卡雙待手機解析短信異常

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) { // 解決雙卡雙待類型手機解析短信異常問題  

                        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();  

            }  

        }  

        return msgs;  

    }  

反射方式擷取短信

Android 解決雙卡雙待手機解析短信異常
Android 解決雙卡雙待手機解析短信異常

/** 

     * 使用java反射機制擷取短信資訊(解決雙卡雙待手機解析短信異常問題,優先解析gsm類型的短信,假如解析失敗才按cdma類型的短信進行解析) 

     *  

     * @param intent 

     * @return 

     */  

    private static smsmessage[] getsmsmessagebyreflect(intent intent) {  

                    smsmessage message = createfrompdugsm((byte[]) messages[i]);  

                    if (null == message) {  

            } catch (securityexception e) {  

            } catch (illegalargumentexception e) {  

            } catch (classnotfoundexception e) {  

            } catch (nosuchmethodexception e) {  

            } catch (illegalaccessexception e) {  

            } catch (invocationtargetexception e) {  

            } catch (instantiationexception e) {  

通過java反射機制解析gsm類型的短信:

Android 解決雙卡雙待手機解析短信異常
Android 解決雙卡雙待手機解析短信異常

private static smsmessage createfrompdugsm(byte[] pdu) throws securityexception, illegalargumentexception, classnotfoundexception, nosuchmethodexception, illegalaccessexception, invocationtargetexception, instantiationexception {  

        return createfrompdu(pdu, "com.android.internal.telephony.gsm.smsmessage");  

解析cdma類型的短信

Android 解決雙卡雙待手機解析短信異常
Android 解決雙卡雙待手機解析短信異常

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類型的短信

Android 解決雙卡雙待手機解析短信異常
Android 解決雙卡雙待手機解析短信異常

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;  

    }  

繼續閱讀