2015-12-02 61 views
7

我在我的Android应用程序运行的命令行参数,如:Android的运行Exec用NetworkRequest

ProcessBuilder pb = new ProcessBuilder(cmds); 
Process process = pb.start(); 
process.waitFor(); 

cmds是参数运行列表。我的命令通过http连接探测远程URL。我的设备已连接到无法访问互联网的WiFi网络,但却托管了我想要探测的网址。我的设备也有蜂窝连接,可以访问互联网,但不能访问网址。我的设备运行Android 6.0棉花糖。

通常在棒棒糖或以上,Android默认为网络连接到互联网。要访问没有互联网的WiFi网络,您需要使用NetworkRequest,例如:https://stackoverflow.com/a/27958106/1847734

如何将获得的Network传递给上述Process,以便连接通过我的WiFi网络,而不是我的蜂窝网络?我需要使用ConnectivityManager#bindProcessToNetwork吗?如何加入使用此方法设置网络的过程?似乎没有选择给这个过程。

+0

棘手的问题。如果您在构建和启动流程之前将网络绑定到您的应用程序流程,那么您是否如此幸运以至于网络被继承? – totoro

+0

不幸的是,没有它似乎没有。 –

+0

@JonG你最终如何解决这个问题?建议你是否使用本地实现?我有完全相同的问题,我能够绑定“正常”的网络请求API> = 21,但无法找到一种方法来绑定一个进程(我也需要使用'ping'进行测试) – soey

回答

6

从棒棒糖开始NetworkParcelable所以你可以把它写到一个字节数组然后回读。我们从写作部分开始。

final Parcel parcel = Parcel.obtain(); 
try { 
    // Create a byte array from Network. 
    parcel.writeParcelable(network, 0); 
    final byte[] data = parcel.marshall(); 

    // Start a process. 
    ProcessBuilder pb = new ProcessBuilder(cmds); 
    Process process = pb.start(); 

    // Send serialized Network to the process. 
    final DataOutputStream out = new DataOutputStream(process.getOutputStream()); 
    out.write(data.length); 
    out.write(data); 

    // Wait until the process terminates. 
    process.waitFor(); 
} finally { 
    parcel.recycle(); 
} 

而阅读部分。

// Read data from the input stream. 
final DataInputStream in = new DataInputStream(System.in); 
final int length = in.readInt(); 
final byte[] data = new byte[length]; 
in.readFully(data); 

final Parcel parcel = Parcel.obtain(); 
try { 
    // Restore Network from a byte array. 
    parcel.unmarshall(data, 0, data.length); 
    final Network network = parcel.readParcelable(null); 

    // Use the Network object to bind the process to it. 
    connectivityManager.bindProcessToNetwork(network); 
} finally { 
    parcel.recycle(); 
} 

此代码仅适用于Android 6.0。如果你想要它在棒棒糖上工作,你应该使用ConnectivityManager.setProcessDefaultNetwork(Network)而不是ConnectivityManager.bindProcessToNetwork(Network)。此代码不适用于Android 5.0之前的设备。

UPDATE

对于非Android程序可以创建一个插座,它Network.bindSocket(Socket)绑定到联播网,并通过套接字描述符子进程。

如果以前的方法对您不适用,您可以从multinetwork.h调用NDK函数android_setsocknetwork,甚至尝试执行Android将进程绑定到给定网络时执行的操作。你可能感兴趣的一切发生在netd clientNetdClient发送消息给fwmarkdhere传递一个网络ID。实际发送的消息发生在here。但我会建议使用这种方法作为解决问题的最后机会方式。

+0

我didn不知道你可以打包一个网络,这很有趣,但是我的进程在命令行上运行了一个编译好的二进制文件,所以我认为我不能在那里传递网络。 –

+0

在答案中增加了更多信息。 – Michael