在android 7.1 之前 设置wifi ap方法如下:
WifiManager mWifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
mWifiManager.setWifiApEnabled(null, true)
android 7.1后 api 发生了变化 用 setWifiApEnabled打开会导致 连接热点失败,通过在 android 原生setting 查看源码 发现 7.1后 改用
import static android.net.ConnectivityManager.TETHERING_WIFI;
private Handler mHandler = new Handler();
private OnStartTetheringCallback mStartTetheringCallback;
...................
mStartTetheringCallback = new OnStartTetheringCallback(this);
ConnectivityManager mCm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
mCm.startTethering(TETHERING_WIFI, true, mStartTetheringCallback, mHandler);
private static final class OnStartTetheringCallback extends
ConnectivityManager.OnStartTetheringCallback {
final WeakReference mTetherSettings;
OnStartTetheringCallback(TetherSettings settings) {
mTetherSettings = new WeakReference(settings);
}
@Override
public void onTetheringStarted() {
update();
}
@Override
public void onTetheringFailed() {
update();
}
private void update() {
TetherSettings settings = mTetherSettings.get();
if (settings != null) {
settings.updateState();
}
}
}
这里7.1采用ConnectivityManager类的 startTethering方法 我们看下framework源码里面 startTethering原型
@SystemApi
public void startTethering(int type, boolean showProvisioningUi,
final OnStartTetheringCallback callback) {
startTethering(type, showProvisioningUi, callback, null);
}
@SystemApi
public void startTethering(int type, boolean showProvisioningUi,
final OnStartTetheringCallback callback, Handler handler) {
ResultReceiver wrappedCallback = new ResultReceiver(handler) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (resultCode == TETHER_ERROR_NO_ERROR) {
callback.onTetheringStarted();
} else {
callback.onTetheringFailed();
}
}
};
try {
mService.startTethering(type, wrappedCallback, showProvisioningUi);
} catch (RemoteException e) {
Log.e(TAG, "Exception trying to start tethering.", e);
wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
}
}
@SystemApi
public void stopTethering(int type) {
try {
mService.stopTethering(type);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
startTethering方法参数官方具体解释如下:
/**
* Runs tether provisioning for the given type if needed and then starts tethering if
* the check succeeds. If no carrier provisioning is required for tethering, tethering is
* enabled immediately. If provisioning fails, tethering will not be enabled. It also
* schedules tether provisioning re-checks if appropriate.
*
* @param type The type of tethering to start. Must be one of
* {@link ConnectivityManager.TETHERING_WIFI},
* {@link ConnectivityManager.TETHERING_USB}, or
* {@link ConnectivityManager.TETHERING_BLUETOOTH}.
* @param showProvisioningUi a boolean indicating to show the provisioning app UI if there
* is one. This should be true the first time this function is called and also any time
* the user can see this UI. It gives users information from their carrier about the
* check failing and how they can sign up for tethering if possible.
* @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller
* of the result of trying to tether.
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
* @hide
我们 代开wifi 热点 用 ConnectivityManager.TETHERING_WIFI
显示UI更新 ,这里用到 ConnectivityManager.OnStartTetheringCallback
由于这是一个静态的类,我们可以用过弱引用找到父类的 一些方法 和 Context等
来更新 打开热点的结果
private static final class OnStartTetheringCallback extends
ConnectivityManager.OnStartTetheringCallback {
final WeakReference mTetherSettings;
OnStartTetheringCallback(TetherSettings settings) {
mTetherSettings = new WeakReference(settings);
}
@Override
public void onTetheringStarted() {
update();
}
@Override
public void onTetheringFailed() {
update();
}
private void update() {
TetherSettings settings = mTetherSettings.get();
//**通过get方法找到父类的引用 并调用方法**
if (settings != null) {
settings.updateState();
}
}
}
最后在 7.1上面通过修改setWifiApEnabled方法 并成功连接到wifi ap 上网
PS: android7.1 startTethering方法是系统api 只能在系统源码里面编译 自己做了个jar包 以及导入的方法 还有demo apk 方便使用eclipse 的童鞋使用
注意:很多童鞋反应没有作用,请 ps | grep com.example.wifiap7 看下uid是否为 system , 7.1权限更严格.必须是system用户才能控制wifi热点,附件里面提供的platform签名文件为android原生的,其他厂家可能自己有改
android 7.1 wifi热点Demo