CDMA手机两种实现模式:
机卡分离式:用户信息写在单独的UIM卡
机卡一体式:用户信息写在手机中的
这个跟CDMA Subscription模式有关,对于我们来说使用的是独立UIM卡,在软件里面使用什么方式,跟一项NV值有关,但这项值却无法使用QXDM来更改,确切的说是改了,重新开机之后值又被写回去了,
所以这项NV值应当是在代码中设置的,高通一直说在网络设置里面,但是也一直没有找到,看了代码才知道由于某种原因没显示出来,都不管了,直接找到CDMA信息读取模式设置代码改成UIM模式即可。
下面看这个设置的过程:
public static void makeDefaultPhone(Context context) { //Get cdmaSubscription mode from Settings.Secure
int cdmaSubscription; //从数据库读取cdma Subscription 默认preferredCdmaSubscription
cdmaSubscription = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.CDMA_SUBSCRIPTION_MODE, preferredCdmaSubscription); Log.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription); //传递cdma Subscription 创建RIL
sCommandsInterface = new RIL(context, networkMode, cdmaSubscription); …… }
这里默认的preferredCdmaSubscription就是
preferredCdmaSubscription = CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION;
而PREFERRED_CDMA_SUBSCRIPTION = SUBSCRIPTION_FROM_NV;
这里看到从NV中读取,即用户信息存储在手机上,cdma Subscription的信息都在CdmaSubscriptionSourceManager这个类中维护
但是这跟关于这个NV项有什么关系呢?
public RIL(Context context, int preferredNetworkType, int cdmaSubscription, Integer instanceId) { mCdmaSubscription = cdmaSubscription; } private void processUnsolicited (Parcel p) { case RIL_UNSOL_RIL_CONNECTED: { // Initial conditions
setRadioPower(false, null); setPreferredNetworkType(mPreferredNetworkType, null); //启动RIL建立连接之后,会设置Cdma Subscription 这就是创建java层RIL时传递的 //此处应当传递到modem,设置了相关的NV项,所以使用工具更改此NV不起作用
setCdmaSubscriptionSource(mCdmaSubscription, null); break; } }
所以关于Cdma Subscription 模式的设置,应当重点关注
CdmaSubscriptionSourceManager
这个类很简单,是一个Handler,监听维护CDMA subscription模式;
// Constructor
private CdmaSubscriptionSourceManager(Context context, CommandsInterface ci) { mContext = context; mCM = ci; //监听Cdma Subscription 模式变化
mCM.registerForCdmaSubscriptionChanged(this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); mCM.registerForOn(this, EVENT_RADIO_ON, null); //设置当前Cdma Subscription 获取默认的
int subscriptionSource = getDefaultCdmaSubscriptionSource(); mCdmaSubscriptionSource.set(subscriptionSource); }
其他模块获取当前CDMA Subscription模式
public int getCdmaSubscriptionSource() { return mCdmaSubscriptionSource.get(); }