android SubscriptionInfo subid slotid phonestatue
这个小节是针对文章下面的评论加的。
frameworks/base/telephony/java/android/telephony/SubscriptionManager.java
public int getDefaultDataPhoneId() 默认数据slotId
public static int getDefaultDataSubscriptionId() 默认数据subId
public int getDefaultSmsPhoneId() 默认短信slotId
public static int getDefaultSmsSubscriptionId() 默认短信subId
public static int getDefaultVoicePhoneId() 默认通话slotId
public static int getDefaultVoiceSubscriptionId() 默认通话subId
public static int getDefaultSubscriptionId() 获取默认subId,上述三个都返回-1的话使用这个
互换方法
两个id互换的方法在SubscriptionManager类中
frameworks/base/telephony/java/android/telephony/SubscriptionManager.java
/MTK平台
public static int getSubIdUsingPhoneId(int phoneId)
public static int getSlotId(int subId)
/高通平台
public static int getSubIdbySlot(Context ctx, int slot) {
int subid[] = SubscriptionManager.getSubId(slot);
if(subid != null) {
return subid[0];
}
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
原文链接:https://blog.csdn.net/firedancer0089/article/details/59518976/
2. Subscription和SubscriptionInfo
每一张SIM卡都对应一个Subscription,用谁家的SIM卡就相当于订阅(Subscription)谁家的业务。
SIM卡的信息就是SubscriptionInfo(Subscription Information),比如iccid、MNC、MCC等,多张SIM卡就有多个SubscriptionInfo。
其中ICCID:Integrate circuit card identity,集成电路卡识别码,即SIM卡卡号,相当于手机号码的身份证。
//frameworks/base/telephony/java/android/telephony/SubscriptionInfo.java public class SubscriptionInfo implements Parcelable {//实现Parcelable是为了进程间ipc通信。(Inter-Process Communication) @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mId); //数据库id,递增主键,每一个iccid的卡会占用1个id dest.writeString(mIccId); //sim卡的iccid,每张sim卡是唯一的 dest.writeInt(mSimSlotIndex); //sim卡插入卡槽值,0是卡1,1是卡2,没有插入则是-1 dest.writeCharSequence(mDisplayName); //sim卡名称,用户可以自定义 dest.writeCharSequence(mCarrierName); //运营商名称 dest.writeInt(mNameSource); //名称来源,是用户设置或者是从sim卡读取(一般就是运营商名称)等 dest.writeInt(mIconTint); //sim卡图标染色值,tint的概念可以百度google dest.writeString(mNumber); //sim卡关联号码 dest.writeInt(mDataRoaming); //sim卡是否启用数据漫游 dest.writeInt(mMcc); //mcc,移动国家码,3位数字,中国是460 dest.writeInt(mMnc); //mnc,移动网络码,2位数字,如00,01等,表示运营商 dest.writeString(mCountryIso); //国家iso代码 mIconBitmap.writeToParcel(dest, flags); //sim卡图标 } ...... }
它是和TelephonyProvider数据库中的siminfo对应的。
//vendor/mediatek/proprietary/packages/providers/TelephonyProvider/src/com/android/providers/telephony/TelephonyProvider.java private void createSimInfoTable(SQLiteDatabase db) { if (DBG) log("dbh.createSimInfoTable:+"); db.execSQL("CREATE TABLE " + SIMINFO_TABLE + "(" + SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + SubscriptionManager.ICC_ID + " TEXT NOT NULL," + SubscriptionManager.SIM_SLOT_INDEX + " INTEGER DEFAULT " + SubscriptionManager.SIM_NOT_INSERTED + "," + SubscriptionManager.DISPLAY_NAME + " TEXT," + SubscriptionManager.CARRIER_NAME + " TEXT," + SubscriptionManager.NAME_SOURCE + " INTEGER DEFAULT " + SubscriptionManager.NAME_SOURCE_DEFAULT_SOURCE + "," + SubscriptionManager.COLOR + " INTEGER DEFAULT " + SubscriptionManager.COLOR_DEFAULT + "," + SubscriptionManager.NUMBER + " TEXT," + SubscriptionManager.DISPLAY_NUMBER_FORMAT + " INTEGER NOT NULL DEFAULT " + SubscriptionManager.DISPLAY_NUMBER_DEFAULT + "," + SubscriptionManager.DATA_ROAMING + " INTEGER DEFAULT " + SubscriptionManager.DATA_ROAMING_DEFAULT + "," + SubscriptionManager.MCC + " INTEGER DEFAULT 0," + SubscriptionManager.MNC + " INTEGER DEFAULT 0," ... + SubscriptionManager.CB_OPT_OUT_DIALOG + " INTEGER DEFAULT 1" + ");"); if (DBG) log("dbh.createSimInfoTable:-"); }
建表函数createSimInfoTable,常量都是在SubscriptionManager中定义,可以从名字看出和SubscriptionInfo是对应的,当然后面mtk加了不少字段。
3. SubscriptionManager及其相关方法
SubscriptionManager为第三方app层使用,用于:
1). 获取和设置当前双卡设置(如当前默认拨号卡);
2). 进行slotid和subId转换等;
3). 获取当前的卡信息SubscriptionInfo。
SubscriptionManager //frameworks/base/telephony/java/android/telephony/SubscriptionManager.java 1). 获取SubscriptionManager对象 public static SubscriptionManager from(Context context); //SubscriptionManager mSubscrMgr = SubscriptionManager.from(mContext);//get Manager 2). 第三方app获取slot和subId public int getDefaultDataPhoneId() 默认数据slotId public static int getDefaultDataSubscriptionId() 默认数据subId public int getDefaultSmsPhoneId() 默认短信slotId public static int getDefaultSmsSubscriptionId() 默认短信subId public static int getDefaultVoicePhoneId() 默认通话slotId public static int getDefaultVoiceSubscriptionId() 默认通话subId 上述三个都返回-1的话使用 public static int getDefaultSubscriptionId() 获取默认subId 3). slotid和subId转换 public static int getSlotIndex(int subId) public static int getPhoneId(int subId) public static int[] getSubId(int slotIndex) 4). 第三方app获取SubscriptionInfo public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) //根据卡槽获取对应的SubscriptionInfo public SubscriptionInfo getActiveSubscriptionInfo(int subId) //根据subId获取对应的SubscriptionInfo
SubscriptionInfo代表了sim卡的相关数据,其常用方法如下:
SubscriptionInfo//frameworks/base/telephony/java/android/telephony/SubscriptionInfo.java public int getDataRoaming();//return the data roaming state for this subscription public CharSequence getDisplayName() ;//return the name displayed to the user that identifies this subscription public String getIccId() ; public int getMcc(); public int getMnc() ; public String getNumber();//return the number of this subscription. public int getSimSlotIndex() //return the slot index of this Subscription's SIM card. public int getSubscriptionId() //return the subscription ID - subId
可以发现,通过slotId得到对应的subId,再通过SubscriptionManager的getActiviteSubscriptionInfo()方法获取SIM卡的subscriptionInfo,进而可以获取该卡的mcc/mnc/iccid等信息。
也可以直接使用slotId,调用SubscriptionManager的getActiviteSubscriptionInfoFromSimSlotIndex()方法,获取SIM卡的subscriptionInfo。
注:由slotId得到subId,也可使用MtkSubscriptionManager(mtk自己定义的Subscription管理类)的静态方法getSubIdUsingPhoneId()
4. SubscriptionManager和SubscriptionController
SubscriptionManager是SubscriptionController的应用程序接口,提供有关当前电话订阅的信息。
SubscriptionController运行在phone进程中,是双卡相关功能正真实现端,为SubscriptionManager提供服务。
SubscriptionManager的功能基本都是通过binder调用SubscriptionController服务端来实现,使用ISub.aidl和SubscriptionController进行沟通
同理,MtkSubscriptionManager使用IMtkSub.aidl和MtkSubscriptionControllerEx进行沟通
以getSubIdUsingPhoneId()方法展示各个类之间的关系:
MtkSubscriptionManager public static int getSubIdUsingPhoneId(int phoneId) { if (VDBG) Rlog.d(LOG_TAG, "[getSubIdUsingPhoneId]+ phoneId:" + phoneId); int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; try { IMtkSub iSub = IMtkSub.Stub.asInterface(ServiceManager.getService("isubstub")); if (iSub != null) { subId = iSub.getSubIdUsingPhoneId(phoneId); } } catch (RemoteException ex) { // ignore it } return subId; }
其中MtkSubscriptionController.getMtkInstance()返回MtkSubscriptionController实例
public class MtkSubscriptionController extends SubscriptionController { public static MtkSubscriptionController getMtkInstance() { synchronized (MtkSubscriptionController.class) { return sMtkInstance; } }}
public class SubscriptionController extends ISub.Stub { public int getSubIdUsingPhoneId(int phoneId) { int[] subIds = getSubId(phoneId); if (subIds == null || subIds.length == 0) { return SubscriptionManager.INVALID_SUBSCRIPTION_ID; } return subIds[0]; } /** * Return the subId for specified slot Id. * @deprecated */ @Override @Deprecated public int[] getSubId(int slotIndex) { if (VDBG) printStackTrace("[getSubId]+ slotIndex=" + slotIndex); // Map default slotIndex to the current default subId. // TODO: Not used anywhere sp consider deleting as it's somewhat nebulous // as a slot maybe used for multiple different type of "connections" // such as: voice, data and sms. But we're doing the best we can and using // getDefaultSubId which makes a best guess. if (slotIndex == SubscriptionManager.DEFAULT_SIM_SLOT_INDEX) { slotIndex = getSlotIndex(getDefaultSubId()); if (VDBG) logd("[getSubId] map default slotIndex=" + slotIndex); } ...... // Create an array of subIds that are in this slot? ArrayList<Integer> subIds = new ArrayList<Integer>(); for (Entry<Integer, Integer> entry: sSlotIndexToSubId.entrySet()) { int slot = entry.getKey(); int sub = entry.getValue(); if (slotIndex == slot) { subIds.add(sub); } } // Convert ArrayList to array int numSubIds = subIds.size(); if (numSubIds > 0) { int[] subIdArr = new int[numSubIds]; for (int i = 0; i < numSubIds; i++) { subIdArr[i] = subIds.get(i); } if (VDBG) logd("[getSubId]- subIdArr=" + subIdArr); return subIdArr; } else { if (DBG) logd("[getSubId]- numSubIds == 0, return DummySubIds slotIndex=" + slotIndex); return getDummySubIds(slotIndex); } }}
public class SubscriptionManager { /** @hide */ public static int[] getSubId(int slotIndex) { if (!isValidSlotIndex(slotIndex)) { logd("[getSubId]- fail"); return null; } int[] subId = null; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { subId = iSub.getSubId(slotIndex); } } catch (RemoteException ex) { // ignore it } return subId; }}
作者:getskill
链接:https://www.jianshu.com/p/c43a71bf7815
评论