Android:强制数据通过无线电与 WiFi 发送

Posted

技术标签:

【中文标题】Android:强制数据通过无线电与 WiFi 发送【英文标题】:Android: Force data to be sent over radio vs WiFi 【发布时间】:2011-08-18 12:47:51 【问题描述】:

是否可以强制 android 应用程序仅使用移动无线电连接(3g/4g/等),禁止使用 WiFi?

我想我想使用 HIPRI 连接:(例如:WIFI 开启,使用 HIPRI 3G): http://groups.google.com/group/android-developers/browse_thread/thread/d41f85505484d29b

【问题讨论】:

How to use 3G Connection in Android Application instead of Wi-fi?的可能重复 【参考方案1】:

我不相信您可以“强制”连接路径而不暂时明确关闭 Wi-Fi 无线电(不推荐)。但是,您可以尝试在您希望发生这种情况的期间设置网络首选项:

ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
//Prefer mobile over wifi
cm.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);

//Do your work

//Remove your preference
cm.setNetworkPreference(ConnectivityManager.DEFAULT_NETWORK_PREFERENCE);

希望有帮助!

【讨论】:

就我的测试所见。在 ConnectivityService 的源代码中,您可以看到设置此首选项会导致系统尝试拆除任何已连接的非首选网络,因此它正在执行我们期望发生的事情。 codesearch.google.com/codesearch#uX1GffpyOZk/services/java/com/… 这个例子有点老了。更新为使用适当的常量将首选项重置为默认值。 这个触发器可以连接任何东西。悲伤的事情还是我需要更多的尝试?我需要使用 TCP 连接吗?因为系统将答案发送到另一个套接字中!我通过一个发送请求,并通过另一个接收回复!似乎 Android 更改了显式绑定套接字的 IP 地址。讨厌所有讨厌 UDP 并将他们的套接字绑定在 0.0.0.0 上的人。 :-) 谷歌,他们是糟糕的程序员,不是我的!为什么你听到他们而不是我?悲伤的时光。启示录。 setNetworkPreference() 在 API 级别 21 中已弃用 developer.android.com/reference/android/net/…【参考方案2】:

在 Android 2.2 中,您可以在使用 WiFi 的同时使用高优先级移动数据。 “feature”参数的值为“enableHIPRI”,隐藏在Phone API中。

方法: ConnectivityManager.startUsingNetworkFeature(int networkType, String feature) 的 http://developer.android.com/reference/android/net/ConnectivityManager.html

来源:http://code.google.com/p/android/issues/detail?id=5885

您可以查看其他答案:https://***.com/a/4756630/327011

这不是一个好政策...如果真的需要,请使用它!

【讨论】:

作为用户,您希望手机仅在 WiFi 断开连接时才能访问移动数据。如果此方法正常运行,您可能会在用户不知情或无法阻止的情况下增加移动数据费用。 不,不正确——作为用户,我希望我的 SIP确实有效,而 WiFi 无法保证,因此,我选择了仅使用 3G 的选项。但是,根据android.stackexchange.com/questions/61554/…,我现在在连接 WiFi 时根本没有任何 SIP。这是应用程序中的错误,还是无法在应用程序中修复的问题? 它不起作用。它会触发并只允许那些在 3G IP 上打开和绑定的套接字继续在另一个 Wi-Fi IP 上工作。谷歌那些疯狂的强盗认为打破经典伯克利套接字很棒。黑客们,看看你能在这里破解什么! ;-)【参考方案3】:

ConnectivityManager.setNetworkPreference() 即将被淘汰。但更重要的是,如果您在更改之前执行 getNetworkPreference(),它将返回 ConnectivityManager.TYPE_MOBILE。将其设置在那里没有任何区别。至于 HIPRI 本身,它以非常奇怪的模式工作。首先,它允许连接到所有主机,而不仅仅是那些明确请求的主机。其次,当您使用 stopUsingFeature...() 调用将其关闭时,它不会被关闭并且仍然处于活动状态。第三,即使 wifi 可用,所有设备应用程序都开始使用它,这与文档中所说的相矛盾。

【讨论】:

【参考方案4】:

(我回答了同样的问题here)

您不能在每个应用程序的基础上明确强制通信通道(您可以通过ConnectivityManager.setNetworkPreference(...) 请求使用首选模式,但这不是“强制”)。

虽然这可能是糟糕的用户体验,但您可以通知用户您的应用不允许使用 WiFi,然后如果他们想继续,请禁用他们的 WiFi。为此,您需要ACCESS_WIFI_STATECHANGE_WIFI_STATE 权限。代码看起来像这样:

manager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);

if(manager.isWifiEnabled()) 
    manager.setWifiEnabled(false);

// and to be sure:
ConnectivityManager.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);

【讨论】:

ConnectivityManager.setNetworkPreference() 即将被淘汰。但更重要的是,如果您在更改之前执行 getNetworkPreference(),它将返回 ConnectivityManager.TYPE_MOBILE。将它设置在那里没有任何区别。【参考方案5】:

试着看看这个,它有很多信息,可能有你正在寻找的解决方案:How to use 3G Connection in Android Application instead of Wi-fi?

它具有设置 HIPRI 移动连接并保持其运行的工作服务示例。 AFAIK 这是在 android 中使用 wifi 和 3g 的唯一或多或少直接的方法。唯一的缺点是,此连接仅允许将数据传输到明确请求路由的服务器。这基本上意味着您无法路由到许多服务器,因为按名称查找主机以获取 IP 地址需要时间,并且为 10 台服务器执行此操作需要 30-60 秒,这使得它启动缓慢。因此,您应该确切地知道哪些服务器应该通过移动连接可用。

【讨论】:

请注意,link-only answers are discouraged,SO 答案应该是寻找解决方案的终点(与另一个中途停留的参考相比,它往往会随着时间的推移变得陈旧)。请考虑在此处添加独立的概要,并保留链接作为参考。

以上是关于Android:强制数据通过无线电与 WiFi 发送的主要内容,如果未能解决你的问题,请参考以下文章

Android - 检测用户已离开网络无线范围并关闭 WiFi

强制 Android 在没有互联网的情况下使用 Wifi 网络

强制 Android 应用连接到某个 WiFi 网络

Android如何获取到连接的WIFI无线路由器的所有客户端的MAC地址?

填坑实录 Android Studio 利用 ADB WIFI 插件实现真机无线调试

打算用51单片机和ESP8266wifi模块做个无线传数据的东西,但是不知道怎么控制wifi模块发送数据