哪个api可以变更sim卡续约api模式是什么意思

2523人阅读
android serviceManager集合(17)
SubscriptionManager
Subscription可以理解为卡上的一个信息单元,里面包含了卡的一些必要信息。
SubscriptionData是Subscription的一个集合。
SubscriptionManager总体上是一个Handler,主要以消息驱动。
维护几个信息:
1.用户指定的Subscription
&&&&&&&&&2.当前激活的Subscription
&&&&&&&&&3.准备好的Subscription&,依赖于卡状态的主动上报
&&&&&&&&&4.当前的数据Subscription
&&&&&&&&&5.设置Subscription模式?
提供两个功能:
1.&&&&&&&激活或去激活Subscription
2.&&&&&&&设置数据Subscription
3.&&&&&&&Modem修改了卡状态以后会同步做出反应
1.&&&&&&&SetUiccSubsParams&设定两个值:subId和SubscriptionStatus
2.&&&&&&&PhoneSubscriptionInfo&维护SubscriptionManager中管理的Subscription信息
&&&&&* Subscription Id
&&&&private enum SubscriptionId {
&&&&&&&&SUB1,
&&&&&&&&SUB2
这里固定了subId的叫法,与习惯不一样。
SubscriptionManager使用单例模式,但是使用getInstance()有可能得到null。
在构造SubscriptionManager的时候,会先调用getUserPreferredSubs()来把存在数据库里的卡的Subscription信息还原回mUserPrefSubs(一个SubscriptionData),如果没有就设定无效的值进去,且保存回数据库。
实例化一个CardSubscriptionManager对象,向这个对象注册三个事件:
registerForCardInfoAvailable——EVENT_CARD_INFO_AVAILABLE
registerForCardInfoUnavailable——EVENT_CARD_INFO_NOT_AVAILABLE
registerForAllCardsInfoAvailable——EVENT_ALL_CARD_INFO_AVAILABLE
向每一个Ril实例,注册三个事件:
registerForSubscriptionStatusChanged——EVENT_SUBSCRIPTION_STATUS_CHANGED
registerForOffOrNotAvailable——EVENT_RADIO_OFF_OR_NOT_AVAILABLE
registerForOn——EVENT_RADIO_ON
实例化两个激活/去激活注册器列表:
mSubDeactivatedRegistrants
mSubActivatedRegistrants
实例化两个激活/去激活队列:
mActivatePending
mDeactivatePending
从MSimPhoneFactory.getDataSubscription()获取当前数据通道使用的是哪一个Subscription
实例化mCurrentSubscriptions队列
private void updateSubPreferences() {
int activeSubCount = 0;
Subscription activeSub =
for (SubscriptionId sub: SubscriptionId.values()) {
看有几个激活的sub
if (getCurrentSubscriptionStatus(sub) == SubscriptionStatus.SUB_ACTIVATED) {
activeSubCount++;
activeSub = getCurrentSubscription(sub);
// If there is only one active subscription, set user preferred settings
// for voice/sms/data subscription to this subscription.
只有一个卡激活
if (activeSubCount == 1) {
if (MSimPhoneFactory.getDefaultSubscription() != activeSub.subId) {
设置这个卡为voice/sms/data的默认
MSimPhoneFactory.setDefaultSubscription(activeSub.subId);
如果当前的数据通道不是这张激活的卡,设置这张卡为默认数据通道。
if (mCurrentDds != activeSub.subId) {
Log.i(LOG_TAG,&mCurrentDds != activeSub.subId &);
Log.i(LOG_TAG,&activeSub
= &+activeSub);
// Currently selected DDS subscription is not in activated state.
// So set the DDS to the only active subscription available now.
// Directly set the Data Subscription Source to the only activeSub if it
// is READY. If the SUBSCRIPTION_READY event is not yet received on this
// subscription, wait for the event to set the Data Subscription Source.
SubscriptionId subId = SubscriptionId.values()[activeSub.subId];
这张卡的状态要ready
if (getCurrentSubscriptionReadiness(subId)) {
mQueuedDds = activeSub.subId;
Message callback = Message.obtain(this, EVENT_SET_DATA_SUBSCRIPTION_DONE,
Integer.toString(activeSub.subId));
logd(&update setDataSubscription to & + activeSub.subId);
mCi[activeSub.subId].setDataSubscription(callback);
mSetDdsRequired =
如果不ready,就置一个标志位,等ready了再设置,在别的函数里
Log.i(LOG_TAG,&mQueuedDds = activeSub.subId&);
// Set the flag and update the mCurrentDds, so that when subscription
// ready event receives, it will set the dds properly.
mSetDdsRequired =
mCurrentDds = activeSub.subId;
//MSimPhoneFactory.setDataSubscription(mCurrentDds);
}else if (activeSubCount & 1){
两张卡都激活了
int preferredDataSub = MSimPhoneFactory.getUserPreferredDDS();
如果现在的数据通道不是用户选择的那个,处理方式同上
if (mCurrentDds != preferredDataSub){
logd(&current dds is &+mCurrentDds+&,preferred one is &+preferredDataSub);
if (getCurrentSubscriptionReadiness(SubscriptionId.values()[preferredDataSub])){
mQueuedDds = preferredDataS
Message callback = Message.obtain(this,EVENT_SET_DATA_SUBSCRIPTION_DONE,
Integer.toString(preferredDataSub));
logd(&update dds to &+preferredDataSub);
mCi[preferredDataSub].setDataSubscription(callback);
logd(&updata dds later&);
mSetDdsRequired =
mCurrentDds = preferredDataS
* Start one deactivate from the pending deactivate request queue.
* If the deactivate is required for the DDS SUB, then initiate
* clean up the data connection and deactivate later.
* @return true if deactivate is started.
private boolean startNextPendingDeactivateRequests() {
printPendingDeactivateRequests();
遍历两张卡,对每张卡上的去激活请求进行处理
for (SubscriptionId sub: SubscriptionId.values()) {
Subscription newSub = mDeactivatePending.get(sub);
if (newSub != null && newSub.subStatus == SubscriptionStatus.SUB_DEACTIVATE) {
if (!validateDeactivationRequest(newSub)) {
// Not a valid entry. Clear the deactivate pending entry
mDeactivatePending.put(sub, null);
logd(&startNextPendingDeactivateRequests: Need to deactivating SUB : & + newSub);
if (mCurrentDds == newSub.subId && mDataActive) {
如果是当前正在用的数据通道所在的sub,先关数据
// This is the DDS.
// Tear down all the data calls on this subscription. Once the
// clean up completed, the set uicc subscription request with
// deactivate will be sent to deactivate this subscription.
logd(&Deactivate all the data calls if there is any&);
Message allDataCleanedUpMsg = Message.obtain(this, EVENT_CLEANUP_DATA_CONNECTION_DONE, mCurrentDds);
MSimProxyManager.getInstance().disableDataConnectivity(mCurrentDds, allDataCleanedUpMsg);
mSetDdsRequired =
如果不是就可以直接去激活,通过RIL的setUiccSubscription
logd(&startNextPendingDeactivateRequests: Deactivating now&);
SetUiccSubsParams setSubParam = new SetUiccSubsParams(newSub.subId, newSub.subStatus);
Message msgSetUiccSubDone = Message.obtain(this,
EVENT_SET_UICC_SUBSCRIPTION_DONE,
setSubParam);
mCi[newSub.subId].setUiccSubscription(newSub.slotId,
newSub.getAppIndex(),
newSub.subId,
newSub.subStatus.ordinal(),
msgSetUiccSubDone);
// process one request at a time!!
* Start one activate request from the pending activate request queue.
* @return true if activate request is started.
private boolean startNextPendingActivateRequests() {
printPendingActivateRequests();
遍历两张卡,对每张卡上的激活请求进行处理
for (SubscriptionId sub: SubscriptionId.values()) {
Subscription newSub = mActivatePending.get(sub);
if (newSub != null && newSub.subStatus == SubscriptionStatus.SUB_ACTIVATE) {
if (!validateActivationRequest(newSub)) {
// Not a valid entry.
Clear the pending activate request list
mActivatePending.put(sub, null);
// We need to update the phone object for the new subscription.
MSimProxyManager.getInstance().checkAndUpdatePhoneObject(newSub);
logd(&startNextPendingActivateRequests: Activating SUB : & + newSub);
SetUiccSubsParams setSubParam = new SetUiccSubsParams(newSub.subId, newSub.subStatus);
Message msgSetUiccSubDone = Message.obtain(this,
EVENT_SET_UICC_SUBSCRIPTION_DONE,
setSubParam);
mCi[newSub.subId].setUiccSubscription(newSub.slotId,
newSub.getAppIndex(),
newSub.subId,
newSub.subStatus.ordinal(),
msgSetUiccSubDone);
// process one request at a time!!
* Set Uicc Subscriptions
* Algorithm:
* 1. Process the set subscription request if not in progress, return false if
already in progress.
* 2. Read each requested SUB
* 3. If user selected a different app for a SUB and previous status of SUB is
ACTIVATED, then need to deactivate it.
Add to the pending Deactivate request Queue.
* 4. If user selected an app for SUB to ACTIVATE
Add to the pending Activate request Queue.
* 5. Start deactivate requests
* 6. If no deactivate requests, start activate requests.
In case of deactivate requests started, the pending activate requests with
be processed after finishing the deactivate.
* 7. If any set uicc subscription started, return true.
* @param subData - Contains the required SUB1 and SUB2 subscription information.
To activate a SUB, set the subStatus to ACTIVATE
To deactivate, set the subStatus to DEACTIVATE
To keep the subscription with out any change, set the sub to current sub.
* @return true if the requested set subscriptions are started.
false if there is no request to update the subscriptions
or if already a set subscription is in progress.
如果有去激活的请求先执行去激活的操作,再执行激活的操作
public boolean setSubscription(SubscriptionData subData) {
boolean ret =
// Return failure if the set uicc subscription is already in progress.
// Ideally the setSubscription should not be called when there is a
// activate/deactivate in undergoing.
Whoever calling should aware of
// set subscription status.
if (mSetSubscriptionInProgress) {
如果正在执行激活/去激活操作,直接返回false
mSubResult[0] = SUB_NOT_CHANGED;
mSubResult[1] = SUB_NOT_CHANGED;
// Check what are the user preferred subscriptions.
for (SubscriptionId subId: SubscriptionId.values()) {
// If previous subscription is not same as the requested subscription
(ie., the user must have marked this subscription as deactivate or
selected a new sim app for this subscription), then deactivate the
previous subscription.
如果当前的Subscription和参数给的不一样,且当前的是激活态,就把当前的这个去激活
if (!getCurrentSubscription(subId).equals(subData.subscription[subId.ordinal()])) {
if (getCurrentSubscriptionStatus(subId) == SubscriptionStatus.SUB_ACTIVATED) {
logd(&Need to deactivate current SUB :& + subId);
Subscription newSub = new Subscription();
newSub.copyFrom(getCurrentSubscription(subId));
newSub.subStatus = SubscriptionStatus.SUB_DEACTIVATE;
mDeactivatePending.put(subId, newSub);
} else if (getCurrentSubscriptionStatus(subId) == SubscriptionStatus.SUB_DEACTIVATED
&& subData.subscription[subId.ordinal()].subStatus == SubscriptionStatus.SUB_DEACTIVATE) {
// This subscription is already in deactivated state!
如果参数里有要激活的,就放到激活队列里
if (subData.subscription[subId.ordinal()].subStatus == SubscriptionStatus.SUB_ACTIVATE) {
logd(&Need to activate new SUB : & + subId);
Subscription newSub = new Subscription();
newSub.copyFrom(subData.subscription[subId.ordinal()]);
mActivatePending.put(subId, newSub);
先执行去激活,再激活
// Start the set uicc subscription only if
if (!mSetSubscriptionInProgress) {
boolean deactivateInProgress = startNextPendingDeactivateRequests();
if (deactivateInProgress) {
mSetSubscriptionInProgress =
processActivateRequests();
if (mSetSubscriptionInProgress) {
// No set uicc request to process.
* Sets the designated data subscription source(DDS).
* @param subscription
* @param onCompleteMsg
设置数据通道,这个是逻辑上设置,最后还要通过MsimPhoneFactory的setDataSubscription去把设置的值写到数据库里去。
public void setDataSubscription(int subscription, Message onCompleteMsg) {
logd(&setDataSubscription: mCurrentDds = &
+ mCurrentDds + & new subscription = & + subscription);
if (!getCurrentSubscriptionReadiness(SubscriptionId.values()[subscription])) {
loge(&setDataSubscription: requested SUB:& + subscription
+ & is not yet activated, returning failure&);
if(onCompleteMsg != null){
AsyncResult.forMessage(onCompleteMsg,
new RuntimeException(&Subscription not active&));
onCompleteMsg.sendToTarget();
mSetDdsCompleteMsg = onCompleteM
// If there is no set dds in progress disable the current
// active dds. Once all data connections is teared down, the data
// connections on mQueuedDds will be enabled.
// Call the MSimPhoneFactory setDataSubscription API only after disconnecting
// the current dds.
要先断开当前的数据连接,然后通过RIL的setDataSubscription去设置数据通道
mQueuedDds =
if (!mDisableDdsInProgress) {
Message allDataDisabledMsg = obtainMessage(EVENT_DISABLE_DATA_CONNECTION_DONE);
MSimProxyManager.getInstance().disableDataConnectivity(mCurrentDds, allDataDisabledMsg);
mDisableDdsInProgress =
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:71956次
积分:1070
积分:1070
排名:千里之外
原创:17篇
转载:125篇
(1)(1)(4)(16)(21)(26)(7)(4)(27)(28)(1)(8)编辑:www.fx114.net
本篇文章主要介绍了"SIM API",主要涉及到SIM API方面的内容,对于SIM API感兴趣的同学可以参考一下。
1 #include "simmgr.h"2 这些函数是SIM管理器API的一部分,它们使能管理SIM卡上存储的信息。
HRESULT SimInitialize (&& DWORD dwFlags,&& SIMCALLBACK lpfnCallBack,&& DWORD dwParam,&& LPHSIM lphSim);参数:dwFlags 指出要接受的通知,如果希望得到通知怎么设置为SIM_INIT_SIMCARD_NOTIFICATIONS (0x)否则置零
lpfnCallBack 通知消息的回调函数,参数可为空如果不想获得通知消息的话。
dwParam 各个通知消息传递的参数,参数可为空。
lphSim 指向一个后续调用的函数需要的HSIM句柄
返回值:如果成功返回S_OK,或者一个SIM_E错误常数,定义包含在SIM错误管理的常数表。
条件:Smartphone Platforms: Smartphone 2002 and laterPocket PC Platforms: Pocket PC 2002 and later操作系统版本: Windows CE 3.0 and later头文件: simmgr.h库: cellcore.lib
-----------------------------------------------------
SimGetPhonebookStatus函数得到本地通讯簿的状态。
HRESULT SimGetPhonebookStatus (&& HSIM hSim,&& DWORD dwLocation,&& LPDWORD lpdwUsed,&& LPDWORD lpdwTotal);
hSim 指向一个有效的HSIM句柄
dwLocation 一个通讯簿使用的存储库值;等于一个SIM_PBSTORAGE包含的值. 值的描述:SIM_PBSTORAGE_EMERGENCY 紧急拨号列表 SIM_PBSTORAGE_FIXEDDIALING SIM 固定的拨号列表SIM_PBSTORAGE_LASTDIALING SIM 最近的拨号列表 SIM_PBSTORAGE_OWNNUMBERS SIM 自定义的拨号列表 SIM_PBSTORAGE_SIM General SIM 仓库
lpdwUsed 使用的库的号码
lpdwTotal 库的总数
返回值:如果成功返回S_OK,或者一个SIM_E错误常数,定义包含在SIM错误管理的常数表。
条件:Smartphone Platforms: Smartphone 2002 and laterPocket PC Platforms: Pocket PC 2002 and later操作系统版本: Windows CE 3.0 and later头文件: simmgr.h库: cellcore.lib
-----------------------------------------------------
HRESULT SimReadPhonebookEntry (&& HSIM hSim,&& DWORD dwLocation,&& DWORD dwIndex,&& LPSIMPHONEBOOKENTRY lpPhonebookEntry);
hSim 包含一个有效的HSIM句柄。
dwLocation 一个通讯簿使用的存储库值;等于一个SIM_PBSTORAGE包含的值. 值的描述:SIM_PBSTORAGE_EMERGENCY 紧急拨号列表 SIM_PBSTORAGE_FIXEDDIALING SIM 固定的拨号列表SIM_PBSTORAGE_LASTDIALING SIM 最近的拨号列表 SIM_PBSTORAGE_OWNNUMBERS SIM 自定义的拨号列表 SIM_PBSTORAGE_SIM General SIM 仓库
dwIndex 要找回的入口索引
lpPhonebookEntry 一个通讯簿入口结构体的指针
返回值:如果成功返回S_OK,或者一个SIM_E错误常数,定义包含在SIM错误管理的常数表。
条件:Smartphone Platforms: Smartphone 2002 and laterPocket PC Platforms: Pocket PC 2002 and later操作系统版本: Windows CE 3.0 and later头文件: simmgr.h库: cellcore.lib
-----------------------------------------------------
HRESULT SimDeinitialize (&& HSIM hSim);
参数hSim 一个有效的已初始化的HSIM句柄
返回值:如果成功返回S_OK,或者一个SIM_E错误常数,定义包含在SIM错误管理的常数表。
条件:Smartphone Platforms: Smartphone 2002 and laterPocket PC Platforms: Pocket PC 2002 and later操作系统版本: Windows CE 3.0 and later头文件: simmgr.h库: cellcore.lib
-----------------------------------------------------
Simmgr.h这些结构体是SIM(Subscriber Identity Module)管理API的一部分,他们能够管理SIM卡的存储信息
结构体描述:
SIMCAPS (SP + PPC) SIM各种不同的地址(?)Addresses various capabilities of the SIM.
SIMFILEREFRESH (SP + PPC) 包含了那些文件已经被改变的信息
SIMLOCKINGPWDLENGTH (SP + PPC) 确定SIM最小的密码长度
SIMMESSAGE (SP + PPC) 包含一个SIM信息入口SIMMESSAGECHANGE (SP + PPC) 包含一个短信息服务(SMS)消息已经被改变的信息并且这些都是SIM上的。
SIMPBECHANGE (SP + PPC) 包含那个SIM通讯簿的入口已经改变了的信息
SIMPHONEBOOKENTRY (SP + PPC) 支持一个SIM通讯簿入口
SIMRECORDINFO (SP + PPC) 包含一个详细的SIM文件信息
/%B4%F3%C2%D7%D7%D3/blog/item/2ff7e.html
===================================================================================
SIM 管理器 API
  在 Pocket PC Phone 中,您可以使用一系列 Windows CE API 调用(统称为 SIM 管理器)来访问 SIM 卡上的信息。以下为 SIM 管理器 API(按功能分组):表 1:SIM 管理器 API
会话以调用 SimInitialize 开始,这将返回一个 SIM 句柄,此后,在调用 SIM 管理器 API 函数时均需要此句柄。通过将此句柄传递给 SimDeinitialize 来终止会话。
例子程序:
如何读取SIM卡联系人:
void&& ReadSimContact(SIMPHONEBOOKENTRY ContactOutBuf) { &HSIM&& hSim&& =&& NULL; &SIMCAPS&&
&if&& (FAILED(SimInitialize(SIM_INIT_NONE,&& NULL,&& 0,&& &hSim))) & &if&& (FAILED(SimGetDevCaps(hSim,&& SIM_CAPSTYPE_PBINDEXRANGE,&& &simcaps))) &
&DWORD& dwRecNum = 0; &DWORD dwCurRec = 0; &dwRecNum = simcaps.dwMaxPBIndex - simcaps.dwMinPBIndex+1; &dwCurRec = simcaps.dwMinPBI
&while( dwCurRec &= dwRecNum ) &{ & if( SimReadPhonebookEntry(hSim, SIM_PBSTORAGE_SIM, dwCurRec, &ContactOutBuf) == S_OK)//If the index is unused & { && dwCurRec++;& }& else//联系人已经读完 跳出循环& {&&& }&} &SimDeinitialize(hSim); &hSim =& NULL; }
写入SIM卡联系人:
BOOL&& WriteSimContact(SIMPHONEBOOKENTRY ContactInBuf) { &HSIM&& hSim&& =&& NULL; &SIMCAPS&&
&if&& (FAILED(SimInitialize(SIM_INIT_NONE,&& NULL,&& 0,&& &hSim))) & return FALSE; &if&& (FAILED(SimGetDevCaps(hSim,&& SIM_CAPSTYPE_PBINDEXRANGE,&& &simcaps))) & return FALSE;
&DWORD& dwRecNum = 0; &DWORD dwCurRec = 0; &dwRecNum = simcaps.dwMaxPBIndex - simcaps.dwMinPBIndex+1; &dwCurRec = simcaps.dwMinPBI &SIMPHONEBOOKENTRY ContactOutBuf = {0};
&while( dwCurRec &= dwRecNum ) //往后写&{ & if(FAILED(SimReadPhonebookEntry(hSim, SIM_PBSTORAGE_SIM, dwCurRec, &ContactOutBuf)))//If the index is unused & {&&&&&& && if( SimWritePhonebookEntry (hSim, SIM_PBSTORAGE_SIM,dwCurRec , &ContactInBuf)== S_OK )//Write the entrySIM_PBINDEX_FIRSTAVAILABLE&& {&&&&&&&&&&&&&& dwCurRec++;&& }&& & }& else& {&&&&&&&&&&& dwCurRec++;&& & }&} &SimDeinitialize(hSim); &hSim =& NULL; &return TRUE;}
删除SIM卡联系人:
BOOL& DeleteSimContact(void) { &HSIM hSim = NULL; &SIMCAPS &&if&& (FAILED(SimInitialize(SIM_INIT_NONE,&& NULL,&& 0,&& &hSim))) &{& return FALSE; &}&if&& (FAILED(SimGetDevCaps(hSim,&& SIM_CAPSTYPE_PBINDEXRANGE,&& &simcaps))) &{& return FALSE; &}&DWORD& dwRecNum = 0; &DWORD& dwCurRec = 0; &dwRecNum = simcaps.dwMaxPBIndex - simcaps.dwMinPBIndex+1; &dwCurRec = simcaps.dwMinPBI &while( dwCurRec &= dwRecNum ) &{&& & SimDeletePhonebookEntry(hSim,SIM_PBSTORAGE_SIM,dwCurRec);& dwCurRec++; &} &SimDeinitialize(hSim); &hSim = NULL; &return TRUE;}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/woxinfei/archive//2394256.aspx
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:}

我要回帖

更多关于 api模式是什么意思 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信