最近项目需要一个开启WiFi热点的功能,由于Android 7.1实现机制跟之前版本有所不同,在网上搜索了很久终于解决了这个问题,特意把过程记录下来,希望大家不要踩坑。
开启WiFi热点函数 主要参考博客 : https://blog.csdn.net/zhang01/article/details/79222057
可以用一个按钮来触发开启热点。
public boolean setWifiApEnabled(boolean enabled) {
if (enabled) { // disable WiFi in any case
wifiManager.setWifiEnabled(false);
}
wifiManager = (WifiManager)getApplicationContext().getSystemService(WIFI_SERVICE);
mContext = this;
handler = new Handler(getMainLooper());
try {
mResultReceiver = new ResultReceiver(handler);
WifiConfiguration apConfig = new WifiConfiguration();
apConfig.SSID = "asdf";
apConfig.preSharedKey = "12121212";
apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
Method mMethod = wifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
mMethod.invoke(wifiManager,apConfig);
ConnectivityManager connectivityManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
Field mField = connectivityManager.getClass().getDeclaredField("TETHERING_WIFI");
mField.setAccessible(true);
WriteToLog.writeToLog("field.setAccessible ");
int mTETHERING_WIFI = (int)mField.get(connectivityManager);
Log.v("mTETHERING_WIFI:",String.valueOf(mTETHERING_WIFI));
Field iConnMgrField = connectivityManager.getClass().getDeclaredField("mService");
iConnMgrField.setAccessible(true);
Object iConnMgr = iConnMgrField.get(connectivityManager);
Class<?> iConnMgrClass = Class.forName(iConnMgr.getClass().getName());
Method mStartTethering1 = iConnMgrClass.getMethod("startTethering", int.class,ResultReceiver.class,boolean.class);
mStartTethering1.setAccessible(true);
mStartTethering1.invoke(iConnMgr, mTETHERING_WIFI,new ResultReceiver(handler){
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
}
},true);
return true;
} else {
Method method = wifiManager.getClass().getMethod(
"setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
return (Boolean) method.invoke(wifiManager, apConfig, enabled);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
WriteToLog.writeToLog("setWifiApEnabled Exception1: " + e.getMessage());
return false;
} catch (InvocationTargetException e) {
e.printStackTrace();
WriteToLog.writeToLog("setWifiApEnabled Exception2: " + e.getMessage());
return false;
} catch (IllegalAccessException e) {
e.printStackTrace();
WriteToLog.writeToLog("setWifiApEnabled Exception3: " + e.getMessage());
return false;
} catch (ClassNotFoundException e) {
e.printStackTrace();
WriteToLog.writeToLog("setWifiApEnabled Exception4: " + e.getMessage());
return false;
} catch (NoSuchFieldException e) {
e.printStackTrace();
WriteToLog.writeToLog("setWifiApEnabled Exception5: " + e.getMessage());
return false;
}
}
但是运行这个代码以后会抛出异常InvocationTargetException :null
需要在AndroidManifest.xml文件中增添:android:sharedUserId="andorid.uid.system"
打包出apk,使用 signapk.jar 给自己的apk签名。
java -jar signapk.jar platform.x509.pem platform.pk8 src.apk dst.apk
将签名好的apk 使用adb push 到手机的/system/app下,注意要使用chmod更改权限
reboot 重启手机 此时你就会发现你的apk的user变成了system这个时候就可以成功开启热点了。