高通平台双卡槽网络模式支持国内所有运营商

Part1

高通平台双卡网络模式通常是卡槽1支持4、3、2G网络,卡槽2一般会默认写为固定,在之前的android L及L以下,msm8909、msm8916平台上基本设置为GSM only,因为需求是在msm8996的android M的,所以指定平台分析下大概走一下设置流程。
从网络设置app(NetworkSetting)界面来开始定位,package/service/Telephony下的MobileNetworkSettings.java
设置网络模式的菜单是ListPreference
private ListPreference mButtonPreferredNetworkMode;
点击该Preference对应的是网络模式对应的array数组,安卓原生会把所有的网络模式都显示出来,适合调试阶段找问题,但是这样不符合市场上机型的好的界面交互.
给用户呈现的应该是上文提到的4/3/2G的网络模式菜单选择
setScreenState() 方法下通过运营商获取mccmnc来分别定制相应的网络模式菜单

先判断一下sim卡的状态
             int simState = TelephonyManager.getDefault().getSimState(mPhone.getPhoneId());
             getPreferenceScreen().setEnabled(simState != TelephonyManager.SIM_STATE_ABSENT);
             
             以下以国内电信网络模式为例,
             setEntries()设置网络模式字符串,setEntryValues设置网络模式对应的数值
if((mccmnc.equals("46003")||mccmnc.equals("46005")||mccmnc.equals("46011"))) {
    
    

            

 mButtonPreferredNetworkMode.setEntries(
                   R.array.preferred_network_mode_choices_FQ1_CT);
             mButtonPreferredNetworkMode.setEntryValues(
                   R.array.preferred_network_mode_values_FQ1_CT);
                  if(subController.getDefaultDataSubId()==subId) {
    
    //判断当前的subId是否为走数据的Sub,通常情况下,只让终端用户手动选择数据卡的网络模式
           if ((getPreferredNetworkModeForSubId()!= 22)) {
    
    
                 if (getPreferredNetworkModeForSubId()== 4) {
    
    
                     setPreferredNetworkMode(4);
                 }else
                     setPreferredNetworkMode(22);
           }
      } else if(subController.getDefaultDataSubId()!=subId){
    
    
             if((prefSet != null)) {
    
    //非数据卡,直接移除网络模式设置preference
                 prefSet.removePreference(mButtonPreferredNetworkMode);
             }
      }

另外,高通andriod M上在PhoneFeature app上直接固定了卡槽二的网络模式,更准确的说是在M之前,一直都是在以下位置把卡槽2默认设置为GSM

vendor\qcom\proprietary\qrdplus\Extension\apps\PhoneFeatures\src\com\qualcomm\qti\phonefeature\PrefNetworkRequest.java
public PrefNetworkRequest(Context context, int slot, int networkMode, Message callback) {
    
    
        super(sSyncQueue);
        mContext = context;
        mCallback = callback;
        commands = new ArrayList<PrefNetworkSetCommand>();
//屏蔽下面的代码,移除固定卡槽2的网络模式设置
        /*if (networkMode != Phone.NT_MODE_GSM_ONLY) {
            for (int index = 0; index < Constants.PHONE_COUNT; index++) {
                if (index != slot)
                    commands.add(new PrefNetworkSetCommand(index, Phone.NT_MODE_GSM_ONLY));
            }
        }*/
        if (slot >= 0 && slot < Constants.PHONE_COUNT) {
    
    
            commands.add(new PrefNetworkSetCommand(slot, networkMode));
        }
    }

而android N之后,默认网络模式有小小的改动

  frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java

            for (int phoneId = 0; phoneId < phoneCount; phoneId++) {
    
    
                mode = TelephonyManager.getTelephonyProperty(phoneId,
                         "ro.telephony.default_network",                   
                         Integer.toString(RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA)
                if (phoneId == 0) {
    
    
                    val = mode;
                } else {
    
    
                    val = val + "," + mode;
                }
            }
Part2

Part1描述的内容总结起来主要是干了两件事
1.针对不同的运营商,化繁为简,优化网络模式菜单
2.解除了卡槽2不能设置任意网络模式的限制
我们最终的目标肯定是直接就能设置好网络模式,并且作为支持热插拔的手机设备,更是要找到检测到sim的状态后,就需要设置好相应的网络模式,保证不同sim卡能准确匹配网络.
然后小提一下Modem端的NV10,这是个网络模式的NV,通过QXDM读取该NV,可以获取当前所有subId的网络模式,上层设置网络模式,实际就是对NV10做修改,另外在之前VoLte的普及度没那么高的前提下,由于CDMA在硬件上只支持单通道,所以对于电信卡的卡槽,就得及时匹配网络,否则就会出现下面的状态:
1.电信卡未注册上4G网络,那么界面显示空信号格,因为没有CDMA的网络模式被分配到电信卡的卡槽
2.电信卡注册上4G网络,一旦打电话,电信的通话需要回落到CDMA,而没有匹配的网络模式,直接导致无法呼出或被呼入

通过每次插拔卡的radio log定位到sim卡检测相关的class
frameworks\opt\telephony\src\java\com\android\internal\telephony\SubscriptionInfoUpdater.java
此处不要以mccmnc去做不同运营商来区分,最好iccid去做判断
handle处理sim卡加载后的,两个卡槽的网络模式分配,重点关注方法
private void handleSimLoaded(int slotId) {
此处就是把2个卡槽做固定判断处理,以slotId为变量参数,
尤其是电信卡

        int SubId = sirInfo.getSubscriptionId();
        int SlotId = mSubscriptionManager.getSlotId(SubId);
        int nwmode = RILConstants.PREFERRED_NETWORK_MODE;
        try {
    
    
            nwmode = android.provider.Settings.Global.getInt(
            mPhone[SlotId].getContext().getContentResolver(),
                           Settings.Global.PREFERRED_NETWORK_MODE + SubId);
            } catch (SettingNotFoundException snfe) {
    
    

}
            try {
    
    
            nwmode  = TelephonyManager.getIntAtIndex(
                             mContext.getContentResolver(),
                                  Settings.Global.PREFERRED_NETWORK_MODE, slotId);
            } catch (SettingNotFoundException retrySnfe) {
    
    

            Rlog.e(LOG_TAG, "Settings Exception Reading Value At Index for"+
                                     " Settings.Global.PREFERRED_NETWORK_MODE");
            }
        }

  }

以上读取默认的网络模式,下面以电信卡在卡槽1和移动卡在卡槽2卡作为例子,设置slotId的网络模式
isCTCard就是去判断下当前的iccid是不是电信卡的iccid

 if(isCTCard(0)&&(!isCTCard(1))) {
    
    
                logd("nw ******sim1 is CT card******");
                if (slotId == 1) {
    
    
                   if (nwmode == 16) {
    
    
                         mPhone[1].setPreferredNetworkType(16, null);
                         Settings.Global.putInt(mPhone[1].getContext().getContentResolver(),
                         Settings.Global.PREFERRED_NETWORK_MODE + SubId,
                         16);
                   logd(" nw "+" 111 CMCC card 3G mode, only sim1 is CT card 3G mode nwmode = "+ nwmode);
                      } if (nwmode == 3) {
    
    
                         mPhone[1].setPreferredNetworkType(3, null);
                         Settings.Global.putInt(mPhone[1].getContext().getContentResolver(),
                         Settings.Global.PREFERRED_NETWORK_MODE + SubId,
                         3);
                         logd(" nw "+" 111 CU card 3G mode, only sim1 is CT card 3G mode nwmode = "+ nwmode);
                      } if (nwmode == 20) {
    
    
                          mPhone[1].setPreferredNetworkType(20, null);
                          Settings.Global.putInt(mPhone[1].getContext().getContentResolver(),
                          Settings.Global.PREFERRED_NETWORK_MODE + SubId,
                          20);
                          logd(" nw "+" 111 if equals 20 set 20");
                      } if (nwmode == 1) {
    
    
                          mPhone[1].setPreferredNetworkType(1, null);
                          Settings.Global.putInt(mPhone[1].getContext().getContentResolver(),
                          Settings.Global.PREFERRED_NETWORK_MODE + SubId,
                          1);
                          logd(" nw "+" 111 if equals 1 set 1");
                       }
                      else if ((nwmode != 20)&&(nwmode != 16)&&(nwmode != 3)&&(nwmode != 1)) {
    
    
                          mPhone[1].setPreferredNetworkType(20, null);
                          Settings.Global.putInt(mPhone[1].getContext().getContentResolver(),
                          Settings.Global.PREFERRED_NETWORK_MODE + SubId,
                          20);
                          logd(" dhflogsw "+" 111 normal mode  only sim1 is CT card nwmode = "+ nwmode);
                      }
                }
                if (slotId == 0) {
    
    
                   if (nwmode == 4) {
    
    
                       mPhone[0].setPreferredNetworkType(4, null);
                       Settings.Global.putInt(mPhone[0].getContext().getContentResolver(),
                       Settings.Global.PREFERRED_NETWORK_MODE + SubId,
                       4);
                       logd(" nw "+" 111 only sim1 is CT card 3G mode ");
                   } else {
    
    
                       mPhone[0].setPreferredNetworkType(22, null);
                       Settings.Global.putInt(mPhone[0].getContext().getContentResolver(),
                       Settings.Global.PREFERRED_NETWORK_MODE + SubId,
                       22);
                       logd(" nw "+" 111 only sim1 is CT card LTE mode ");
                    }
                }
关于sim卡的检测

当手机重启或者检测到sim卡状态改变时,RIL会发起sim卡信息的查询,将读到的信息写入数据库,保存至subscriptionManager
在这里插入图片描述
这部分引用FamilyYuan的blog,链接https://blog.csdn.net/myfriend0/article/details/79364548,感谢.
另外,这部分内容是两三年前改过的东西,最近觉得有必要写出来梳理一下,如有不正确的地方,请指正.

猜你喜欢

转载自blog.csdn.net/jeephao/article/details/103394733
今日推荐