我可以同时打开Android上的Wi-Fi和蜂窝网络接口吗?

20

我正在开发一个应用程序,它将在手机上运行,并且手机将成为私人Wi-Fi网络上的一个站点。手机将充当一个站点,而不是接入点,并且私人WiFi网络不会路由到互联网。我的应用程序需要同时与互联网上的服务器以及本地WiFi网络上的设备进行通信,因此它需要同时连接两个网络。我一直在尝试找出如何做到这一点。

我一直在尝试使用谷歌Android开发者组讨论中描述的技术,标题为“Android 2.X能否同时连接3G和Wifi数据网络?”,但它效果不佳。我发现,当我调用 ConnectivityManager.setNetworkPreference(ConnectivityManager.TYPE_MOBILE)启用蜂窝网络时,任何已经打开的WiFi网络上的sockets都会被关闭。虽然我没有尝试过,但我怀疑当我切换回WiFi时,蜂窝网络上的sockets也会发生同样的情况。

另一个问题是,这些调用在全局级别操作,改变整个手机的网络设置,而不仅仅是应用程序。像这样全局性地切换网络设置会干扰手机上正在运行的任何其他应用程序。即使在我的应用程序退出后,手机仍然以它设置的最后一个网络配置继续运行。

我正在寻找一种方式,可以同时在蜂窝数据和WiFi网络上打开连接,而不会干扰手机上运行的其他应用程序。

  1. 有谁知道如何做到这一点吗?
  2. 有人知道这是否可能吗?

1
类似的问题?https://dev59.com/oVXTa4cB1Zd3GeqP4sBB - Marvin Pinto
9个回答

2
这其实很简单。您需要提交两个请求:一个使用 cellular 传输类型的网络请求,以及另一个使用 wifi 传输类型的附加请求。然后,使用从这些请求返回的任何网络,按需使用它们(例如,仅在从 wifi 请求返回的网络上处理内部资源)。
以下是同时保持 Wi-Fi 和 Cellular 连接的示例:
final ConnectivityManager connectivityManager = (ConnectivityManager)
  context.getSystemService(Context.CONNECTIVITY_SERVICE);

final NetworkRequest requestForWifi =
  new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
  .build();

final NetworkRequest requestForCellular =
  new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
  .build();

final NetworkCallback cbWifi = new NetworkCallback() {
  @Override
  void onAvailable(Network network) {
      // Triggers when this network is available so you can bind to it.
      
      // Examples of how to bind to it include 
      // (uncomment the best option for your use-case):
      
      // If you want to set connections for the entire app
      // connectivityManager.bindProcessToNetwork(network);

      // If you want to open a specific connection:
      // By socket:
      // try (Socket socket = new Socket()) {
      //     Network network = getNetwork();
      //     network.bindSocket(socket);
      // }
      // Or by URL:
      // URLConnection conn = network.openConnection(URL url);
  }
};

final NetworkCallback cbCellular = new NetworkCallback() {
  @Override
  void onAvailable(Network network) {
      // Triggers when this network is available so you can bind to it.
  }
};

connectivityManager.requestNetwork(requestForWifi, cbWifi);
connectivityManager.requestNetwork(requestForCellular, cbCellular);

只要有特定网络类型的请求(如Wi-Fi或蜂窝网络),则“ConnectivityManager”所依赖的服务“ConnectivityService”将保持这些网络可用。因此,使用上面的模式但调整“NetworkRequest”对象以满足您的需求,您可以保持任意数量的网络可用。

1

这个Android:强制使用无线电而不是WiFi发送数据的主题提到了两种可能的解决方法。

  1. 每当您希望应用程序使用特定连接时,请设置网络首选项:

    ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    cm.setNetworkPreference(ConnectivityManager.TYPE_MOBILE);
    
  2. 启用高优先级移动数据连接:

    connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
    
对于第二种方法,明确指出它适用于Android 2.2,不知道在实际版本中是否也适用。然而据我所知,enableHIPRI更像是一个隐藏的网络设置,所以如果可能的话,我更倾向于使用第一种方法。

0

我认为同一时间只能使用一项服务。你可以使用WiFi,也可以使用移动3G数据。但两者不能同时工作。


0

没有 root 权限,应用程序无法产生太大的影响。

使用 Android API,你最多只能打开 WiFi,希望设备会切换到它,并关闭 WiFi 以使设备切换到 3G(如果有的话,APN 正确等)。

其他任何事情都不能保证有效。例如,设置首选连接类型并不保证设备会切换到该类型。

通常的行为是,一旦 WiFi 可用,设备将同时开启 3G 和 WiFi 一小段时间(3-5 秒),然后关闭 3G。一旦用户或您的应用程序关闭 WiFi 并尝试连接到互联网,设备将在短时间内打开 3G。

从 Android 2.3 开始,你甚至不能再禁用/启用 3G。过去可以破坏/恢复 APN 设置以启用/禁用 3G,但从 4.0 开始,你不能通过编程方式更改 APN 设置。


不完全正确 - 仍然可以手动禁用3G。只需打开拨号器并输入 *#*#4636#*#*。然后点击“电话信息”和“关闭无线电”。 - Nathan Osman

0

如果我没有记错,如果同时有Wi-Fi和3G/4G可用,Wi-Fi将优先连接。

只有当Wi-Fi不可用时,它才会切换到3G/4G。当然,这需要同时开启两者。

与其使用私人Wi-Fi从而限制您的选择,您可以考虑拥有一个面向互联网的VPN,这样设备将从3G/4G连接到VPN,如果安全是您使用私人Wi-Fi的原因,则随后访问数据。

而且,VPN客户端已内置于Android中,并且还提供第三方客户端。


0

你可能想要了解一下临时 wifi 网络。它可以通过 wifi 连接到设备,即使安卓手机已经在使用 wifi 上网(不过不使用 IP 协议栈)。

不要混淆 wifi(IEEE 802.11x)连接和互联网(IP)连接。 IP 可以在 wifi、移动网络、以太网、DSL、拨号或家鸽子网络上运行,但一次只能连接一个网络。

如果想获取有关临时 wifi 网络的更多信息,请查看以下链接。

https://code.google.com/p/android-wifi-tether/

请注意,许多运营商禁止多播(共享)其IP连接。不错。

0

目前在Android应用程序中无法同时使用两个网络,但您可以在PC上这样做。
从WIFI路由器连接一个,从LAN或USB互联网棒连接另一个。
因此,请创建应用程序并在PC上使用。如果您不知道如何在PC上运行Android,则可以搜索谷歌。


0

3G和Wifi数据网络不能同时连接,但如果运营商支持并且Android框架也为运营商进行了更改,则可以同时连接3G和Wifi。 现在一些运营商已经具备了这个功能,但有些则没有。


0

如果你无法通过API调用实现,并且愿意在较低层次上动手操作,一些Linux知识可能会有所帮助。 基本上,你需要启动两个接口,并将默认路由设置在3G接口上。 对于这种任务,你需要使用具有root权限的系统命令。 关闭套接字的原因可能是接口因API调用而断开并重新连接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接