android学习笔记2 彩信APN切换流程(framework)

第 36 章:电话与 RIL 无线接口层是 Java 电话框架和厂商调制解调器固件之间的桥梁。早期 RIL 是 C 语言守护进程 rild,通过 Unix 套接字、自定义二进制协议与框架通信。Android12 及以后迁移到稳定 AIDL HAL,把旧的单体 IRadio HIDL 接口拆分为多个按业务域划分的 AIDL 接口。# 列出全部radio‑hal aidl文件# 统计IRadioVoice接口方法数量# 统计IRadioData接口方法数量# 查看语音通话数据结构体Call.aidl。 阅读详情

TransactionService之前的流程比较简单不在赘述,现在主要理清下从TransactionService到framework的流程。

 

首先会走到TransactionService的onStartCommand,在此函数中会对当前网络状态进行判断,然后调用到launchTransaction,如果此时网络不可用,会弹出toast,否则就向自己的handler发送EVENT_TRANSACTION_REQUEST。

Handler收到EVENT_TRANSACTION_REQUEST消息后,根据不同的transactionType对data进行不同的处理,我们用的是SEND_TRANSACTION,所以创建了transaction = newSendTransaction,紧接着调用processTransaction,开始进行transaction。

这里就到了关键的函数----beginMmsConnectivity,会根据此函数的返回值来进行下一步的操作,如果是APN_REQUEST_STARTED,则会把当前的MMS放到等待队列里,直到对应的APNready之后才会发送。

beginMmsConnectivity 会调到connectivityservice的startUsingNetworkFeature,下面重点看下这个函数。

 

    public intstartUsingNetworkFeature(int networkType, Stringfeature,              // networkType这里我们是0,也就是TYPE_MOBILE,feature 是 enablemms1

            IBinderbinder) {

 

…….

       if(networkType == ConnectivityManager.TYPE_MOBILE) {

           //if type is MMS,continue setup data call

           Slog.d(TAG, "if type is MMS,continue setup data call");

           if (!getMobileDataEnabledByPhoneId(getPhoneIdByFeature(feature)) &&

                   !(feature.indexOf(Phone.FEATURE_ENABLE_MMS)!=-1)) {

           //if (!getMobileDataEnabledByPhoneId(getPhoneIdByFeature(feature))) {

               if (DBG) Slog.d(TAG, "requested special network with data disabled - rejected");

               return Phone.APN_TYPE_NOT_AVAILABLE;

           }   if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DM)) {

               usedNetworkType = ConnectivityManager.TYPE_MOBILE_DM;

           } else if (TextUtils.equals(feature.substring(0,Phone.FEATURE_ENABLE_MMS.length()), Phone.FEATURE_ENABLE_MMS)){       //这里判断feature的前几位是不是enablemms

               skipAvailableCheck = true;

               usedNetworkType =ConnectivityManager.getMmsTypeByPhoneId(getPhoneIdByFeature(feature));// 将usedNetworkType赋值为11,即TYPE_MOBILE_DM+1

                                    /* yuqing :if send sms with sim2 ,usedNetworkType=TYPE_MOBILE_DM+1=11 */

           } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {

               usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL;

           } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN)) {

               usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN;

           } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {

               usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI;

           }

       }

       NetworkStateTracker network = mNetTrackers[usedNetworkType]; //根据usedNetworkType来选取对应的NetworkStateTracker

        if(DBG) Slog.d(TAG, "network = " + network);

       if (network != null) {

           if (usedNetworkType != networkType){              //传入的是0,现在NetworkStateTracker是11

               Integer currentPid = new Integer(getCallingPid());

 

               NetworkStateTracker radio = mNetTrackers[networkType];

               NetworkInfo ni = network.getNetworkInfo();

 

               // TODO: using serviceState to check is better for Msms

               if (!skipAvailableCheck && ni.isAvailable() == false) {

                   if (DBG) Slog.d(TAG, "special network not available");

                   return Phone.APN_TYPE_NOT_AVAILABLE;

               }              synchronized(this) {

                   mFeatureUsers.add(f);

                   if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) {

                       // this gets used for per-pid dns whenconnected

                       mNetRequestersPids[usedNetworkType].add(currentPid);

                   }

               }

               mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_RESTORE_DEFAULT_NETWORK,

                       f), getRestoreDefaultNetworkDelay());

 

               if (DBG) Slog.d(TAG,"ni.isConnectedOrConnecting()="+ni.isConnectedOrConnecting()); //当卡2的数据连接还没起来的时候,这里是disconnect

               if ((ni.isConnectedOrConnecting() == true) &&

                       !network.isTeardownRequested()) {

                   if (ni.isConnected() == true) {

                       // add the pid-specific dns

                       handleDnsConfigurationChange(networkType);

                       if (DBG) Slog.d(TAG, "special network already active");

                       return Phone.APN_ALREADY_ACTIVE;

                   }

                   if (DBG) Slog.d(TAG, "special network already connecting");

                   return Phone.APN_REQUEST_STARTED;

               }

 

               // check if the radio in play can make another contact

               // assume if cannot fornow               if (!isAlreadyConnecting) {

                   if (DBG) Slog.d(TAG, "reconnecting to special network");

                   if(!network.reconnect()){                // 重要函数,实际调用的是MobileDataStateTracker.reconnect(),下面分析

                                              

                       //if the mms apn is not available, remove the request from mMmsFeatureRequest

                       //if not remove it, the othe mms send request will be pending.

                       if (isMmsFeature(feature) && mMmsFeatureRequest.size() > 0) {

                           mMmsFeatureRequest.remove(0);

                       }

                       return Phone.APN_TYPE_NOT_AVAILABLE;

                   }

               } else {

                   if (DBG) Slog.d(TAG, "already reconnecting to special network");

               }

               return Phone.APN_REQUEST_STARTED;

           } else{               synchronized(this) {

                   mFeatureUsers.add(f);

               }

               mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_RESTORE_DEFAULT_NETWORK,

                       f), getRestoreDefaultNetworkDelay());

 

               return network.startUsingNetworkFeature(feature,

                       getCallingPid(), getCallingUid());

           }

       }

       return Phone.APN_TYPE_NOT_AVAILABLE;

}

 

MobileDataStateTracker.reconnect()中会调用setEnableApn (mApnType,true),此时的apntype是已经转换好了的, mApnType =networkTypeToApnType(netType);

代码如下,我们在创建的时候,选择的是第11个即mNetTrackers[usedNetworkType],也就是说netype =11,但是经过这个函数转换后神奇的变成了MMS,不知是何用意,暂且先不管。

    public static StringnetworkTypeToApnType(int netType) {

       switch(netType) {

           case ConnectivityManager.TYPE_MOBILE:

               return Phone.APN_TYPE_DEFAULT;  // TODO - use just one of these

           case ConnectivityManager.TYPE_MOBILE_MMS:

               return Phone.APN_TYPE_MMS;

           case ConnectivityManager.TYPE_MOBILE_SUPL:

               return Phone.APN_TYPE_SUPL;

           case ConnectivityManager.TYPE_MOBILE_DUN:

               return Phone.APN_TYPE_DUN;

           case ConnectivityManager.TYPE_MOBILE_HIPRI:

               return Phone.APN_TYPE_HIPRI;

           case ConnectivityManager.TYPE_MOBILE_DM:

               return Phone.APN_TYPE_DM;           

default:

                    // Msms MMS netType @zha

               if (ConnectivityManager.isNetworkTypeValid(netType)) {

                   return Phone.APN_TYPE_MMS;

                    } else {

                   Log.e(TAG, "Error mapping networkType " + netType + " toapnType.");

                   return null;

                    }

       }

    }

setEnableApn调用了mPhoneService.enableApnType(apnType),即DataConnectionTracker.enableApnType,返回值就是此函数中给出的,此函数中又调用了apnTypeToId来转换ID,

转换为APN_MMS_ID,紧接着调用setEnabled,发送EVENT_ENABLE_NEW_APN给自己的handler,回调到onEnableApn--àonEnableNewApn()

调用GsmDataConnectionTracker的onEnableNewApn,这里会调用       cleanUpConnection(true, Phone.REASON_APN_SWITCHED);disconnect当前APN,

停止netstate的poll,也就是为什么我们看到E的图标没有了。

调用MsmsGsmDataConnectionTracker的enableApnType,到MsmsGsmDataConnectionTrackerProxy.onEnableNewApn,此函数就是最终gprsattach的地方。

 

public staticvoid onEnableNewApn(int phoneId) {

       synchronized (sInstance) {

           log("onEnableNewApn(" + phoneId + ") activePhoneId:" +sActivePhoneId);

           if (phoneId == INVALID_PHONE_ID){                       //传入PHONEID不正确

               log("phoneId is invalid,onEnableNewApn out!!!");

               return;

           }

           sRequestConnectPhoneId = phoneId;

           sRequestPhoneIdBeforeVoiceCallEnd = sRequestConnectPhoneId;

           if (sActivePhoneId != INVALID_PHONE_ID) {

               if(sRequestConnectPhoneId!=sActivePhoneId){             //当前APN存在,且phoneid和请求值不等,即双卡之间切换时

                  

                    if(sTracker[sActivePhoneId].isAllPdpDisconnectDone()) { //PDP连接全部断开时,switchphone E图标消失,否则强制断开连接。

                       checkAndSwitchPhone(sActivePhoneId, null);

                   } else {

                       sTracker[sActivePhoneId].cleanupConnections(true,

                       Phone.REASON_DATA_DISABLED);

                   }

               }else{

                   sTracker[sActivePhoneId].onEnableNewApnInternal();

               }

           } else {   //当前activephone不存在,

                if(sTracker[sRequestConnectPhoneId].getCurrentGprsState() ==ServiceState.STATE_IN_SERVICE) { //如果GPRS inservice,发起数据连接

                   sTracker[sRequestConnectPhoneId].trySetupData(Phone.REASON_APN_SWITCHED);

                   sActivePhoneId = sRequestConnectPhoneId;

               } else {

                   sTracker[sRequestConnectPhoneId].mGsmPhone.mCM.setGprsAttach(null);//notinservice ,则发起gprsattach

                   sActivePhoneId = sRequestConnectPhoneId;

              }

           }

           if(phoneId == sActivePhoneId){ //如果传入值和当前active值相同

               // do not need to switch phone, so we initialize sRequestConnectPhoneId.

               sRequestConnectPhoneId=INVALID_PHONE_ID;

           }

           log("onEnableNewApn out");

       }

}

如果这次setapnenable没有成功(返回APN_REQUEST_STARTED),TransactionService会将当前的Transaction放入pending列表,

并侦听EVENT_DATA_STATE_CHANGED事件,在合适的时候重新发起,调用processPendingTransaction处理pending的Transaction。

Android多网络环境(wifi,mobile)下强制在某个网络(mobile)访问服务端以及适配 在wifi和移动数据网络同时开启之下,现在需要wifi开着的情况下,强制通过移动数据网络发送网络请求,以及在机型和低版本适配。 阅读详情

相关推荐

Android13配置selinux让system应用可读sys,proc,SN号

Android13预置的system应用,需要读/sys, /proc目录,读(SN)serial number号, 需要修改selinux配置,否则会报avc错.其修改方法会比Android11复杂一些.。

zmlovelx(帅得不敢出门 程序员群31843264) 2654

startUsingNetworkFeature

connectivity.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "wap");          该函数的feature参数是和厂商相关的,在OPhone1.5中就是“数据链接”设置中“接入点”的名称

anzhu_111的专栏 4748

计算机毕业设计springboot股票模拟交易系统的设计与实现u6m959【附源码+数据库+部署+LW】

选题背景: 随着互联网和金融科技的快速发展,股票市场成为了吸引人们关注和参与的重要领域之一。越来越多的人开始对股票投资感兴趣,希望通过交易股票来获取收益。然而,对于初学者来说,股票市场的复杂性和风险往往让他们望而却步。因此,设计和实现一个股票模拟交易系统,可以帮助初学者更好地理解和掌握股票交易的规则和技巧,提高他们的投资决策能力。 意义: 股票模拟交易系统的设计与实现具有以下几个重要意义: 提供实践机会:股票模拟交易系统为投资者提供了一个实践的平台,使他们能够在真实市场环境下进行模拟交易,了解股票市场的

gp12081的博客 1760

android 上网 (三)-- 数据开关变化和应用主动拨号

这篇给出是数据开关状态变化引起网络状态的改变的代码流程,数据开关是指设置  -->无线网络设置 -->移动设置 -->是否启用数据的那个选项,选中表示启用,当然不同手机的中文翻译可能不同,不过不影响理解。先贴张图,图中就是设置数据开关所走的代码流程了。           这张图并不是完整的,其实在上图最后的 MobileDataStateTracker.java的reconnect()

balmy的专栏 6369

Springboot + vue 实现导出word

Springboot + vue 实现导出word 后端代码 使用word先创建好已知的模板 使用word工具另存为.xml格式的文件 使用freemarker ftl模板 将修改后的xml文件复制到开发工具中,将文件后缀修改为ftl文件,并且将里面的动态值使用${}包裹例如:${zyjn} word工具类 /*** * * Project Name:maventest * <p>生成word工具类<br> * * @ClassName: WordUtil *

qq_45542373的博客 2895

RK3568 MIPI屏幕启动异常:从uboot logo到黑屏的排查与修复

本文详细分析了RK3568平台MIPI屏幕在启动过程中,从uboot阶段正常显示logo到内核阶段黑屏的典型故障。通过硬件测量与软件调试,最终定位问题根源在于电源时序,并提供了在设备树中为屏幕供电的regulator节点添加`regulator-boot-on`属性的关键解决方案,有效解决了因内核启动早期电源管理导致的显示异常。

weixin_29161719的博客 541

双卡发送和接收彩信的解决方法 mms 主要还是看数据连接的建立

双卡发送和接收彩信的解决方法,因每一个厂商都有自己的接口,下面列出一些我常用到的的接口:           第一种:                   1、点击发送(卡1或卡2)按钮时,就把数据连接(data connect)切换到对应的卡上。问题来了,如何切换,用哪个api? 一般厂商和原生android源码里都有一个管理和订阅card信息的隐藏管理类:"android.telephon

subaohao的专栏 4768

【CarMaker实战指南】从零构建环形测试场景与车辆连续仿真

本文详细介绍了如何使用CarMaker软件从零构建环形测试场景与实现车辆连续仿真。通过分步指导搭建闭环道路、连接交叉路口、规划车辆轨迹等核心操作,帮助用户掌握CarMaker的基础应用技巧,并提供了常见问题排查与进阶优化建议,适用于车辆耐久性测试和自动驾驶算法验证等场景。

weixin_29274969的博客 234

Android手机上网、彩信APN设置

Android手机上网、彩信APN设置Godaddy最新域名优惠码 - 帅哥推荐博客主机 - linost圣诞促销返款 - iPhone4销售状态查询<br />前几天师弟跑来问我G2(Magic)怎么一直没法接收手机报啊?<br />我问他设置APN没,他倒反问我,APN是什么?<br />我晕死,当时确实也忘记给他设置了,只是给他了APN开关和3G流量狗<br />为了方便新手使用,我将各运营商的上网、彩信APN设置整理,希望对新手有所帮助,以接触多少及垃圾程度排名:<br />中国移动<br />首先

yihui8的专栏 2803

DSH-Work:一个让DeepSeek下载即用的Harness客户端

使用大模型工具时,环境配置往往比模型本身更让人头疼。DeepSeek Harness作为一类封装层,将模型调用、上下文管理、参数控制等复杂细节统一收拢,对外提供简洁操作入口。开源的DSH-Work正是这样一款Harness客户端,它通过自带运行时与保守默认配置,实现了下载即用、免配环境的目标,让使用者无需掌握Python、CUDA等专业知识即可快速连接DeepSeek云端或本地服务。对于非技术背景的用户,它降低了AI工具的使用门槛;对于开发者,它把时间从环境排错中解放出来,更专注于提示词调优与工作流设计。无

weixin_29048309的博客 343

手把手教你学PCIE-- 热插拔电路设计与实现方案

PCIe热插拔(Hot-Plug)技术允许用户在系统运行时安全地插入或移除设备,而无需重启系统。本文将深入讲解热插拔电路的设计要点、关键器件选型及信号协议规范,涵盖机械结构、电气保护和电源管理三大核心模块。​。

MHD0815的博客 440

Android代码设置APN

什么是APN?APN(Access Point Name)中文全称叫接入点。APN指一种网络接入技术,是通过手机上网时必须配置的一个参数,它决定了手机通过哪种接入方式来访问网络。APN用来标识GPRS的业务种类,目前分为两大类:CMWAP(通过GPRS访问WAP业务)、CMNET(除了WAP以外的服务目前都用CMNET,比如连接因特网等)。APN手机里的位置不同手机可能位置不一样,我使用的测试机是红

Jimbin的博客 1万+

【原创】下载RealEstate10K数据集原始视频的方法

目前互联网上能搜到下载RealEstate10K数据集原始视频的方法都已经不能用了,这篇博客介绍一种目前可用的下载RealEstate10K数据集原始视频的方法,并给出自动化的脚本代码。

沉迷单车的追风少年 2461

android 彩信 apn 切换,android学习笔记2 彩信APN切换流程(framework)

TransactionService之前的流程比较简单不在赘述,现在主要理清下从TransactionService到framework的流程。首先会走到TransactionService的onStartCommand,在此函数中会对当前网络状态进行判断,然后调用到launchTransaction,如果此时网络不可用,会弹出toast,否则就向自己的handler发送EVENT_TRANSAC...

weixin_40003478的博客 198

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

android 彩信 apn 切换,android学习笔记2 彩信APN切换流程(framework)

TransactionService之前的流程比较简单不在赘述,现在主要理清下从TransactionService到framework的流程。首先会走到TransactionService的onStartCommand,在此函数中会对当前网络状态进行判断,然后调用到launchTransaction,如果此时网络不可用,会弹出toast,否则就向自己的handler发送EVENT_TRANSAC...

weixin_42160252的博客 377

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

android 上网 (一)-- apn切换拨号

android的上网总体上分两种,一种是切换apn或启用数据开关导致网络连接,另一种应用程序主动拨号如彩信。这里要给出的流程是第一种,没有过多的说明,直接出图。图中代码参考android2.3代码,每个方框内有类名,方法和关键TAG,不过这个图没有画完,画图软件一页画不下了只好分开。下图主要说明当手动切换apn时,上网拨号的流程是怎么跑的,从framework到ril再回来,对于回来以后的流程还没

balmy的专栏 5373

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

彩信APN切换流程(framework)

TransactionService之前的流程比较简单不在赘述,现在主要理清下从TransactionService到framework的流程。 首先会走到TransactionService的onStartCommand,在此函数中会对当前网络状态进行判断,然后调用到launchTransaction,如果此时网络不可用,会弹出toast,否则就向自己的handler发送...

初心(linux,python,php,photoshop) 170

Android开发全栈指南:从环境搭建到AI集成

移动应用开发中,Android系统凭借其开源的Linux内核和分层架构设计,成为覆盖全球70%市场份额的移动操作系统。其核心价值在于通过HAL层标准化硬件接口,结合ART虚拟机实现跨平台兼容性,使开发者能构建适配海量设备的应用。现代Android开发采用MVVM架构配合Jetpack组件,大幅提升代码可维护性。在工程实践层面,Android Studio提供完善的工具链支持Java/Kotlin开发,而动态功能模块化技术可实现按需加载。随着Android 16集成Gemini Nano等AI模型,设备端机器

weixin_33895657的博客 398

Android开发技术周报:工具链更新与性能优化实践

Android开发作为移动应用开发的核心领域,其技术生态持续快速演进。从底层工具链到上层框架,每周都有新的优化与最佳实践涌现。理解Android Studio、Gradle等开发工具的版本迭代,掌握Jetpack组件库的性能优化原理,是提升开发效率的关键。特别是在内存管理、UI渲染等核心场景中,合理应用新技术可显著改善应用性能。通过系统化的技术周报,开发者能够及时获取ARM芯片优化、Compose API改进等热门前沿信息,并将这些更新应用于实际项目开发中,如课程提醒系统等典型移动应用场景。持续跟踪工具链更

weixin_33910759的博客 358

Android:设置APN为cmnet源码

public class APNActivity extends Activity { 02 03 public static final Uri APN_URI = Uri.parse("content://telephony/carriers"); 04

Working harder, getting stronger! 2536

Android数据连接浅析

在Android中,应用对数据连接的操作需要通过framework提供的以下两个服务类frameworks/base/services/java/com/android/server/ConnectivityService数据连接的系统级服务类,frameworks/base/core/java/android/net/ConnectivityManager数据连接的应用层管理类。下面就Conne

Android专栏 6762

Android网络编程(二)ConnectivityManager和NetworkInfo详解

一.   ConnectivityManager详解      概要      ConnectivityManager是网络连接相关的管理器,它主要用于查询网络状态并在网络发生改变时发出状态变化通知。这个类主要负责的下列四个方面:      1.  监控网络状态(包括WiFi, GPRS, UMTS等)。      2.  当网络连接改变时发送广播Intent。      3.  当一种

OyangYujun的专栏 2万+

Android网络连接的理解

Android的网络连接类型大致分为wifi和mobile两种,wifi比较容易理解,难理解一点的是mobile类型。 首先,检查当前是否有网络连接采用的方法如下: public static boolean isNetworkConnected(Context context) { NetworkInfo networkInfo = ((ConnectivityM

hjj0212的专栏 2323

[Android]自定义移动网络接入点

<br />1.点击“Network”将显示本机的无线及网络信息。<br />2.点击"WAP"将自动设接入点为CMWAP。<br />3.点击“GPRS”将自动设接入点为GPRS。<br /> <br /> <br />package lab.sodino.network; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.U

Sodino的专栏 5737

Android源码分析--彩信

建立新的彩信,点击发送后,会断开默认的数据业务,然后连接MMS网络。 首先调用: ConnectivityService.java—startUsingNetworkFeature,这个函数中会判断当前连接的网络是否为MMS网络,若不是就会调用函数: MobileDataStateTracker.java—类MobileDataStateTracker中的函数reconnect函数。 Re...

135
上一篇: [android学习1]横竖屏切换的机理
下一篇: android 学习笔记3--静默安装功能的实现
有梦想的胖子
博客等级 码龄16年 51粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值