android 6.0 wifi开发,android热点 8.0 ,7.1 ,6.0一7.0 以及6.0以下热点创建到连接完全适配...

项目里面有个面对面快传的功能,开始自己确定需求的时候想,不就是开启一个热点,然后另一方连上,然后就使用udp通信完事儿.没想到这个开启热点然后wifi连接坑了比较久的时间,还好完成了,完成了.........

直接进入主题吧,6.0以下的开启热点网上一大堆这里就不做赘述.6.0-7.0主要就是需要添加一个修改系统设置的权限,和大部分申请动态权限的方法是一致的

//6.0需要的动态权限

public void initWithGetPermission(Activity context) {

boolean permission;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

permission = Settings.System.canWrite(context);

} else {

permission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED;

}

if (permission) {

init();

} else {

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {

Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);

intent.setData(Uri.parse("package:" + context.getPackageName()));

context.startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS);

} else {

ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_SETTINGS}, REQUEST_CODE_WRITE_SETTINGS);

}

}

}

//7.0之前开启热点的方法

public static boolean configApState(Context context, String apName) {

WifiManager wifimanager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);

WifiConfiguration wificonfiguration = null;

try {

wificonfiguration = new WifiConfiguration();

wificonfiguration.SSID = apName;

if (isApOn(context)) {

wifimanager.setWifiEnabled(false);

disableAp(context);

}

Method method = wifimanager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);

method.invoke(wifimanager, wificonfiguration, !isApOn(context));

return true;

} catch (Exception e) {

e.printStackTrace();

}

return false;

}

接下来就是7.1的适配,自己之前是是用的6.0的开启热点方法连接7.1的手机,虽然发现热点能够创建成功,但是其他手机无论怎么样都连接不上这个热点,而且一直显示的连接中,这是因为从7.1开始原先的接口WifiManager.java中setWifiApEnabled方法用来打开WiFi热点已经用不了了。这个时候只能用了一种投机取巧的方法,提示用户自己去开启热点,然后我们回来判断热点是否开启,这个时候万无一失其他手机肯定能连上这个热点.后来用了下QQ的面对面快传,发现QQ也是用这种方法,英雄所见略同(手动滑稽).

private void showRequestApDialogOnN_MR1() {

final CustomDialog dialog = new CustomDialog(this);

dialog.setMessage("android7.1系统以上不支持自动开启热点,需要手动开启热点");

dialog.setPositiveButton("去开启", new CustomDialog.onPositiveOnclickListener() {

@Override

public void onYesClick() {

dialog.dismiss();

openAP();

}

});

dialog.setNegativeButton("退出", new CustomDialog.onNoOnclickListener() {

@Override

public void onNoClick() {

finishBack();

dialog.dismiss();

}

});

dialog.show();

}

//打开系统的便携式热点界面

private void openAP() {

Intent intent = new Intent();

intent.setAction(Intent.ACTION_MAIN);

ComponentName com = new ComponentName("com.android.settings", "com.android.settings.TetherSettings");

intent.setComponent(com);

startActivityForResult(intent, 1000);

}

//判断用户是否开启热点 getWiFiAPConfig(); 这个方法去获取本机的wifi热点的信息就不贴了

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (requestCode == REQUEST_CODE_WRITE_SETTINGS && Settings.System.canWrite(this)) {

init();

} else if (requestCode == 1000) {

if (!ApMgr.isApOn(this)) {

showRequestApDialogOnN_MR1();

} else {

getWiFiAPConfig();

}

}

}

到此基本7.1的手机开启热点基本都能连上了

接下来是8.0的适配 关于8.0的热点网上的文章还是挺多的,我这里使用的startLocalOnlyHotspot这个方法 具体开启的方法如下

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

wifiManager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {

@TargetApi(Build.VERSION_CODES.O)

@Override

public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {

super.onStarted(reservation);

WifiConfiguration wifiConfiguration = reservation.getWifiConfiguration();

ssid = wifiConfiguration.SSID;

mHandler.obtainMessage(2018, wifiConfiguration).sendToTarget();

}

@Override

public void onStopped() {

super.onStopped();

}

@Override

public void onFailed(int reason) {

super.onFailed(reason);

}

}, mHandler);

通过这个方法开启热点,我们是不能设置热点的名称以及密码的只能使用系统生成的随机密码和名称

以上概括了生成热点的方法,但是在连接热点的时候,有可能存在连接不上热点的情况,我针对网上某些这部分功能代码做了修改,目前在我测试的所有机型基本都是能两两连上的,如下

public static WifiConfiguration createWifiCfg(String ssid, String password, int type){

WifiConfiguration config = new WifiConfiguration();

config.allowedAuthAlgorithms.clear();

config.allowedGroupCiphers.clear();

config.allowedKeyManagement.clear();

config.allowedPairwiseCiphers.clear();

config.allowedProtocols.clear();

config.SSID = "\"" + ssid + "\"";

if(type == WIFICIPHER_NOPASS){

config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

}else if(type == WIFICIPHER_WEP){

config.hiddenSSID = true;

config.wepKeys[0]= "\""+password+"\"";

config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);

config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);

config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

config.wepTxKeyIndex = 0;

}else if(type == WIFICIPHER_WPA){// WPA/WPA2 PSK的加密方式都可以通过此方法连上热点 也就是说我们连接热点只用分为有密码和无密码情况

config.preSharedKey = "\""+password+"\"";

config.hiddenSSID = true;

config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);

config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);

config.status = WifiConfiguration.Status.ENABLED;

}

return config;

}

最后提下在我们生成我们需要的热点名称的时候最好后面最好带个随机数,如时间戳?避免这个名称被使用过导致我们的热点可能链接不上...

8.0的热点关闭的问题:在api26的源码中我们可以看到有一个方法是关闭热点的

9dbb02c3e21f

系统关闭热点的方法

这个方法是类私有的,所以我们只能去上一层发现有两个地方调用了它

9dbb02c3e21f

第一个调用的地方

很好,这个是公用的方法,不过被标志成了hide,这意味着我们只能通过反射来调用这个方法了.但是我们使用第二个方法可以更简单的关闭热点,看看另一个调用关闭方法的地方

9dbb02c3e21f

我采用的方式

至于这个对象LocalOnlyHotspotReservation我们在开启热点的在start的时候它会给我们返回一个它的对象,我们只用把它存起来在finish的时候调用LocalOnlyHotspotReservation的close方法就行了,如下

9dbb02c3e21f

使用方式

退出的时候

9dbb02c3e21f

需要关闭热点的时候.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值