如何在 Android 8.0 (Oreo) 中以编程方式打开 on/off wifi 热点
How to turn on/off wifi hotspot programmatically in Android 8.0 (Oreo)
我知道如何使用以下方法在 android 中使用反射打开 on/off wifi 热点。
private static boolean changeWifiHotspotState(Context context,boolean enable) {
try {
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Method method = manager.getClass().getDeclaredMethod("setWifiApEnabled", WifiConfiguration.class,
Boolean.TYPE);
method.setAccessible(true);
WifiConfiguration configuration = enable ? getWifiApConfiguration(manager) : null;
boolean isSuccess = (Boolean) method.invoke(manager, configuration, enable);
return isSuccess;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
但是上面的方法不行Android8.0(Oreo).
当我在 Android 8.0 中执行上述方法时,我在 logcat.
中得到以下语句
com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true
有没有其他方法可以在 android 8.0
上 on/off 热点
终于找到解决办法了。
Android8.0,他们提供publicapi开启on/off热点。 WifiManager
下面是开启热点的代码
private WifiManager.LocalOnlyHotspotReservation mReservation;
@RequiresApi(api = Build.VERSION_CODES.O)
private void turnOnHotspot() {
WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {
@Override
public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
super.onStarted(reservation);
Log.d(TAG, "Wifi Hotspot is on now");
mReservation = reservation;
}
@Override
public void onStopped() {
super.onStopped();
Log.d(TAG, "onStopped: ");
}
@Override
public void onFailed(int reason) {
super.onFailed(reason);
Log.d(TAG, "onFailed: ");
}
}, new Handler());
}
private void turnOffHotspot() {
if (mReservation != null) {
mReservation.close();
}
}
onStarted(WifiManager.LocalOnlyHotspotReservation reservation)
方法将在热点打开时被调用。使用 WifiManager.LocalOnlyHotspotReservation
引用你调用 close()
方法来 关闭热点 .
注:
要打开热点,应在设备中启用 Location(GPS)
。否则,它会抛出 SecurityException
我认为 LocalOnlyHotspot
路线是通往的道路,但正如@edsappfactory.com 在评论中所说 - 它只提供封闭网络,无法访问互联网。
在 Oreo hot-spotting/tethering 中移动到 ConnectionManager
,并且其注释 @SystemApi
,因此(名义上)无法访问。
作为我正在做的其他事情的一部分,我制作了一个应用程序并将其放在 github here. It uses reflection to get at the function and DexMaker 上以生成 ConnectionManager.OnStartTetheringCallback
的子类(这也是不可访问的)。
觉得一切正常 - 边缘有点粗糙,所以请随时改进!
相关代码位在:
我失去了耐心试图让我的 DexMaker-generated 回调触发 MyOnStartTetheringCallback
所以所有的代码都是混乱的并且被注释掉了。
根据 Job 的建议,我找到了另一种在 Android Oreo 及更高版本中启用 Wifi HotSpot 的方法。
public boolean enableTetheringNew(MyTetheringCallback callback) {
File outputDir = mContext.getCodeCacheDir();
try {
proxy = ProxyBuilder.forClass(classOnStartTetheringCallback())
.dexCache(outputDir).handler(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "onTetheringStarted":
callback.onTetheringStarted();
break;
case "onTetheringFailed":
callback.onTetheringFailed();
break;
default:
ProxyBuilder.callSuper(proxy, method, args);
}
return null;
}
}).build();
} catch (IOException e) {
e.printStackTrace();
}
ConnectivityManager manager = (ConnectivityManager) mContext.getApplicationContext().getSystemService(ConnectivityManager.class);
Method method = null;
try {
method = manager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, classOnStartTetheringCallback(), Handler.class);
if (method == null) {
Log.e(TAG, "startTetheringMethod is null");
} else {
method.invoke(manager, TETHERING_WIFI, false, proxy, null);
}
return true;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return false;
}
private Class classOnStartTetheringCallback() {
try {
return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
我知道如何使用以下方法在 android 中使用反射打开 on/off wifi 热点。
private static boolean changeWifiHotspotState(Context context,boolean enable) {
try {
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Method method = manager.getClass().getDeclaredMethod("setWifiApEnabled", WifiConfiguration.class,
Boolean.TYPE);
method.setAccessible(true);
WifiConfiguration configuration = enable ? getWifiApConfiguration(manager) : null;
boolean isSuccess = (Boolean) method.invoke(manager, configuration, enable);
return isSuccess;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
但是上面的方法不行Android8.0(Oreo).
当我在 Android 8.0 中执行上述方法时,我在 logcat.
com.gck.dummy W/WifiManager: com.gck.dummy attempted call to setWifiApEnabled: enabled = true
有没有其他方法可以在 android 8.0
上 on/off 热点终于找到解决办法了。 Android8.0,他们提供publicapi开启on/off热点。 WifiManager
下面是开启热点的代码
private WifiManager.LocalOnlyHotspotReservation mReservation;
@RequiresApi(api = Build.VERSION_CODES.O)
private void turnOnHotspot() {
WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {
@Override
public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
super.onStarted(reservation);
Log.d(TAG, "Wifi Hotspot is on now");
mReservation = reservation;
}
@Override
public void onStopped() {
super.onStopped();
Log.d(TAG, "onStopped: ");
}
@Override
public void onFailed(int reason) {
super.onFailed(reason);
Log.d(TAG, "onFailed: ");
}
}, new Handler());
}
private void turnOffHotspot() {
if (mReservation != null) {
mReservation.close();
}
}
onStarted(WifiManager.LocalOnlyHotspotReservation reservation)
方法将在热点打开时被调用。使用 WifiManager.LocalOnlyHotspotReservation
引用你调用 close()
方法来 关闭热点 .
注:
要打开热点,应在设备中启用 Location(GPS)
。否则,它会抛出 SecurityException
我认为 LocalOnlyHotspot
路线是通往的道路,但正如@edsappfactory.com 在评论中所说 - 它只提供封闭网络,无法访问互联网。
在 Oreo hot-spotting/tethering 中移动到 ConnectionManager
,并且其注释 @SystemApi
,因此(名义上)无法访问。
作为我正在做的其他事情的一部分,我制作了一个应用程序并将其放在 github here. It uses reflection to get at the function and DexMaker 上以生成 ConnectionManager.OnStartTetheringCallback
的子类(这也是不可访问的)。
觉得一切正常 - 边缘有点粗糙,所以请随时改进!
相关代码位在:
我失去了耐心试图让我的 DexMaker-generated 回调触发 MyOnStartTetheringCallback
所以所有的代码都是混乱的并且被注释掉了。
根据 Job 的建议,我找到了另一种在 Android Oreo 及更高版本中启用 Wifi HotSpot 的方法。
public boolean enableTetheringNew(MyTetheringCallback callback) {
File outputDir = mContext.getCodeCacheDir();
try {
proxy = ProxyBuilder.forClass(classOnStartTetheringCallback())
.dexCache(outputDir).handler(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "onTetheringStarted":
callback.onTetheringStarted();
break;
case "onTetheringFailed":
callback.onTetheringFailed();
break;
default:
ProxyBuilder.callSuper(proxy, method, args);
}
return null;
}
}).build();
} catch (IOException e) {
e.printStackTrace();
}
ConnectivityManager manager = (ConnectivityManager) mContext.getApplicationContext().getSystemService(ConnectivityManager.class);
Method method = null;
try {
method = manager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, classOnStartTetheringCallback(), Handler.class);
if (method == null) {
Log.e(TAG, "startTetheringMethod is null");
} else {
method.invoke(manager, TETHERING_WIFI, false, proxy, null);
}
return true;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return false;
}
private Class classOnStartTetheringCallback() {
try {
return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}