让Android同时使用WiFi与设备和移动数据通信与服务器通信?

Arc*_*ver 15 android wifi obd-ii

我正在开发一个通过Wifi连接到OBD2设备的Android应用程序,应用程序可以读取速度,转速,发动机冷却液温度等详细信息等.因此,wifi仅用于连接OBD2设备(它没有连接设施)互联网,仅用于与当地客户沟通​​).我还需要一个用于Web服务的Internet连接.但在连接我的wifi后,我无法通过Android中的移动数据网络连接互联网.

类似的应用程序也是为iOS开发的.在iOS中,我可以通过Wifi(静态Wifi设置)和来自我的蜂窝网络的Internet连接使用设备.这意味着使用一些静态IP配置我的wifi我能够在iOS中使用移动数据网络进行Internet连接.

但在Android中,如果我使用静态wifi并检查Internet连接,则无法使用.

如何通过在Android中配置wifi设置来并行或以其他任何方式使用Wifi和Internet连接?

Chr*_*met 5

connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);
Run Code Online (Sandbox Code Playgroud)

您可以请求某个hostAddress,它必须使用该类型的连接.如果你使用Hipri那么它将采用移动网络.但这可能会失败!如果它工作,那么到该地址的所有连接将覆盖该类型的连接.

您可能必须先激活它.

int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
Run Code Online (Sandbox Code Playgroud)

这可能需要几秒钟,因为硬件模块必须启动.

我在几个项目中使用它并且工作得很好.在像2.2这样的旧设备上它会反应真的不稳定!但是我没有在4.0+上发现任何问题

  • https://developer.android.com/sdk/api_diff/21/changes/android.net.ConnectivityManager.html这两种方法现已弃用... (2认同)

Ank*_*wal 5

首先,我们可能在这里面临的问题是,由于WiFi网络上没有互联网连接,因此HTTP数据将无法通过该连接。请参阅即使Android M上的移动数据处于打开状态(具有连接)也可以通过WiFi发送请求(无连接),以解决问题

但是,我遇到了有时没有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" />
Run Code Online (Sandbox Code Playgroud)

变量:

private ConnectivityManager.NetworkCallback mWifiNetworkCallback, mMobileNetworkCallback;
private Network mWifiNetwork, mMobileNetwork;
Run Code Online (Sandbox Code Playgroud)

获取连接管理器:

final ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
Run Code Online (Sandbox Code Playgroud)

建立网络回调:

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();
            }
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

请求网络:

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);
Run Code Online (Sandbox Code Playgroud)

发出这样的适当请求:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

注意: 这些功能在Android Lollipop及更高版本中可用。因此,有必要Build.Version.SDK_INT在适当的地方使用,例如:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
Run Code Online (Sandbox Code Playgroud)