Android APN开发流程分析

更新时间:2024-05-25 23:56:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Android APN开发流程分析

2 Data Connect流程分析

Android的数据连接是基于PPP方式的,主要步骤为:首先通过AT命令激活PDP连接,然后pppd通过数据端口完成拨号连接;

数据连接的核心控制类是DataConnectionTracker,存在于GSMPhone里,数据连接不需要用干预,在APN设置好之后,在适当的情况下就会自动激活,激活的入口点是:DataConnectionTracker.trySetupData→setupData→

PdpConnection.connetc→CommandsInterface.setupDefaultPDP,通过PdpConnection访问GSMPhone

RIL层的setupDefaultPDP实现,setupDefaultPDP的结果由EVENT_SETUP_PDP_DONE返回,如果成则开始调用pppd完成实际连接,这是通过DataLink.connect实现的;

DataLink只是抽象基类,此处它的实现类是PppLink,实现DataLinkInterface接口,所以

DataLink.connect实际上调用PppLink.connect,它通过SystemService.start(SERVICE_PPPD_

开始pppd服务,并通过checkPPP函数访问Linux的sys文件系统来查询pppd的连接状态,如果便可以将LINKUP的消息通知出去以完成连接流程。

2 Data Connect流程分析

Android的数据连接是基于PPP方式的,主要步骤为:首先通过AT命令激活PDP连接,然后利用pppd通过数据端口完成拨号连接;

数据连接的核心控制类是DataConnectionTracker,存在于GSMPhone里,数据连接不需要用户的干预,在APN设置好之后,在适当的情况下就会自动激活,激活的入口点是:DataConnectionTracker.trySetupData→setupData→ PdpConnection.connetc→CommandsInterface.setupDefaultPDP,通过PdpConnection访问GSMPhone中的RIL层的setupDefaultPDP实现,setupDefaultPDP的结果由EVENT_SETUP_PDP_DONE返回,如果成功,则开始调用pppd完成实际连接,这是通过DataLink.connect实现的;

DataLink只是抽象基类,此处它的实现类是PppLink,实现

DataLinkInterface接口,所以DataLink.connect实际上调用PppLink.connect,它通过SystemService.start(SERVICE_PPPD_GPRS)开始pppd服务,并通过checkPPP函数访问Linux的sys文件系统来查询pppd的连接状态,如果成功,便可以将LINKUP的消息通知出去以完成连接流程。

3.3 RILD源码分析

RIL对对消息的处理是将消息通过LocalSocket发送到以rild为名称的有名端口。这个有

Socket

ril.cpp

s_fdListen

=

android_get_control_socket(SOCKET_NAME_RIL)

RILD是守护进程,执行的过程为:获取参数→打开功能库→建立事件循环→执行RIL_Init→RIL_register;事件循环式核心,通过Select多路复用机制,读取来自上层的Socket

接口的具体操作命令,同时一些命令Timeout唤醒机制,也通过Select实现;

1. Request流程

命令下发流程:首先从JAVA层通过Socket将命令发送到RIL层的RILD守护进程,RILD中负责监听的ril_event_loop消息循环中的Select发现RILD Socket有了请求连接信号,建立一个record_stream,打通与上层的数据通道并开始接收请求数据,数据通道的回调函数processCommandsCallback()会保证收到一个完整的Request后,将其送达processCommandBuffer()函数;

解析过程:processCommandBuffer()从Socket中序列化的数据流里还原信息,将其组织到RequestInfo中;RequestInfo数据结构如下(存在于ril.cpp中):

typedef struct RequestInfo {

int32_t token; //this is not RIL_Token CommandInfo *pCI; struct RequestInfo *p_next; char cancelled;

char local; // responses to local commands do not go back to command process } RequestInfo;

RIL层以Request号为基础采用表驱动方式分发请求,CommandInfo结构表示命令的信息,关联了Request号和实际的请求函数,以及响应函数之间的关系;

分发流程:s_callback.onRequest()完成分发操作,s_callback获取自libreference-ril的RIL_RadioFunction结构指针,Request请求在这里转入底层的libreference-ril处理,handler是reference-ril.cpp中的Request。

onRequest根据Request号进行简单的switch分发,然后将命令和参数转换成对应的AT命令,由writeline()完成驱动层的发送,writeline通过驱动程序节点的文件描述符进行写操作实现控制。 2. Response流程

Response有两类:unsolicited表示主动上报的消息,如来电,来短信等,而solicited是AT命令的响应,判断是否是solicited的依据有两点:一是当前用AT命令正在等待响应;二是读取的响应符合该AT命令的响应格式。

对于Response流程来讲,流程是从Modem设备发回响应数据开始的。

RIL通过readerLoop函数,利用readline逐行读取响应数据,随后通过processLine进

行分析,主动上报的一般以+XXXX的形式出现,而AT命令的响应格式则有一行或多行之分,但最终一定以OK或者ERROR结尾,于是PrcessLine有以下几种情况: 1)、没有AT命令等待响应或不符合AT响应格式,一般是主动上报行,由handleUnsolicited处理,handleUnsolicited→onUnsolicetd→RIL_onUnsolicitedResponse; 2)、isFinalResponseSucess/isFinalResponseError是最终响应行,转到handleFinalResponse处理,handleFInalResponse会发送线程同步信号,激活等到的发送线程;

3)、符合当前AT命令响应格式的行,解析并获取数据,这是响应处理的中间过程,然后继续收到最终响应行,然后进入2)流程

最后的发送动作由sendResponse→sendResponseRaw→blockingWrite通过Socket回传给上层来完成,响应解析由上层完成。

Android MMS 源码流程(一) 2010-06-25 08:21

概述

MMS的收发操作借助于手机的短信机制,实际收发过程需要网络的APN支持,使用特定的APN接入点实现MMS数据的真实发送和接收;

源码流程

1) Telephpony.java getOrCreateThreadId()函数: 目录:\\frameworks\\base\\core\\java\\android\\provider\\

说明:这个函数根据接收者列表和未保存的消息返回一个线程ID,如果这个消息开始一个新的线程,那么函数分配一个线程ID,否则返回一个适当的已经存在的线程ID;

2) MmsMessageSender.java sendMessage()函数:

目录:\\packages\\apps\\mms\\src\\com\\android\\mms\\transaction\\ 说明:对Mms进行封包 3) 再一次调用第一步函数

4) ConnectivityService.java startUsingNetworkFeature()函数: 目录:\\framework\\base\\services\\java\\com\\android\\server\\

说明:该函数为实现Mms 网络连接的关键函数,下面我们详细分析: A、enforceChangePermission():判断调用的进程是否具有操作权限,如果不具有,抛出一个SecurityException异常,并强制准许权限 B、 ConnectivityManager.isNetworkTypeValid(networkType)来判断

networkType是否合法,如果不合法返回一个APN_REQUEST_FAILED,

在这里用到了最重要的ConnectivityManager类: public class ConnectivityManager定义在

\\frameworks\\base\\core\\java\\android\\net的ConnectivityManager.java里,其主要作用为:

1、监视网络连接,如WIFI、GPRS、UMTS等 2、当网路连接出现变化的时候,发送广播intents 3、当一个网络连接丢失之后,尝试连接另一个网络 4、为App提供粗粒度、细粒度的有效网络状态查询

C、 FeatureUser f = new FeatureUser(networkType, feature, binder);

新建一个FeatureUser类变量,该类实现:当调用进程died时发送一个Notice,这样就可以自我老化

D、int usedNetworkType = networkType;

if(networkType == ConnectivityManager.TYPE_MOBILE) {

if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) { usedNetworkType =

ConnectivityManager.TYPE_MOBILE_MMS; } 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; } }

这段代码获取使用的网络类型;

E、NetworkStateTracker network = mNetTrackers[usedNetworkType];

NetworkStateTracker类在NetworkStateTracker.java里:每个子类保持跟踪一个网络接口的连接状态,一个网络的状态信息由一个Tracker类保持,基类管理network-type-independent 网络状态 F、mFeatureUsers.add(f);

列表操作,将f添加到列表的end

G、if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) { // this gets used for per-pid dns when connected

mNetRequestersPids[usedNetworkType].add(currentPid); }

判断网络操作需要的Pid是否包含当前Pid,如果不包含就添加进去 H、mHandler.sendMessageDelayed(mHandler.obtainMessage(

NetworkStateTracker.EVENT_RESTORE_DEFAULT_NETWORK,

f), getRestoreDefaultNetworkDelay());

消息发送,问题:消息的Handle函数也在该文件本地,? I、 if ((ni.isConnectedOrConnecting() == true) && !network.isTeardownRequested()) { if (ni.isConnected() == true) { // add the pid-specific dns

Log.d(TAG, \before handleDnsConfigurationChange\

handleDnsConfigurationChange();

if (DBG) Log.d(TAG, \active\

return Phone.APN_ALREADY_ACTIVE; }

if (DBG) Log.d(TAG, \connecting\

return Phone.APN_REQUEST_STARTED; }

这里判断网络是正在连接还是已经连接完成,如果是已经连接完成,就去设置Dns,并返回already状态 J、network.reconnect()

如果网络不是已经连接完成的状态的话,这里触发一个重新连接,直到网络状态变成isConnected; Android MMS 源码流程(二) 2010-06-25 08:21

5) 接下来的操作存在于DataConnectionTracker.java里: public synchronized int enableApnType(String type):

该函数确保用指定的类型连接APN,成功返回APN_ALREADY_ACTIVE或者APN_REQUEST_STARTED

private void setEnabled(int id, boolean enable): 发送EVENT_ENABLE_NEW_APN事件

protected synchronized void onEnableApn(int apnId, int enabled)

该实例主要功能是判断目前是enable还是disable APN,如果是enable的话,调用onEnableNewApn();实现enable APN,如果是disable的话,根据enabledCount,onCleanUpConnection关闭APN或者改为默认连接 6) public void handleMessage(Message msg),ConnectivityService.java里 进入到对事件EVENT_STATE_CHANGED的处理,state= CONNECTED, old= CONNECTING, reason= apnChanged, apnTypeList= mms,应该是最后调用了handleConnect(info);发送一个广播事件

7) MobileDataStateTracker.java:MobileDataStateReceiver类的public void

onReceive(Context context, Intent intent)函数里处理case CONNECTED处理;调用setDetailedState(NetworkStateTracker类实例)发送了

EVENT_STATE_CHANGED事件

8) 然后又跳回ConnectivityService.java里的handleMessage函数EVENT_STATE_CHANGED事件的CONNECTED状态处理 9) handleConnect里最后调用updateNetworkSettings(实现在NetworkStateTracker类里),并发送sendConnectedBroadcast(info);广播事件

10) ConnectivityService.java handleDnsConfigurationChange配置DNS信息,并在handleConnect 函数调用addPrivateDnsRoutes添加路由信息

11) 接下来调用了GpsLocationProvider.java里的updateNetworkState和runLocked,原因不明?

12) 接下来返回去调用startUsingNetworkFeature

(ConnectivityService.java),又一次add dns ?,然后返回APN_ALREADY_ACTIVE状态

13) ensureRouteToHost()(/packages/apps/Mms/src/com/android/mms/transaction/Transaction.java)调用了ConnectivityManager类里的requestRouteToHost 至此关于Mms的Apn网络连接就建立起来了,

下面的步骤是在RILJ层以及RILD层实现数据和AT命令与modem的数据通信,省去

下面分析disable APN的流程,基本上就是Start的反过程:

1) 数据通信完毕,SendTransaction.java里的run函数给出数据通信完成之后的状态

2) stopUsingNetworkFeature()(ConnectivityService实例);这个就是startUsingNetworkFeature的反过程

3) disableApnType(mms),DataConnectionTracker类 4) setEnabled,DataConnectionTracker类

Android平台中Wifi的初始化 收藏 1. WIFI JAVA layer:

1.1 . 当android系统启动WIFI 模块时, 它将调用 Wifiserver 类的setWifiEnabledBlocking函数。

1.2 . 在该函数中,如果是使能WIFI, 它将做四件事: a. load wifi driver. b. 启动wpa_supplicant. c. 启动 event loop. d. 更新wifi的状态.

2. WIFI Native layer: 2.1 . 当java层调用 loadDriver时, 它实际上是通过JNI来调用Native函数, JNI->android_net_wifi_loadDriver -> wifi_load_driver。

在wifi_load_driver函数中,它将首先通过system property -- wlan.driver.status 的状态来判断驱动是否已经加载。如果没有加载,将会加载该驱动。

2.2 . 当java层调用startSupplicant时,它实际上是通过JNI调用到wifi_start_supplicant函数,

在wifi_start_supplicant函数里,首先确定wpa supplicant的配置文件存在,如果不存在,将默认配置文件拷贝到相应目录下,下面是配置文件的默认路径和工作路径: static const char SUPP_CONFIG_TEMPLATE[]= \static const char SUPP_CONFIG_FILE[] = \

然后,调用control_supplicant函数, 如果这时wpa_supplicant还没有启动, 将会启动wpa_supplicant.

2.3 . java层通过connectToSupplicant调用wifi_connect_to_supplicant函数,在该函数中,将通过 wpa_ctrl_open函数分别创建两个AF_UNIX地址族和数据报方式的socket,一个是ctrl_conn, 用于向wpa_supplicant发送命令并接收response, 另一个是monitor_conn, 它一直阻塞等待从wpa_supplicant过来的event。最后,通过monitor_conn向wpa_supplicant发送命令 ATTACH,用于将自己的socket信息注册到wpa_supplicant, 由于socket是数据报方式的,这一步是必须的,对于存在于wpa_supplicant的服务器端,它是所有客户端共享的,由于它需要主动向 monitor_conn客户端发送事件,所以它必须先记录下该客户端的详细信息,wpa_supplicant就可以将EVENT发向该socket。

在完成上面这些操作后,java层会通过jni方式调用函数android_net_wifi_waitForEvent(应该是起一个线程,在线程里调用),该函数会调用wifi_wait_for_event,在wifi_wait_for_event函数里,会阻塞接收从 wpa_supplicant模块传来的事件,一旦wpa_supplicant模块有事件发,wifi_wait_for_event接收到后,会将包含事件的buf通过函数参数的方式回传到java层,java收到事件后,再继续调用wifi_wait_for_event函数进行阻塞等待接收,从而完成一个循环。

2.4 . 以上的流程完成以后,WIFI java layer 调用的WIFI native api 就和wpa_supplicant进程就建立了联系,WIFI java layer就可以向wpa_supplicant发送命令和接收response, 并且wpa_supplicant也可以主动向WIFI java layer发送事件了。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhaohc_nj/archive/2010/08/30/5849536.aspx

android 新建一个Apn后的数据连接的调试过程

android, Apn, 数据, 调试

当我新建了一个APN 保存信息后,系统发现APN发生了改变就会去进行数据连接. 我查看调试信息发现第一次发送 setup_data_call 请求后,底层做出了响应,数据连接成功了状态为 CONNECTED, 却出现了PREFERED APN is null, 然后又监听到了 Apn 发生了改变,所以就将状态改变为 DISCONNECTING ,接着就发送一个DEACTIVATE_DATA_CALL 的请求要求断开数据连接,然后又发送一个 setup_data_call 去进行数据连接,第二次就连接成功了并在屏幕上显示出来了 G 标志.

其中让我非常纳闷的是: 为什么检测到两次APN 发生了改变? 当第一次连接状态已经为 CONNECTED 了却又监听到了 APN 发生了改变.

添加APN网络接入点,设置指定网络为默认网络 收藏 网上看了很多资料,再加上自己的理解和探索,终于实现了添加接入点设置和将当前网络设置为自己指定的网络接入点。废话不多说,上源码,大家分享下:(在moto-xt800,CDMA下进行了测试)

1.准备工作:

AndroidManifest。xml文件里添加以下三个权限设置:

android:name=\n>

android:name=\

android:name=\

开始上代码了,很期待吧?

2.新建一个类ApnNode,算是属性设置吧

public class ApnNode {

private String name ;

private String apn ;

private String proxy ;

private String port;

private String user;

private String server;

private String password;

private String mmsc;

private String mmsproxy;

private String mmsport;

private String mcc;

private String mnc;

private String numeric;

private String type;

/**

* @return the name */

public String getName() { return name; }

/**

* @param name the name to set */

public void setName(String name) { this.name = name; }

/**

* @return the apn */

public String getApn() {

return apn; }

/**

* @param apn the apn to set */

public void setApn(String apn) { this.apn = apn; }

/**

* @return the proxy */

public String getProxy() { return proxy; }

/**

* @param proxy the proxy to set */

public void setProxy(String proxy) { this.proxy = proxy; }

/**

* @return the port */

public String getPort() { return port; }

/**

* @param port the port to set */

public void setPort(String port) { this.port = port; }

/**

* @return the user */

public String getUser() { return user; }

/**

* @param user the user to set */

public void setUser(String user) { this.user = user; }

/**

* @return the server */

public String getServer() { return server; }

/**

* @param server the server to set */

public void setServer(String server) { this.server = server; }

/**

* @return the password */

public String getPassword() { return password; }

/**

* @param password the password to set */

public void setPassword(String password) { this.password = password; }

/**

* @return the mmsc */

public String getMmsc() { return mmsc; }

/**

* @param mmsc the mmsc to set */

public void setMmsc(String mmsc) { this.mmsc = mmsc; }

/**

* @return the mmsproxy */

public String getMmsproxy() { return mmsproxy; }

/**

* @param mmsproxy the mmsproxy to set */

public void setMmsproxy(String mmsproxy) { this.mmsproxy = mmsproxy; }

/**

* @return the mmsport */

public String getMmsport() { return mmsport; }

/**

* @param mmsport the mmsport to set */

public void setMmsport(String mmsport) { this.mmsport = mmsport; }

/**

* @return the mcc */

public String getMcc() { return mcc; }

/**

* @param mcc the mcc to set */

public void setMcc(String mcc) { this.mcc = mcc; }

/**

* @return the mnc */

public String getMnc() { return mnc; }

/**

* @param mnc the mnc to set */

public void setMnc(String mnc) { this.mnc = mnc; }

/**

* @return the numeric */

public String getNumeric() { return numeric; }

/**

* @param numeric the numeric to set */

public void setNumeric(String numeric) { this.numeric = numeric; }

/**

* @return the type */

public String getType() { return type; }

/**

* @param type the type to set */

public void setType(String type) { this.type = type;

} }

如果里面的函数名不清楚的话,网上找APN设置,一大堆的资料

3.主界面里的代码为:

public class ApnNew extends Activity { private Button setbtn; private Button insertbtn; private Button apnexist;

@Override

public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.apnnew);

setbtn = (Button)this.findViewById(R.id.setApn); setbtn.setOnClickListener(setlis);

insertbtn = (Button)this.findViewById(R.id.insertApn); insertbtn.setOnClickListener(insertlis);

apnexist = (Button)this.findViewById(R.id.Apnexist); apnexist.setOnClickListener(existlis); }

private OnClickListener setlis = new OnClickListener(){

@Override

public void onClick(View v) { setCmwapAPN(); } };

private OnClickListener insertlis = new OnClickListener(){

@Override

public void onClick(View v) { InsetAPN();

if(apnd_id != 0)

Toast.makeText(ApnNew.this, String.valueOf(apnd_id), Toast.LENGTH_SHORT).show(); else

Toast.makeText(ApnNew.this, \is unsuccess\Toast.LENGTH_SHORT).show(); } };

private OnClickListener existlis = new OnClickListener(){

@Override

public void onClick(View v) { int ri = checkAPN(); if(ri == -1)

Toast.makeText(ApnNew.this, \Toast.LENGTH_SHORT).show(); else

Toast.makeText(ApnNew.this, \Toast.LENGTH_SHORT).show(); } }; /*

* 入口

* 设置指定的APN接入点 * */

public void setCmwapAPN() { try {

if (!isCmwap()) {

int net_type = getNetWorkType(); m_oldNetWorkType = net_type;

if ((phoneSettedApnID = checkAPN()) != -1) {

SetDefaultAPN(phoneSettedApnID); } else {

InsetAPN();

SetDefaultAPN(apnd_id); }

不存在存在此APN\此APN\

Thread.sleep(8000L); } }

catch (Exception e) {

Log.i(\ } }

private int apnd_id = 0; int m_oldApnId = -1; int m_oldNetWorkType = -1;

private int phoneSettedApnID = -1;//当前APNid private static final Uri APN_TABLE_URI = Uri.parse(\

private static final Uri PREFERRED_APN_URI = Uri.parse(\ private String getMCC() {

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); String numeric = tm.getSimOperator(); String mcc = numeric.substring(0, 3); Log.i(\ return mcc; }

private String getMNC() {

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); String numeric = tm.getSimOperator();

String mnc = numeric.substring(3, numeric.length()); Log.i(\ return mnc; }

private String getSimOperator() {

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

String SimOperator = tm.getSimOperator(); return SimOperator; }

public ApnNode getDefaultAPN() {

String id = \ String apn = \ String proxy = \ String name = \ String port = \ String type = \ String mcc = \ String mnc = \ String numeric = \

ApnNode apnNode = new ApnNode(); // Uri uri = Uri.parse(\

Cursor mCursor = getContentResolver().query(PREFERRED_APN_URI, null, null, null, null); if (mCursor == null) {

// throw new Exception(\ return null; }

while (mCursor != null && mCursor.moveToNext()) {

id = mCursor.getString(mCursor.getColumnIndex(\ name = mCursor.getString(mCursor.getColumnIndex(\ apn = mCursor.getString(mCursor.getColumnIndex(\ proxy = mCursor.getString(mCursor.getColumnIndex(\ port = mCursor.getString(mCursor.getColumnIndex(\ mcc = mCursor.getString(mCursor.getColumnIndex(\ mnc = mCursor.getString(mCursor.getColumnIndex(\

numeric = mCursor.getString(mCursor.getColumnIndex(\ Log.d(\apn + \ }

phoneSettedApnID = Integer.valueOf(id); apnNode.setName(name); apnNode.setApn(apn); apnNode.setProxy(proxy);

apnNode.setPort(port); apnNode.setMcc(mcc); apnNode.setMnc(mnc);

apnNode.setNumeric(numeric); return apnNode; }

public boolean isCurretApn() {

ApnNode apnNode = new ApnNode(); apnNode.setName(\中国电信CTNET\ apnNode.setApn(\

apnNode.setProxy(\ apnNode.setPort(\ apnNode.setMcc(getMCC()); apnNode.setMnc(getMNC());

apnNode.setNumeric(getSimOperator()); ApnNode checkApn = getDefaultAPN(); if ((apnNode.getApn().equals(checkApn.getApn()) && apnNode.getMcc().equals(checkApn.getMcc()) && apnNode.getMnc().equals(checkApn.getMnc()) && apnNode.getNumeric().equals( checkApn.getNumeric())) && (checkApn.getType() == null || \|| \

(apnNode.getApn().equals(checkApn.getApn()) && checkApn.getProxy().equals(\ {

return true; }

m_oldApnId = phoneSettedApnID; return false; }

/**

* 获得网络连接管理 *

* @return */

private ConnectivityManager getConnectManager() {

ConnectivityManager m_ConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

return m_ConnectivityManager; }

/**

* 获得当前联网类型wifi or mobile *

* @return */

private int getNetWorkType() {

if (getConnectManager() != null) {

NetworkInfo networkInfo getConnectManager().getActiveNetworkInfo(); if (networkInfo != null)

return networkInfo.getType(); return -1; } else {

return -1; } }

private boolean isCmwap() {

int net_type = getNetWorkType();

if (net_type == ConnectivityManager.TYPE_MOBILE) {

return isCurretApn(); }

else if (net_type == ConnectivityManager.TYPE_WIFI) {

return false; }

return false; }

public boolean setDefaultApn(int apnId) {

boolean res = false;

ContentResolver resolver = getContentResolver(); ContentValues values = new ContentValues(); values.put(\

try

=

{

resolver.update(PREFERRED_APN_URI, values, null, null);

Cursor c = resolver.query(PREFERRED_APN_URI, new String[] { \\ if (c != null) {

res = true; c.close(); } }

catch (SQLException e) { }

return res; }

public void SetDefaultAPN(int id) {

setDefaultApn(id); ConnectivityManager cm = (ConnectivityManager) this.getSystemService(CONNECTIVITY_SERVICE);

cm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, \ Cursor cursor = getContentResolver().query(PREFERRED_APN_URI, null, null, null, null);

int rows = cursor.getCount(); cursor.moveToFirst(); String apn;

for (int i = 0; i < rows; i++) {

apn = cursor.getString(1);

Log.e(\ cursor.moveToNext(); } }

//检查指定APN是否存在 public int checkAPN() {

ApnNode checkApn = new ApnNode(); checkApn.setName(\中国电信ctnet\ checkApn.setApn(\ checkApn.setMcc(getMCC());

checkApn.setMnc(getMNC());

checkApn.setNumeric(getSimOperator()); return isApnExisted(checkApn); }

public int isApnExisted(ApnNode apnNode) {

int apnId = -1;

// Uri uri = Uri.parse(\

Cursor mCursor = getContentResolver().query(APN_TABLE_URI, null, null, null, null);

while (mCursor != null && mCursor.moveToNext()) {

apnId = mCursor.getShort(mCursor.getColumnIndex(\

String name = mCursor.getString(mCursor.getColumnIndex(\ String apn = mCursor.getString(mCursor.getColumnIndex(\ String type = mCursor.getString(mCursor.getColumnIndex(\ String proxy = mCursor.getString(mCursor.getColumnIndex(\ String port = mCursor.getString(mCursor.getColumnIndex(\ String current = mCursor.getString(mCursor.getColumnIndex(\

String mcc = mCursor.getString(mCursor.getColumnIndex(\ String mnc = mCursor.getString(mCursor.getColumnIndex(\ String numeric = mCursor.getString(mCursor.getColumnIndex(\

Log.e(\+ type + \

if (/*apnNode.getName().equals(name)*/(apnNode.getApn().equals(apn) && apnNode.getMcc().equals(mcc) && apnNode.getMnc().equals(mnc) && apnNode.getNumeric().equals(numeric)) && (type == null || \|| \(apnNode.getApn().equals(apn) && \ {

return apnId; } else {

apnId = -1; } }

return apnId; }

public int addNewApn(ApnNode apnNode)

{

int apnId = -1;

ContentResolver resolver = getContentResolver(); ContentValues values = new ContentValues(); values.put(\ values.put(\ values.put(\ values.put(\ values.put(\

values.put(\ values.put(\ values.put(\

values.put(\

// Note: this values need to be update, and for now, it only for XT800.

Cursor c = null; try {

Uri newRow = resolver.insert(APN_TABLE_URI, values); if (newRow != null) {

c = resolver.query(newRow, null, null, null, null);

int idindex = c.getColumnIndex(\ c.moveToFirst();

apnId = c.getShort(idindex);

Log.d(\\ID: \+ apnId + \Inserting new APN succeeded!\ } }

catch (SQLException e) { }

if (c != null) c.close();

return apnId; }

//添加一个APN

private void InsetAPN() {

ApnNode checkApn = new ApnNode();

checkApn.setName(\中国电信CTNET\ checkApn.setApn(\

// checkApn.setProxy(\// checkApn.setPort(\ checkApn.setUser(\

checkApn.setPassword(\ checkApn.setMcc(getMCC()); checkApn.setMnc(getMNC());

checkApn.setNumeric(getSimOperator()); apnd_id = addNewApn(checkApn); } }

4.主界面的xml文件为:

android:id=\

android:layout_width=\android:layout_height=\android:orientation=\

xmlns:android=\>

只要是开发过android的肯定清楚这些代码和界面吧,我也不多解释了,如果哥们你看不懂,那就是说明你还没弄清android开发,先去补补课再来看

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/napolun007/archive/2010/07/20/5748595.aspx

网络连接实例(接上篇APN设置) 收藏

private static final String WEBURL = \

try {

// 创建URL对象

URL url = new URL(WEBURL); // 创建URL连接 HttpURLConnection connection = (HttpURLConnection)url.openConnection();

// 对于 HTTP 连接可以直接转换成 HttpURLConnection,

// 这样就可以使用一些 HTTP 连接特定的方法,如 setRequestMethod() 等

// HttpURLConnection connection

// =(HttpURLConnection)url.openConnection(Proxy_yours); // 设置参数

connection.setConnectTimeout(10000); // 连接服务器

connection.connect();

} catch (IOException e) {

// TODO Auto-generated catch block e.printStackTrace(); }

连接Intenet网络,进行APN设置后无法直接进入网络,可以先进行下此项连接设置,就能登录网络了

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/napolun007/archive/2010/07/21/5753018.aspx

本文来源:https://www.bwwdw.com/article/p187.html

Top