Make Android simultaneously use WiFi to talk to a device and mobile data to talk to a server?

左心房为你撑大大i 提交于 2019-12-17 10:43:02

问题


I'm developing an Android application which connects to an OBD2 device by Wifi and app can read Speed, RPM, Engine coolant temperature details etc. So wifi is used only for connecting with the OBD2 device(it doesn't have facility to connect with internet, only for communication with local clients). I also need an internet connection for web services. But after connecting my wifi I am not able to connect internet via my mobile data network in android.

The similar application is also developed for iOS. In iOS, I can use device over Wifi (Static Wifi setting) and Internet connection from my cellular network. It means configure my wifi with some static ip I am able to use mobile data network for Internet connection in iOS.

But in Android, If I use static wifi and check for Internet connection, it is not available.

How can I use Wifi and Internet connection both run parallel or any other way by configuring wifi settings in android ?


回答1:


connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);

You can request for a certain hostAddress that it must use that type of connectivity. IF you use Hipri then it will take the mobile network. But this can fail ! If it works, then ALL connections to that address will go over that type of connectivity.

You might have to activate it first.

int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");

This can take a couple of seconds, since the hardware modules has to start up.

I've use this on several projects and works great. On old device such as 2.2 it will react really unstable ! But I haven't found any problems on 4.0+




回答2:


Firstly, the problem we may face here is that because there is no internet connection on WiFi network, HTTP data will not go through that connection. See Send request over WiFi (without connection) even if Mobile data is ON (with connection) on Android M for solution

However, I have faced issue where sometimes no HTTP request is successful. To solve this problem, we can use ConnectivityManager.requestNetwork() and Network.openConnection() to achieve this.

Make sure that Mobile data and WiFi network is enabled and Android Manifest has proper connections:

<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" />

Variables:

private ConnectivityManager.NetworkCallback mWifiNetworkCallback, mMobileNetworkCallback;
private Network mWifiNetwork, mMobileNetwork;

Get the connectivity manager:

final ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);

Build network callbacks:

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();
            }
        }
    };
}

Request networks:

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);

Make the appropriate request like this:

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();
    }
}

Note: These functions are avaialble from Android Lollipop and above. So, it is necessary to use Build.Version.SDK_INT at appropriate place, like this:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {


来源:https://stackoverflow.com/questions/24429190/make-android-simultaneously-use-wifi-to-talk-to-a-device-and-mobile-data-to-talk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!