故事背景:
笔者从Android 原生开发转岗到Flutter Web开发两年了,忽然接到一个反馈提供给第三方配网SDK线上配网失败的问题,且配网失败率在某些特定手机上为百分之九十以上,由于这个SDK前期是由我负责,这次只能责无旁贷的处理这件事。
第一时间下载了客户的Android客户端APP,用自己的手机测试添加设备,果然不出所料配网添加设备,可以说失败率为100%,这是一个很好的信号,有了这个可复现的场景,我们就能处理掉它。
第二时间查看了提供给客户sdk的版本,发现竟然是两年前的版本了,查看Git提交记录,统计出来两年内有关配网修改的相关记录,将主干上的修改点一一合并到SDK分支,重新集成后自测成功率为70%,提交客户验证发现问题依旧。
总结配网失败过程,发现在AP配网和流量有关,也就是手机在流量通道可用时,在使用AP配网阶段时,配网失败率极高,针对这个问题,公司自有APP也进行过处理,新集成的SDK也包括该优化点。
现在直接贴出解决方案,过程就不再一一赘述(大家都懂的,就是不停地......)。
connection_manager = (ConnectivityManager) mContext.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
NetworkRequest.Builder request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED);
networkCallback= new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
NetworkCapabilities capabilities = connection_manager.getNetworkCapabilities(network);
boolean isCapWifi = capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
boolean isAPConnected = apWifiHelper.isAPConnected(mContext,ApConstant.AP_OTHER_DEFAULT_SSID);
if (isCapWifi&& isAPConnected) {
ApTcpClient.getInstance().newSocket();
try {
network.bindSocket(ApTcpClient.getInstance().socket);
} catch (IOException e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connection_manager.bindProcessToNetwork(network);
} else {
ConnectivityManager.setProcessDefaultNetwork(network);
}
}else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connection_manager.bindProcessToNetwork(null);
} else {
ConnectivityManager.setProcessDefaultNetwork(null);
}
}
}
@Override
public void onUnavailable() {
super.onUnavailable();
}
};
connection_manager.registerNetworkCallback(request.build(),networkCallback );
}
} catch (Exception e) {
e.printStackTrace();
}
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED);
这三行是关键,第一行是指定通信通道,第二行是指网络不受限,第三行是信任网络,增加这个参数让设备连接wifi之后还联网
总结:这次AP配网失败主要是高版本Android系统的网络智能选择引起的,当系统检测到手机连接的Wifi为无外网的网络时,在通信时会智能切换到流量通道,导致AP配网失败,本次解决思路就是在AP配网阶段,强制指定socket 通道为WIFI通道,切忽略网络状态。
最后说明:本次修改针对是TargetSdk 版本28