andorid中APN与SPN相关的设置相关

2024-01-05 03:48
文章标签 设置 相关 andorid spn apn

本文主要是介绍andorid中APN与SPN相关的设置相关,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

APN:

一,简介

APN全称是Access Point Name,是手机上网必须要配置的一个参数,用来决定手机是通过哪一种接入方式来访问网络。

接入方式:在国外,接入方式有很多,比如:gprs;hscsd;WAP;edge等等。国内的接入方式目前一般只有gprs。而gprs在运营

                商那里被人为的划分为几种。

     国内分类:

         移动:cmwap 和 cmnet。
         联通:分为UNIWAP/3GWAP,UNINET/3GNET,对应划分的G网,W网(即2G,3G网)
                  (注:彩信之所以单独配置接入点是因为彩信服务需要连接专用的服务器)
那么为什么会有两个接入点呢?
      WAP:采用的实现方式是“终端+WAP网关+WAP服务器”的模式,通过WAP网关完成WAP-WEB的协议转换以达到节省网络流量和兼容现有WEB应用的目的。
      Internet:“终端+服务器”的工作模式。
      Cmwap: 对网络接入作了一定的限制,只能访问WAP业务。
      Cmnet: 直连Internet。

国内接入点的分类一般是这几个,但是海外的接入点各不相同,一个运营商可以有好几个不同的接入点,这个跟运营商有关。


二.使用路径


了解了有关于接入方式的分类,我们来看看APN的使用。apn和spn在手机里的路径为:
        System/etc/apn-conf.xml
        System/etx/spn-conf.xml
apn和spn一般会直接存入数据库中,数据库的位置在:
           /data/data/com.android.providers.telephony/databases/ telephony.db/Carriers表

在每一个项目的开始时,都需要配置一下,平台上默认的spn和apn的一般是在/device/sprd/scx35l/device.mk中配置:

       APN_VERSION := $(shell cat frameworks/base/core/res/res/xml/apns.xml|grep "<apns version"|cut -d \" -f 2)
       PRODUCT_COPY_FILES += vendor/sprd/overlay/apn/apns-conf_$(APN_VERSION).xml:system/etc/apns-conf.xml

当然,也有可能不是在这个地方配置,apn的位置也不一定在vendor/sprd/overlay/apn/下,我们可以执行grep -rin "spn-conf*.xml" ./搜索一下,然后在我们项目的mk中配置就好了。如下:

      PRODUCT_COPY_FILES += $(BOARDDIR)/apns-conf.xml:system/etc/apns-conf.xml
      PRODUCT_COPY_FILES += $(BOARDDIR)/spn-conf.xml:system/etc/spn-conf.xml


三.apn配置详解


Apn配置的几个关键字段:
      Apn type的5种类型:

            1.default(默认网络连接),

            2.supl(Secure User Plane Location安全用户面定位),

            3.mms(彩信专用连接),

            4.hipri(高优先级网络),

            5.dun(Dial Up Networking拨号网络)
       注意:此表中的数据连接优先级是由低到高,即default数据连接的优先级最低,而hipri数据连接的优先级最高。比如:手机上网聊天,建立的是default数据连接。如果此时接到一条彩信,由于彩信的数据连接是mms,优先级比default高,所以会先断开default数据连接,建立mms数据连接,让手机先收到彩信。所以收发彩信的同时不能上网。
            在启动手机时,需要初始化telephony.db数据库,这时候会读取手机目录System/etc/apn-conf.xml并把其中的内容加入到Carriers表中。以后查询有关apn的配置参数都是从Carriers表中取出。

创建并初始化Carriers表:packages/providers/TelephonyProvider/src/com/android/providers/telephony/TelephonyProvider.java

 内部类:DatabaseHelper.java

 public void onCreate(SQLiteDatabase db) {// Set up the database schema// SPRD : for multi-simfor (int i = 0; i < TelephonyManager.getPhoneCount(); i++) {db.execSQL("CREATE TABLE " + (CARRIERS_TABLE + i) +"(_id INTEGER PRIMARY KEY," +"name TEXT," +"numeric TEXT," +"mcc TEXT," +"mnc TEXT," +"apn TEXT," +"user TEXT," +"server TEXT," +"password TEXT," +"proxy TEXT," +"port TEXT," +"mmsproxy TEXT," +"mmsport TEXT," +"mmsc TEXT," +"authtype INTEGER," +"type TEXT," +"current INTEGER," +"protocol TEXT," +"preload TEXT," +"roaming_protocol TEXT," +"carrier_enabled BOOLEAN," +"bearer INTEGER," +"mvno_type TEXT," +"mvno_match_data TEXT);");}/* SPRD : for multi-sim @{ */// initDatabase(db);SharedPreferences sharedPreferences = mContext.getSharedPreferences(NEED_INSERT_CONFIG,Context.MODE_PRIVATE);Editor editor = sharedPreferences.edit();editor.putBoolean(NEED_INSERT, true);editor.commit();/* @} */}private void initDatabase(SQLiteDatabase db, int phoneId) {…XmlPullParser confparser = null;File confFile = new File(Environment.getRootDirectory(), PARTNER_APNS_PATH);FileReader confreader = null;confreader = new FileReader(confFile);confparser = Xml.newPullParser();confparser.setInput(confreader);XmlUtils.beginDocument(confparser, "apns");loadApns(db, confparser, phoneId);…}private void loadApns(SQLiteDatabase db, XmlPullParser parser ,int phoneId) {if (parser != null) {db.beginTransaction();XmlUtils.nextElement(parser);while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {ContentValues row = getRow(parser);if (row == null) {throw new XmlPullParserException("Expected 'apn' tag", parser, null);}/* SPRD : for multi-sim @{ *///insertAddingDefaults(db, CARRIERS_TABLE, row);insertAddingDefaults(db, getTableNameByPhoneId(phoneId), row);/* SPRD : for multi-sim @{ */XmlUtils.nextElement(parser);}db.setTransactionSuccessful();}}private void insertAddingDefaults(SQLiteDatabase db, String table, ContentValues row) {// Initialize defaults if anyif (row.containsKey(Telephony.Carriers.AUTH_TYPE) == false) {row.put(Telephony.Carriers.AUTH_TYPE, -1);}if (row.containsKey(Telephony.Carriers.PROTOCOL) == false) {row.put(Telephony.Carriers.PROTOCOL, "IPV4V6");}if (row.containsKey(Telephony.Carriers.ROAMING_PROTOCOL) == false) {row.put(Telephony.Carriers.ROAMING_PROTOCOL, "IPV4V6");}if (row.containsKey(Telephony.Carriers.CARRIER_ENABLED) == false) {row.put(Telephony.Carriers.CARRIER_ENABLED, true);}if (row.containsKey(Telephony.Carriers.BEARER) == false) {row.put(Telephony.Carriers.BEARER, 0);}if (row.containsKey(Telephony.Carriers.MVNO_TYPE) == false) {row.put(Telephony.Carriers.MVNO_TYPE, "");}if (row.containsKey(Telephony.Carriers.MVNO_MATCH_DATA) == false) {row.put(Telephony.Carriers.MVNO_MATCH_DATA, "");}/* SPRD : for multi-sim @{ *///db.insert(CARRIERS_TABLE, null, row);db.insert(table, null, row);/* @} */}
}设置APN:
packages/apps/Settings/src/com/android/settings/ApnSettings.java@Overrideprotected void onResume() {super.onResume();registerReceiver(mMobileStateReceiver, mMobileStateFilter);/** SPRD: Bug 327811 title add phoneId @{ */if (TelephonyManager.isMultiSim()) {this.setTitle(getResources().getString(R.string.apn_settings_ex, mPhoneId + 1));}/** @} */if (!mRestoreDefaultApnMode) {fillList();} else {showDialog(DIALOG_RESTORE_DEFAULTAPN);}}private void fillList() {String where;Uri contentUri = Telephony.Carriers.getContentUri(mPhoneId,null);if (TelephonyManager.isMultiSim()) {where = "numeric=\""+ android.os.SystemProperties.get(TelephonyManager.getProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, mPhoneId), "")+ "\"";} else {where = "numeric=\""+ android.os.SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "")+ "\"";}where += " and name!='CMCC DM'";Log.d(TAG,"where = " + where);Cursor cursor = getContentResolver().query(contentUri, new String[] {"_id", "name", "apn", "type"}, where, null,null);/* @} */if (cursor != null) {PreferenceGroup apnList = (PreferenceGroup) findPreference("apn_list");apnList.removeAll();ArrayList<Preference> mmsApnList = new ArrayList<Preference>();/* SPRD: add by spreadst @{ */String firstKey = null;boolean hasKey = false;ApnPreference firstPref = new ApnPreference(this);/* @} */mSelectedKey = getSelectedApnKey();Log.d(TAG, "mSelectedKey = " + mSelectedKey);cursor.moveToFirst();while (!cursor.isAfterLast()) {String name = cursor.getString(NAME_INDEX);String apn = cursor.getString(APN_INDEX);String key = cursor.getString(ID_INDEX);String type = cursor.getString(TYPES_INDEX);Log.d(TAG, "name = " + name + "apn = " + apn + "key = " + key + "type = " + type);ApnPreference pref = new ApnPreference(this);pref.setKey(key);pref.setTitle(name);pref.setSummary(apn);pref.setPersistent(false);pref.setOnPreferenceChangeListener(this);/* SPRD: for multi-sim @{*/// boolean selectable = ((type == null) || !type.equals("mms"));boolean selectable = ((type == null) || (type.indexOf("default") != -1)|| (type.equals("*")));/* @} */pref.setSelectable(selectable);if (selectable) {if ((mSelectedKey != null) && mSelectedKey.equals(key)) {pref.setChecked();hasKey = true;Log.d(TAG, "mSelectedKey has a value: firstKey = " + firstKey + " hasKey = " + hasKey + " firstPref = " + firstPref);} else if (mSelectedKey == null) {pref.setChecked();hasKey = true;Log.d(TAG, "mSelectedKey is null: firstKey = " + firstKey + " hasKey = " + hasKey + " firstPref = " + firstPref);setSelectedApnKey(key);}apnList.addPreference(pref);// if mSelectedKey dose not match with the operator,// remember the first key as firstKeyif (firstKey == null) {firstPref = pref;firstKey = key;}} else {mmsApnList.add(pref);}cursor.moveToNext();}cursor.close();for (Preference preference : mmsApnList) {apnList.addPreference(preference);}/* SPRD: add by spreadst @{ */// set firstKey to be SelectedApnKeyif (!hasKey) {firstPref.setChecked();setSelectedApnKey(firstKey);}Log.d(TAG, "Final: firstKey = " + firstKey + " hasKey = " + hasKey + " firstPref = " + firstPref);Log.d(TAG,"apnList = " + apnList);/* @} */}}



四.测试APN


     直接替换system/etc中的apn-config.xml。然后在APN Setting中点击Reset to default,这个动作会重新读取apn-config.xml并把数据重新写入数据库中。proxy是WAP网

 关,亲测如果没写也可上网,但是apn不可写错,否则无法上网。
  <apn carrier="中国联通 Wap 网络 (China Unicom)"
      mcc="460"
      mnc="01"
      apn="uniwap"
      proxy="10.0.0.172"
      port="80"
  />
      上面的Carrier是数据库表carriers中的name字段,这个字段只运用在APN Settings中的名字显示。而下拉状态栏和SIM卡管理中的名字显示则与SIM卡中携带的名字与SPN共同决定。参见以下SPN的说明,以下信息都是来自MTK的Mediatek On-Line,有条件的可以去看看。



SPN:


一:Background & 相关flow
MTK Operator name display在手机中分成两种类型:

1. Sim卡名称:
根据开机从SIM卡中读取的EF_SPN文件的内容(如果EF_SPN为空,则看EF_SPN_CPHS/EF_SPN_SHORT_CPHS)来设定,如果都为空,则设定默认名字CARD01/CARD02(L0上是SUB01/SUB02) ;然后会保存在SIMInfo这个database中,后续sim卡的名称就从此database中取得
(L之前的版本:
根据开机从SIM卡中读取的IMSI去到Spn-conf.xml中(如果是MVNO的卡则是Virtual-spn-conf-by-***.xml中)匹配得到的name来设定)
关于MVNO可以参考如下FAQ:
ID: FAQ09811
[NW]如何区分MNO和MVNO

使用场景:
Setting下SIM cards中SIM cards(L之前的版本:SimMangement中SIMInfo)等

2. 注册上的网络的名称:
这部分显示所用string的主要来源有如下这些,且他们之间最终显示哪个source的string是根据网络和这些source的内容所最终确定的rule决定的(如当前是否roaming,当前注册的plmn是否在EF_SPDI中,EF_SPN中有相关flag标识要不要显示spn…)

关于rule:
请参考Gsm sec 51.011 EF_SPN的部分还有cphs spec;
code的部分,请参考SIMRecords. getDisplayRule和GsmServiceStateTracker. updateSpnDisplay:
 
(1) Sim卡中文件,如EF_SPN, EF_OPN, EF_SOPN, EF_OPL, EF_PNN, EF_SPDI…
(2) 注册到的网络的plmn,对应Spn-conf.xml
(3) NITZ,即网络下发的名字
 
Spec 51.011中EF_SPN定义的rule 总结就是:

1. 名称分为 SPN 和 Registered plmn(包括EONS, CPHS (即ONS), S-CPHS, NITZ, PLMN;优先级依次降低)

2. 如果没有SPN文件,那么就显示Registered plmn

3. 若有SPN,注册的plmn是HPLMN或者注册的plmn在SIM卡文件EF_SPDI中,那么

    (1) 如果有SPN就要显示SPN

    (2) 如果SPN的bit1 = 1, 则需要同时显示Registered plmn,如果SPN的bit1=0,则不需要同时显示Registered plmn

4. 若有SPN,注册的plmn是Roaming plmn且注册的plmn也不在SIM卡文件EF_SPDI中,那么

    (1) 显示Registered plmn

    (2) 如果SPN的bit2=0,则需要同时显示SPN,如果SPN的bit2=1,则不需要同时显示SPN

 
上图中的PLMN的取值如下:
 

使用场景:
Keyguard,Notification list,...
 

其中客户可以客制化的部分是Spn-conf.xml/Virtual-spn-conf-by-***.xml;换句话说,如果你修改了相关xml没有生效,应该是按照spec显示了更高优先级的名字(EONS, CPHS, NITZ…)

 

如果按照spec显示了更高优先级的名字,而不是xml配置的,那么想要显示xml的名字必然要修改code flow而导致破坏spec定义的rule(由于这是spec定义的通用rule,所以SIM卡在实做时也需要follow spec rule)------这样的客制化很可能会导致CTA/FTA等测试fail,且遵循spec的SIM卡显示也会出问题;建议跟客户说明这部分是有spec规定的,不要进行除xml的客制化
 
二:遇到问题时的处理方式
如果有些Operator不follow   GSM Spec,而定义自己的rule,请按照如下方式处理:
(1)如果operator有出正式spec,请提供详细的技术说明文档;
(2)把此卡在同一时间同一地点(确保网络状况相同)放到Samsung,HTC等对比机中复现问题,提供对比机表现
(3)将此卡放到MTK手机中复现问题并提供复现问题的开机mobile log



             
    

这篇关于andorid中APN与SPN相关的设置相关的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/571563

相关文章

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

log4j2相关配置说明以及${sys:catalina.home}应用

${sys:catalina.home} 等价于 System.getProperty("catalina.home") 就是Tomcat的根目录:  C:\apache-tomcat-7.0.77 <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" /> 2017-08-10

Node Linux相关安装

下载经编译好的文件cd /optwget https://nodejs.org/dist/v10.15.3/node-v10.15.3-linux-x64.tar.gztar -xvf node-v10.15.3-linux-x64.tar.gzln -s /opt/node-v10.15.3-linux-x64/bin/npm /usr/local/bin/ln -s /opt/nod

git ssh key相关

step1、进入.ssh文件夹   (windows下 下载git客户端)   cd ~/.ssh(windows mkdir ~/.ssh) step2、配置name和email git config --global user.name "你的名称"git config --global user.email "你的邮箱" step3、生成key ssh-keygen

zookeeper相关面试题

zk的数据同步原理?zk的集群会出现脑裂的问题吗?zk的watch机制实现原理?zk是如何保证一致性的?zk的快速选举leader原理?zk的典型应用场景zk中一个客户端修改了数据之后,其他客户端能够马上获取到最新的数据吗?zk对事物的支持? 1. zk的数据同步原理? zk的数据同步过程中,通过以下三个参数来选择对应的数据同步方式 peerLastZxid:Learner服务器(Follo

uniapp设置微信小程序的交互反馈

链接:uni.showToast(OBJECT) | uni-app官网 (dcloud.net.cn) 设置操作成功的弹窗: title是我们弹窗提示的文字 showToast是我们在加载的时候进入就会弹出的提示。 2.设置失败的提示窗口和标签 icon:'error'是设置我们失败的logo 设置的文字上限是7个文字,如果需要设置的提示文字过长就需要设置icon并给

Tomcat性能参数设置

转自:http://blog.csdn.net/chinadeng/article/details/6591542 Tomcat性能参数设置 2010 - 12 - 27 Tomcat性能参数设置 博客分类: Java Linux Tomcat 网络应用 多线程 Socket 默认参数不适合生产环境使用,因此需要修改一些参数   1、修改启动时内存参数、并指定J

rtmp流媒体编程相关整理2013(crtmpserver,rtmpdump,x264,faac)

转自:http://blog.163.com/zhujiatc@126/blog/static/1834638201392335213119/ 相关资料在线版(不定时更新,其实也不会很多,也许一两个月也不会改) http://www.zhujiatc.esy.es/crtmpserver/index.htm 去年在这进行rtmp相关整理,其实内容早有了,只是整理一下看着方