android wifi ap模式AP是什么类型的wifi

如何把Android手机变成一个WIFI下载热点? — 报文转发及DNS报文拦截 - 为程序员服务
如何把Android手机变成一个WIFI下载热点? — 报文转发及DNS报文拦截
随着wifi的普及,移动运营商的热点也越来越多了,如中国移动的CMCC、中国电信的ChinaNet、中国联通的ChinaUnicom等,一般来说,连上此类的热点,打开浏览器上网时都会自动跳转到一个验证页面,最近有个项目也有类似的需求,Android手机自建热点,别的手机wifi连接此热点,打开浏览器,输入任意内容,自动跳转到一个下载列表页面,点击相应的链接即可下载相应的文件。
考虑如下几种情况:
浏览器输入IP地址,请求对应IP地址的80端口的内容
浏览器输入域名,先进行DNS解析域名,得到IP地址后,请求对应的80端口的内容
浏览器输入任意字符,一般浏览器内部设置一个默认的搜索引擎,此时地址栏的内容会作为搜索的关键字,加在搜索的url中
因此,需要解决如下问题:
端口报文转发
DNS报文拦截
端口报文转发
Android系统本身是Linux内核,1024以下端口都名花有主,如http是80,https是443,dns是53,对于这些1024以下端口的绑定需要root权限,但一般的App是没有root权限的,除非在 AndroidManifest.xml 文件中声明 android:sharedUserId=&android.uid.system&,并使用密钥文件进行签名:
java -jar signapk.jar platform.x509.pem platform.pk8 your.apk your_signed.apk
但问题是密钥文件属于手机厂商,显然不可能拿到这个密钥文件,当然,如果在模拟器里测试倒是可以的,从android源代码 build/target/product/security 里找到密钥文件,platform.pk8 和 platform.x509.pem,签名工具 signapk.jar 在 build/tools/signapk 下。
基于以上原因,一般Web服务器都绑定8080端口,手机浏览器如果输入IP地址,会访问Web服务器的80端口,这样就需要进行端口报文转发,对应dns报文拦截,无法监听53端口,同样需要端口转发,此外,浏览器的搜索引擎如果是google的话,使用https,同样也有这个问题。
iptables是个很好的防火墙管理工具,这里需要做如下配置:
iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to 192.168.43.1:8080
iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 443 -j DNAT --to 192.168.43.1:8443
iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p udp --dport 53 -j DNAT --to 192.168.43.1:53530
说明:-t nat:指定nat表,-A:添加,PREROUTING:路由前处理,-d 0.0.0.0/0:任意目的地IP,-p tcp:协议,--dport 80:端口,-j DNAT:地址映射跳转,--to 192.168.43.1:8080:转发目的地,总的意思就是,到达防火墙的报文,不管去往那个IP地址,只要是发往80端口的tcp包,都转发到192.168.43.1的8080端口。剩下两条意思类似。
需要注意的是:1、如果是App中的java代码调用,需要root权限,一般这么写:
String shell = "su -c iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to 192.168.43.1:8080";
Runtime.getRuntime().exec(shell);
2、Android手机设置为热点模式时,IP地址一般都会固定成192.168.43.1,这是由手机的dhcpcd服务指定的,一般不会去改dhcpcd服务的源代码然后重新编译,但这种写死的做法显然是不太合适的,通用的做法是自动取Ap的IP地址:
public static String getNetworkIpAddress(String name) {
Enumeration&NetworkInterface& interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
Enumeration&InetAddress& enumeration = networkInterface.getInetAddresses();
while (enumeration.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) enumeration.nextElement();
if (!inetAddress.isLoopbackAddress()
&& inetAddress instanceof Inet4Address
&& TextUtils.equals(name, networkInterface.getDisplayName())){
return inetAddress.getHostAddress().toString();
} catch (Exception e) {
e.printStackTrace();
return "";
public static String getApName(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Method method = connectivityManager.getClass().getMethod("getTetheredIfaces");
String[] names = (String[]) method.invoke(connectivityManager);
return names[0];
} catch (Exception e) {
e.printStackTrace();
return "";
看着挺复杂的,因为热点模式和连接到别的热点是完全不同的,取Ap名字时,用到了一个隐藏的方法,需要用反射的方式调用。
DNS报文拦截
DNS意思是域名解析协议,用户打开浏览器浏览网页时,不会记IP地址,而是记某些有含义的网址,DNS就是解决网址到IP地址的对应问题。DNS报文格式参考RFC1035文档,微软的网站上也有介绍: ,这里主要介绍DNS报文的格式。
DNS报文格式
DNS报文一般由如下部分组成:
DNS header (fixed length,12 Bytes)
Question entries (variable length)
Answer resource records (variable length)
Authority resource records (variable length)
Additional resource records(variable length)
套用《TCPIP详解卷》中的一张图
DNS header(固定占12字节)
总共占12字节,结构如下:-- 标识:报文的标识,占2字节,查询的报文里生成,响应的报文里复制此内容,用来标识是对相应查询的响应-- 标记:报文的标记位,占2字节,也就是16位,如下:
QR:0标识查询,1标识响应,
opcode:0为一般查询,1为反向查询(IP地址反查域名),2为查询服务器状态,一般为0
AA:是否为授权回答(authoritative - answer),可以理解为当前域名服务器是否对结果负责,如果从别的域名服务器查询过来的结果,显然不是当前域名服务器可掌控的,因此设为0
TC:是否被截断,UDP报文限定512字节(不包含IP及头部信息),如果超出将截断,此标记也被置1
RD:是否递归查询(Recursion Desired),如果为1,说明DNS服务器如果没有结果,那么DNS服务器会递归地找别的DNS服务器要结果,直到得到结果并返回,如果为0,则在没有结果的情况下,返回DNS列表
RA:是否支持递归查询,在响应报文中,一般都会支持递归查询
zero:必须为0
rcode:错误码,一般为0,表示没有错,如果不为0,表示有问题,错误码可以参考相关文档
--问题资源数:占2字节--回答资源数:占2字节--授权资源数:占2字节--附加资源数:占2字节
Question entries(不定长)
不定长,结构如下:
名字:域名的字符串表示,表示为:0x09microsoft0x03com0x00,需要注意的是长度的最高两位必须为0,因此字符长度不能超过63,也就是说最多0x3f,另外,参考rfc1053,为简化起见,域名总长度不能超过255
类型:相关含义可查手册,一般是0x0001,表示IP地址类型
类:一般是0x0001,表示普通的internet问题
Answer resource records(不定长)
不定长,结构如下:
名字:同前面的查询名字,一般会以索引方式表示,引用到前面的字符,比如前面的
字符在报文中的位置
类型:同前面的查询类型
类:同前面的查询类
生存时间:报文生存时间(TTL),占4字节,单位秒
资源长度:占2字节
资源内容:资源具体的内容,如IP地址:1.1.1.1 表示为 0x
Authority resource records(不定长)
Additional resource records(不定长)
经过以上的分析,来看个例子,打开wireshark抓包工具,监听网卡数据包,打开控制台,输入:,并抓取DNS报文。上图为DNS查询:
21 d5:会话标识,应答中用于标识是哪个查询
01 00:标记,二进制为00 0000,参考标记位,RD被置1,标识是一个递归的查询
00 01:问题数1
00 00:回答资源数0
00 00:授权资源数0
00 00:额外资源数0
05 62 61 69 64 75 03 63 6f 6d 00:域名名字,就是5baidu3com0这种格式,数字标识字符的数量,baidu有5个字符,所以是5baidu,域名字符串最后要跟一个0x00
00 01:查询IP地址
00 01:普通的internet查询
上图为DNS应答:
d36f6dc00c017c0c00c017c0004dcb56f55c00c017c0004dcb56f56
21 d5:标识,和之前的查询一一对应
81 80:标记,二进制为00 0000,QR、RD、RA被置1,表示支持递归查询的应答
00 01:问题数1
00 03:回答资源数3
00 00:授权资源数0
00 00:额外资源数0
05 62 61 69 64 75 03 63 6f 6d 00:域名名字,参考前面的查询报文
00 01:查询IP地址
00 01:普通的internet查询
c0 0c:域名名字,应该和前面的一致,但是为了节省报文长度,这是个引用,怎么知道的呢?因为是c0,二进制是,最高位两位置1了,这串字符前面有12个字节,因此相对位置是0c(从0开始)
00 01:查询IP地址
00 01:普通的internet查询
00 00 01 7c:生存时间(Time to Live,TTL,单位秒),380秒
00 04:资源长度,4个字节,表示接下来的4个字节是资源的实际内容
7b 7d 72 90:资源内容,其实就是IP地址,123.125.114.144
c0 0c ...:同上
从上面的DNS应答报文看,关注7b7d7290、dcb56f55、dcb56f56即可,分别对应三个IP地址:123.125.114.144、220.181.111.85、220.181.111.86
DNS报文拦截实现
了解了DNS报文的内容,下面需要做的就是,监听DNS端口,构造自己的报文返回即可,由于权限问题,一般Android的App是无法监听53端口的,这里可以监听53530端口,再通过iptables设置防火墙,将53端口的报文转发到53530端口即可,注意DNS是UDP包,代码参考如下
byte[] requestBuffer = new byte[256];
byte[] responseBuffer = new byte[256];
byte[] ipBuffer = { (byte) 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
x00, 0x01, 0x7c, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01 };
datagramSocket = new DatagramSocket(53530);
DatagramPacket requestPacket = new DatagramPacket(requestBuffer,requestBuffer.length);
while (!Thread.currentThread().isInterrupted()) {
datagramSocket.receive(requestPacket);
int requestLength = requestPacket.getLength();
System.arraycopy(requestBuffer, 0, responseBuffer, 0, requestLength);
System.arraycopy(ipBuffer, 0, responseBuffer, requestLength, ipBuffer.length);
responseBuffer[2] = (byte) 0x81;
responseBuffer[3] = (byte) 0x80;
responseBuffer[6] = (byte) 0x00;
responseBuffer[7] = (byte) 0x01;
DatagramPacket response = new DatagramPacket(responseBuffer, requestLength + ipBuffer.length, requestPacket.getAddress(), requestPacket.getPort());
datagramSocket.send(response);
} catch (Exception e) {
e.printStackTrace();
这样,所有的DNS解析请求都被转到1.1.1.1这个IP地址了。
这个一般由Web服务器决定,Android有款ijetty,是开源的
可看看其中的源代码,修改其中的Handler就搞定了。
Web bulid Meituan
原文地址:, 感谢原作者分享。
您可能感兴趣的代码Android 2.3 wifi hotspot API - Stack Overflow
to customize your list.
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
J it only takes a minute:
Join the Stack Overflow community to:
Ask programming questions
Answer and help your peers
Get recognized for your expertise
What is the API call I need to make in Android 2.2 (Froyo) to create a Wifi hotspot (as seen in the Tethering and Portable Hotspot settings item).
11.4k85373
There is no official API, but you can use reflection to handle it. I know some say, it's not recommended, however imho I say, screw it if Google doesn't want to provide an API for whatever reason.
Below is the code of an activity I used in my application, where the user can enable/disable the Wifi AP.
When you enable Wifi AP, usually the regular Wifi will be turned off, so after the user disables the Wifi AP again, we'll be activating regular wifi again.
The code sample below is taken from one of my projects, hope you can get the logic there easily. Let me know if you have further questions.
Code is tested on Nexus One 2.2 (and I think also 2.3) as well as on Samsung Galaxy S (2.2).
package com.myapp.android.activity.
import android.app.ProgressD
import android.content.C
import android.net.wifi.WifiC
import android.net.wifi.WifiM
import android.os.AsyncT
import android.os.B
import android.view.V
import android.view.WindowM
import android.widget.B
import java.lang.reflect.M
public class WifiAP extends BaseActivity {
// boolean mIsWifiEnabled =
private static final int WIFI_AP_STATE_UNKNOWN = -1;
private static final int WIFI_AP_STATE_DISABLING = 0;
private static final int WIFI_AP_STATE_DISABLED = 1;
private static final int WIFI_AP_STATE_ENABLING = 2;
private static final int WIFI_AP_STATE_ENABLED = 3;
private static final int WIFI_AP_STATE_FAILED = 4;
private final String[] WIFI_STATE_TEXTSTATE = new String[] {
"DISABLING","DISABLED","ENABLING","ENABLED","FAILED"
private WifiM
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.wifi);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
|WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|WindowManager.LayoutParams.FLAG_DIM_BEHIND
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
public void onResume() {
super.onResume();
updateStatusDisplay();
public void toggleWifi(View v) {
boolean wifiApIsOn = getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING;
new SetWifiAPTask(!wifiApIsOn,false).execute();
public void close(View v) {
boolean wifiApIsOn = getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING;
if (wifiApIsOn) {
new SetWifiAPTask(false,true).execute();
* Endable/disable wifi
* @param enabled
* @return WifiAP state
private int setWifiApEnabled(boolean enabled) {
Log.d("WifiAP", "*** setWifiApEnabled CALLED **** " + enabled);
if (enabled && wifi.getConnectionInfo() !=null) {
wifi.setWifiEnabled(false);
try {Thread.sleep(1500);} catch (Exception e) {}
//int duration = Toast.LENGTH_LONG;
//String toastText = "MobileAP status: ";
int state = WIFI_AP_STATE_UNKNOWN;
wifi.setWifiEnabled(false);
Method method1 = wifi.getClass().getMethod("setWifiApEnabled",
WifiConfiguration.class, boolean.class);
method1.invoke(wifi, null, enabled); // true
Method method2 = wifi.getClass().getMethod("getWifiApState");
state = (Integer) method2.invoke(wifi);
} catch (Exception e) {
Log.e(WIFI_SERVICE, e.getMessage());
// toastText += "ERROR " + e.getMessage();
if (!enabled) {
int loopMax = 10;
while (loopMax&0 && (getWifiAPState()==WIFI_AP_STATE_DISABLING
|| getWifiAPState()==WIFI_AP_STATE_ENABLED
|| getWifiAPState()==WIFI_AP_STATE_FAILED)) {
try {Thread.sleep(500);loopMax--;} catch (Exception e) {}
wifi.setWifiEnabled(true);
} else if (enabled) {
int loopMax = 10;
while (loopMax&0 && (getWifiAPState()==WIFI_AP_STATE_ENABLING
|| getWifiAPState()==WIFI_AP_STATE_DISABLED
|| getWifiAPState()==WIFI_AP_STATE_FAILED)) {
try {Thread.sleep(500);loopMax--;} catch (Exception e) {}
private int getWifiAPState() {
int state = WIFI_AP_STATE_UNKNOWN;
Method method2 = wifi.getClass().getMethod("getWifiApState");
state = (Integer) method2.invoke(wifi);
} catch (Exception e) {}
Log.d("WifiAP", "getWifiAPState.state " + (state==-1?"UNKNOWN":WIFI_STATE_TEXTSTATE[state]));
private void updateStatusDisplay() {
if (getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING) {
((Button)findViewById(R.id.btnWifiToggle)).setText("Turn off");
findViewById(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_on);
((Button)findViewById(R.id.btnWifiToggle)).setText("Turn on");
findViewById(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_off);
class SetWifiAPTask extends AsyncTask&Void, Void, Void& {
boolean mM
boolean mF
public SetWifiAPTask(boolean mode, boolean finish) {
ProgressDialog d = new ProgressDialog(WifiAP.this);
protected void onPreExecute() {
super.onPreExecute();
d.setTitle("Turning WiFi AP " + (mMode?"on":"off") + "...");
d.setMessage("...please wait a moment.");
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
try {d.dismiss();} catch (IllegalArgumentException e) {};
updateStatusDisplay();
if (mFinish) finish();
protected Void doInBackground(Void... params) {
setWifiApEnabled(mMode);
18.9k11103144
Did you find this question interesting? Try our newsletter
Sign up for our newsletter and get our top new questions delivered to your inbox ().
Subscribed!
Success! Please click the link in the confirmation email to activate your subscription.
For anyone interested in getting this working on ICS, setting your AP name, and/or keeping all the WifiAP code in its own class I have updated and improved upon the code given in the other answer:
WifiAP.java:
package com.demo.
import android.app.A
import android.app.ProgressD
import android.content.C
import android.net.wifi.WifiC
import android.net.wifi.WifiM
import android.os.AsyncT
import android.util.L
import java.lang.reflect.M
import com.demo.WifiAPA
* Handle enabling and disabling of WiFi AP
* @author /a/3435
public class WifiAP extends Activity {
private static int constant = 0;
private static final int WIFI_AP_STATE_UNKNOWN = -1;
private static int WIFI_AP_STATE_DISABLING = 0;
private static int WIFI_AP_STATE_DISABLED = 1;
public int WIFI_AP_STATE_ENABLING = 2;
public int WIFI_AP_STATE_ENABLED = 3;
private static int WIFI_AP_STATE_FAILED = 4;
private final String[] WIFI_STATE_TEXTSTATE = new String[] {
"DISABLING","DISABLED","ENABLING","ENABLED","FAILED"
private WifiM
private String TAG = "WifiAP";
private int stateWifiWasIn = -1;
private boolean alwaysEnableWifi = //set to false if you want to try and set wifi state back to what it was before wifi ap enabling, true will result in the wifi always being enabled after wifi ap is disabled
* Toggle the WiFi AP state
* @param wifihandler
* @author /a/3435
public void toggleWiFiAP(WifiManager wifihandler, Context context) {
if (wifi==null){
boolean wifiApIsOn = getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING;
new SetWifiAPTask(!wifiApIsOn,false,context).execute();
* Enable/disable wifi
* @param true or false
* @return WifiAP state
* @author /a/3435
private int setWifiApEnabled(boolean enabled) {
Log.d(TAG, "*** setWifiApEnabled CALLED **** " + enabled);
WifiConfiguration config = new WifiConfiguration();
config.SSID = "My AP";
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
//remember wirelesses current state
if (enabled && stateWifiWasIn==-1){
stateWifiWasIn=wifi.getWifiState();
//disable wireless
if (enabled && wifi.getConnectionInfo() !=null) {
Log.d(TAG, "disable wifi: calling");
wifi.setWifiEnabled(false);
int loopMax = 10;
while(loopMax&0 && wifi.getWifiState()!=WifiManager.WIFI_STATE_DISABLED){
Log.d(TAG, "disable wifi: waiting, pass: " + (10-loopMax));
Thread.sleep(500);
loopMax--;
} catch (Exception e) {
Log.d(TAG, "disable wifi: done, pass: " + (10-loopMax));
//enable/disable wifi ap
int state = WIFI_AP_STATE_UNKNOWN;
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: calling");
wifi.setWifiEnabled(false);
Method method1 = wifi.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
//method1.invoke(wifi, null, enabled); // true
method1.invoke(wifi, config, enabled); // true
Method method2 = wifi.getClass().getMethod("getWifiApState");
state = (Integer) method2.invoke(wifi);
} catch (Exception e) {
Log.e(WIFI_SERVICE, e.getMessage());
// toastText += "ERROR " + e.getMessage();
//hold thread up while processing occurs
if (!enabled) {
int loopMax = 10;
while (loopMax&0 && (getWifiAPState()==WIFI_AP_STATE_DISABLING || getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_FAILED)) {
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: waiting, pass: " + (10-loopMax));
Thread.sleep(500);
loopMax--;
} catch (Exception e) {
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: done, pass: " + (10-loopMax));
//enable wifi if it was enabled beforehand
//this is somewhat unreliable and app gets confused and doesn't turn it back on sometimes so added toggle to always enable if you desire
if(stateWifiWasIn==WifiManager.WIFI_STATE_ENABLED || stateWifiWasIn==WifiManager.WIFI_STATE_ENABLING || stateWifiWasIn==WifiManager.WIFI_STATE_UNKNOWN || alwaysEnableWifi){
Log.d(TAG, "enable wifi: calling");
wifi.setWifiEnabled(true);
//don't hold things up and wait for it to get enabled
stateWifiWasIn = -1;
} else if (enabled) {
int loopMax = 10;
while (loopMax&0 && (getWifiAPState()==WIFI_AP_STATE_ENABLING || getWifiAPState()==WIFI_AP_STATE_DISABLED || getWifiAPState()==WIFI_AP_STATE_FAILED)) {
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: waiting, pass: " + (10-loopMax));
Thread.sleep(500);
loopMax--;
} catch (Exception e) {
Log.d(TAG, (enabled?"enabling":"disabling") +" wifi ap: done, pass: " + (10-loopMax));
* Get the wifi AP state
* @return WifiAP state
* @author /a/3435
public int getWifiAPState() {
int state = WIFI_AP_STATE_UNKNOWN;
Method method2 = wifi.getClass().getMethod("getWifiApState");
state = (Integer) method2.invoke(wifi);
} catch (Exception e) {
if(state&=10){
//using Android 4.0+ (or maybe 3+, haven't had a 3 device to test it on) so use states that are +10
constant=10;
//reset these in case was newer device
WIFI_AP_STATE_DISABLING = 0+
WIFI_AP_STATE_DISABLED = 1+
WIFI_AP_STATE_ENABLING = 2+
WIFI_AP_STATE_ENABLED = 3+
WIFI_AP_STATE_FAILED = 4+
Log.d(TAG, "getWifiAPState.state " + (state==-1?"UNKNOWN":WIFI_STATE_TEXTSTATE[state-constant]));
* the AsyncTask to enable/disable the wifi ap
* @author /a/3435
class SetWifiAPTask extends AsyncTask&Void, Void, Void& {
boolean mM //enable or disable wifi AP
boolean mF //finalize or not (e.g. on exit)
* enable/disable the wifi ap
* @param mode enable or disable wifi AP
* @param finish finalize or not (e.g. on exit)
* @param context the context of the calling activity
* @author /a/3435
public SetWifiAPTask(boolean mode, boolean finish, Context context) {
d = new ProgressDialog(context);
* do before background task runs
* @author /a/3435
protected void onPreExecute() {
super.onPreExecute();
d.setTitle("Turning WiFi AP " + (mMode?"on":"off") + "...");
d.setMessage("...please wait a moment.");
* do after background task runs
* @param aVoid
* @author /a/3435
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
d.dismiss();
WifiAPActivity.updateStatusDisplay();
} catch (IllegalArgumentException e) {
if (mFinish){
* the background task to run
* @param params
* @author /a/3435
protected Void doInBackground(Void... params) {
setWifiApEnabled(mMode);
WifiAPActivity.java:
package com.
import android.app.A
import android.content.C
import android.net.wifi.WifiM
import android.os.B
import android.view.V
import android.view.WindowM
import android.widget.B
import com.demo.WifiAP;
public class WifiAPActivity extends Activity {
//private String TAG = "WifiAPActivity";
boolean wasAPEnabled =
static WifiAP wifiAp;
private WifiM
static Button btnWifiT
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.wifi);
btnWifiToggle = (Button) findViewById(R.id.btnWifiToggle);
wifiAp = new WifiAP();
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
btnWifiToggle.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
wifiAp.toggleWiFiAP(wifi, WifiAPActivity.this);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|WindowManager.LayoutParams.FLAG_DIM_BEHIND);
public void onResume() {
super.onResume();
if (wasAPEnabled) {
if (wifiAp.getWifiAPState()!=wifiAp.WIFI_AP_STATE_ENABLED && wifiAp.getWifiAPState()!=wifiAp.WIFI_AP_STATE_ENABLING){
wifiAp.toggleWiFiAP(wifi, WifiAPActivity.this);
updateStatusDisplay();
public void onPause() {
super.onPause();
boolean wifiApIsOn = wifiAp.getWifiAPState()==wifiAp.WIFI_AP_STATE_ENABLED || wifiAp.getWifiAPState()==wifiAp.WIFI_AP_STATE_ENABLING;
if (wifiApIsOn) {
wasAPEnabled =
wifiAp.toggleWiFiAP(wifi, WifiAPActivity.this);
wasAPEnabled =
updateStatusDisplay();
public static void updateStatusDisplay() {
if (wifiAp.getWifiAPState()==wifiAp.WIFI_AP_STATE_ENABLED || wifiAp.getWifiAPState()==wifiAp.WIFI_AP_STATE_ENABLING) {
btnWifiToggle.setText("Turn off");
//findViewById(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_on);
btnWifiToggle.setText("Turn on");
//findViewById(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_off);
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android="/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" &
android:id="@+id/btnWifiToggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" /&
&/LinearLayout&
permissions:
&uses-permission android:name="android.permission.ACCESS_WIFI_STATE"&&/uses-permission&
&uses-permission android:name="android.permission.CHANGE_WIFI_STATE"&&/uses-permission&
1,25921229
There is no public API for this.
protected by ♦
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10
on this site.
Would you like to answer one of these
Not the answer you're looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabled

我要回帖

更多关于 android wifi ap模式 的文章

 

随机推荐