在看这一篇文章之前,读者先得知道安卓系统中:
(1)、在开启wifi的情况下必须先关闭wifi才能开启热点。
(2)、热点可以没有密码,即加密方式为open,如果有密码,并且采用WPA—PSK的加密模式,密码长度至少为八位数。
下面进入正题,首先,在manifest中添加用户权限,因为要操作热点和变更wifi状态。
紧接着,新建一个热点管理的类,源代码如下:
public class WifiApConnector {
private static final String SETUP_WIFIAP_METHOD = "setWifiApEnabled";
private static final String TAG="wifi_test";
Context context = null;
WifiManager wifiManager = null;
static WifiApConnector wifiApConnector = null;
public static WifiApConnector getInstance(Context context) {
if (wifiApConnector == null) {
wifiApConnector = new WifiApConnector();
wifiApConnector.context = context.getApplicationContext();
wifiApConnector.wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}
return wifiApConnector;
}
public void setupWifiAp(String name, String password) throws Exception {
if (wifiManager.isWifiEnabled()) {
Log.i(TAG,"手机wifi开启了"+wifiManager.isWifiEnabled());
wifiManager.setWifiEnabled(false);
Log.i(TAG,"手机wifi被强行");
if (name == null || "".equals(name)) {
throw new Exception("the name of the wifiap is cannot be null");
}
else{
stratWifiAp(name, password);
Log.i(TAG,"手机关闭wifi之后成功调用startwifiap方法");
}
}
if (!wifiManager.isWifiEnabled()) {
Log.i(TAG,"手机wifi未开启"+wifiManager.isWifiEnabled());
if (name == null || "".equals(name)) {
throw new Exception("the name of the wifiap is cannot be null");
}else{
stratWifiAp(name, password);
Log.i(TAG,"手机不需要关闭wifi之后热点创建成功");
}
}
}
private void stratWifiAp(String name, String password) {
Method method1 = null;
try {
method1 = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
WifiConfiguration netConfig = new WifiConfiguration();
netConfig.SSID = name;
netConfig.preSharedKey = password;
netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
method1.invoke(wifiManager, netConfig, true);
Log.i(TAG,"成功启动start方法创建wifi热点");
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public boolean isWifiApEnabled() {
try {
Method method = wifiManager.getClass().getMethod("isWifiApEnabled");
method.setAccessible(true);
return (Boolean) method.invoke(wifiManager);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
public void closeWifiAp() {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (isWifiApEnabled()) {
try {
Method method = wifiManager.getClass().getMethod("getWifiApConfiguration");
method.setAccessible(true);
WifiConfiguration config = (WifiConfiguration) method.invoke(wifiManager);
Method method2 = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
method2.invoke(wifiManager, config, false);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
Context context = null;
WifiManager wifiManager = null;
static WifiApConnector wifiApConnector = null;
关于contex的意义,在上一篇文章中已经指出,这里先实例化一个WifiManager,同时还实例化出一个本类的对象wifiApconector。
public boolean isWifiApEnabled() {
}
此方法用于判定当前系统wifi是否打开,若打开,则返回true,若没有打开,则返回false。
public void setupWifiAp(String name, String password) throws Exception {
}
在设置热点的方法中,首先对当前wifi状态进行判定,若wifi打开,则关闭wifi,执行start方法,若没有打开,则直接执行。
private void stratWifiAp(String name, String password) {
}
启动wifi的方法,设置用户名、密码,并且捕获异常。
public void closeWifiAp() {
}
关闭热点的方法,若重新设置了名称或者密码,需要先关闭热点,再重新开启。
public class MainActivity extends Activity {
public static final String TAG = "wifi_test";
@SuppressLint("ShowToast") @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WifiApConnector ApConnector = WifiApConnector.getInstance(this);
final EditText apName=(EditText)this.findViewById(R.id.wifiap_name);
final EditText apPassWord=(EditText)this.findViewById(R.id.wifiap_password);
Button setup_btn=(Button)this.findViewById(R.id.setup_wifiap_btn);
Button close_btn=(Button)this.findViewById(R.id.close_wifiap_btn);
setup_btn.setOnClickListener(new View.OnClickListener() {
@SuppressLint("ShowToast") @Override
public void onClick(View v) {
final String ap_name=apName.getText().toString();
Log.i(TAG,"wifi_test"+ap_name);
final String ap_password=apPassWord.getText().toString();
Log.i(TAG,"wifi_test"+ap_password);
if (ap_name!=null && ap_password!=null&&(!"".equals(ap_name))&&(!"".equals(ap_password))){
try {
ApConnector.setupWifiAp(ap_name,ap_password);
Toast.makeText(getApplicationContext(), "热点已经创建 ", 1).show();
} catch (Exception e) {
}
Log.i(TAG,"wifi_test"+ap_password);
}
if (ap_name==null||"".equals(ap_name)||ap_password==null||"".equals(ap_password)){
Toast.makeText(getApplicationContext(), "请正确输入ssid和密码 ", 1).show();
Log.i(TAG,"请正确输入ssid和密码");
}
}
});
close_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ApConnector.closeWifiAp();
Toast.makeText(getApplicationContext(), "热点已经关闭", 1).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
在开启热点之前,先要对输入框的内容进行判断,若用户名和密码有一个为空,则提示正确输入,若都不为空,则判定密码是否满足八位数,并且传入相应的参数。
若要建立没有密码的热点,可以根据多态的性能,重写一个start方法,并且只传入name参数。
如下为布局文件: