我正在开发一个通过Wifi和应用程序连接到OBD2设备的Android应用程序,可以读取速度,转速,发动机冷却液温度等详细信息等。因此,wifi仅用于连接OBD2设备(它没有&#39 ; t具有与互联网连接的便利,仅用于与本地客户通信)。我还需要一个用于Web服务的Internet连接。但在连接我的wifi后,我无法通过Android中的移动数据网络连接互联网。
类似的应用程序也是为iOS开发的。在iOS中,我可以通过Wifi(静态Wifi设置)和来自我的蜂窝网络的Internet连接使用设备。这意味着使用一些静态IP配置我的wifi我能够在iOS中使用移动数据网络进行Internet连接。
但在Android中,如果我使用静态wifi并检查Internet连接,则无法使用。
如何通过在Android中配置wifi设置来并行或以其他任何方式使用Wifi和Internet连接?
答案 0 :(得分:5)
connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);
您可以请求某个hostAddress必须使用该类型的连接。 如果你使用Hipri那么它将采用移动网络。 但这可能会失败!如果它可以工作,那么到该地址的所有连接都将覆盖那种类型的连接。
您可能必须先激活它。
int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
这可能需要几秒钟,因为硬件模块必须启动。
我在几个项目中使用它并且效果很好。 在像2.2这样的旧设备上它会反应真的不稳定! 但是我没有在4.0 +
上发现任何问题答案 1 :(得分:2)
首先,我们在这里可能面临的问题是,由于WiFi网络上没有互联网连接,因此HTTP数据将无法通过该连接。请参见Send request over WiFi (without connection) even if Mobile data is ON (with connection) on Android M以获取解决方案
但是,我遇到了有时没有HTTP请求成功的问题。为了解决这个问题,我们可以使用ConnectivityManager.requestNetwork()和Network.openConnection()来解决这个问题。
确保已启用移动数据和WiFi网络,并且Android Manifest具有正确的连接:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
变量:
private ConnectivityManager.NetworkCallback mWifiNetworkCallback, mMobileNetworkCallback;
private Network mWifiNetwork, mMobileNetwork;
获取连接管理器:
final ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
构建网络回调:
if(mWifiNetworkCallback == null){
//Init only once
mWifiNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(final Network network) {
try {
//Save this network for later use
mWifiNetwork = network;
} catch (NullPointerException npe) {
npe.printStackTrace();
}
}
};
}
if(mMobileNetworkCallback == null){
//Init only once
mMobileNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(final Network network) {
try {
//Save this network for later use
mMobileNetwork = network;
} catch (NullPointerException npe) {
npe.printStackTrace();
}
}
};
}
请求网络
NetworkRequest.Builder wifiBuilder;
wifiBuilder = new NetworkRequest.Builder();
//set the transport type do WIFI
wifiBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
manager.requestNetwork(wifiBuilder.build(), mWifiNetworkCallback);
NetworkRequest.Builder mobileNwBuilder;
mobileNwBuilder = new NetworkRequest.Builder();
//set the transport type do Cellular
mobileNwBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
manager.requestNetwork(mobileNwBuilder.build(), mMobileNetworkCallback);
像这样发出适当的请求:
public void makeHTTPRequest(final String httpUrl, final String payloadJson, final int timeout,
final boolean hasHeaders, final String header1, final String header2) {
try {
URL url = new URL(httpUrl);
HttpURLConnection conn = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
conn = (HttpURLConnection) mWifiNetwork.openConnection(url);
//Or use mMobileNetwork, if and when required
//conn = (HttpURLConnection) mMobileNetwork.openConnection(url);
} else {
conn = (HttpURLConnection) url.openConnection();
}
conn.setRequestProperty("Content-Type", "application/json");
conn.setReadTimeout(timeout * 1000);
conn.setConnectTimeout(timeout * 1000);
conn.setDoInput(true);
conn.setDoOutput(true);
if(hasHeaders){
conn.setRequestProperty("header1", header1);
conn.setRequestProperty("header2", header2);
}
conn.setRequestMethod("PUT");
OutputStream os = conn.getOutputStream();
os.write(payloadJson.getBytes());
os.close();
final int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
final String statusMessage = conn.getResponseMessage();
//Log this
}
} catch (SocketException se){
se.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
注意:
这些功能可从Android Lollipop及更高版本使用。因此,有必要在适当的地方使用Build.Version.SDK_INT
,如下所示:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {