首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >让安卓同时使用WiFi和移动数据与服务器通信?

让安卓同时使用WiFi和移动数据与服务器通信?
EN

Stack Overflow用户
提问于 2014-06-26 19:21:47
回答 2查看 13.5K关注 0票数 20

我正在开发一个安卓应用程序,通过无线连接到OBD2设备,应用程序可以读取速度,转速,发动机冷却剂温度细节等。所以Wifi只用于连接OBD2设备(它没有与互联网连接的设施,只用于与当地客户通信)。我还需要一个网络服务的互联网连接。但是在我连接了wifi之后,我无法在android中通过我的移动数据网络连接互联网。

类似的应用也是为iOS开发的。在iOS中,我可以从我的蜂窝网络使用无线设备(静态无线设置)和互联网连接。这意味着为我的wifi配置一些静态ip,我可以在iOS中使用移动数据网络进行互联网连接。

但在Android中,如果我使用静态wifi并检查互联网连接,它是不可用的。

如何通过在android中配置Wifi设置来同时使用wifi和互联网连接?

EN

回答 2

Stack Overflow用户

发布于 2019-01-03 17:30:44

首先,我们在这里可能面临的问题是,由于WiFi网络上没有internet连接,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具有正确的连接:

代码语言:javascript
运行
复制
<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" />

变量:

代码语言:javascript
运行
复制
private ConnectivityManager.NetworkCallback mWifiNetworkCallback, mMobileNetworkCallback;
private Network mWifiNetwork, mMobileNetwork;

获取连接管理器:

代码语言:javascript
运行
复制
final ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);

构建网络回调:

代码语言:javascript
运行
复制
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();
            }
        }
    };
}

请求网络:

代码语言:javascript
运行
复制
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);

发出如下所示的适当请求:

代码语言:javascript
运行
复制
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();
    }
}

注意:这些功能可以从安卓棒棒糖或更高版本获得。因此,有必要在适当的地方使用Build.Version.SDK_INT,如下所示:

代码语言:javascript
运行
复制
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
票数 10
EN

Stack Overflow用户

发布于 2014-08-22 20:48:50

代码语言:javascript
运行
复制
connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress);

您可以请求某个hostAddress,要求它必须使用该类型的连接。如果你使用Hipri,那么它将占用移动网络。但这可能会失败!如果工作正常,则到该地址的所有连接都将通过该类型的连接。

您可能需要先激活它。

代码语言:javascript
运行
复制
int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");

这可能需要几秒钟的时间,因为硬件模块必须启动。

我已经在几个项目中使用了它,并且效果很好。在像2.2这样的旧设备上,它的反应会非常不稳定!但我在4.0+上没有发现任何问题

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24429190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档