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

Android个开源的移动操作系统,由Google开发。它的各个版本都有不同的特性和适配要求。下面是Android各个版本的适配情况: 1. Android 1.0:这是Android的首个正式版本,发布于2008年。它主要适配了当时的早期智能手机。 2. Android 1.5 Cupcake:这个版本引入了许多新特性,包括虚拟键盘、文本选择和复制功能等。它的适配要求相对较低,可以在较旧的设备上运行。 3. Android 1.6 Donut:这个版本增加了搜索框和快捷方式等功能。它的适配要求与Cupcake相似。 4. Android 2.0/2.1 Eclair:这个版本引入了许多新特性,包括支持多点触控、HTML5视频播放和Live壁纸等。它的适配要求相对较高,需要较新的设备支持。 5. Android 2.2 Froyo:这个版本引入了许多新特性,包括支持移动热点和Adobe Flash等。它的适配要求与Eclair相似。 6. Android 2.3 Gingerbread:这个版本引入了许多新特性,包括支持NFC和下载管理器等。它的适配要求相对较高,需要较新的设备支持。 7. Android 4.0 Ice Cream Sandwich:这个版本引入了许多新特性,包括全新的用户界面和面部解锁等。它的适配要求相对较高,需要较新的设备支持。 8. Android 4.1/4.2/4.3 Jelly Bean:这个版本引入了许多新特性,包括Google Now和通知增强等。它的适配要求与Ice Cream Sandwich相似。 9. Android 4.4 KitKat:这个版本引入了许多新特性,包括透明状态栏和打印支持等。它的适配要求相对较高,需要较新的设备支持。 10. Android 5.0/5.1 Lollipop:这个版本引入了许多新特性,包括Material Design和多用户支持等。它的适配要求相对较高,需要较新的设备支持。 11. Android 6.0 Marshmallow:这个版本引入了许多新特性,包括指纹识别和运行时权限等。它的适配要求相对较高,需要较新的设备支持。 12. Android 7.0/7.1 Nougat:这个版本引入了许多新特性,包括分屏模式和通知增强等。它的适配要求相对较高,需要较新的设备支持。 13. Android 8.0/8.1 Oreo:这个版本引入了许多新特性,包括自适应图标和通知渠道等。它的适配要求相对较高,需要较新的设备支持。 14. Android 9 Pie:这个版本引入了许多新特性,包括手势导航和应用程序切片等。它的适配要求相对较高,需要较新的设备支持。 15. Android 10:这个版本引入了许多新特性,包括暗黑模式和系统级录屏等。它的适配要求相对较高,需要较新的设备支持。 16. Android 11:这个版本引入了许多新特性,包括聊天气泡和无线Android Auto等。它的适配要求相对较高,需要较新的设备支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值