ProcessBuilder pb = new ProcessBuilder(cmds); Process process = pb.start(); process.waitFor();
其中cmds是要运行的参数列表.我的命令通过http连接探测远程URL.我的设备连接到无法访问互联网的WiFi网络,但确实托管了我想要探测的网址.我的设备也有一个可以访问互联网的蜂窝连接,但不能访问URL.我的设备运行的是Android 6.0 Marshmallow.
通常在Lollipop或更高版本中,Android默认使用连接到互联网的网络.要访问没有Internet的WiFi网络,您需要使用NetworkRequest,例如:https://stackoverflow.com/a/27958106/1847734.
如何将获得的网络传递给上述进程,以便连接通过我的WiFi网络,而不是我的蜂窝网络?
我是否需要使用ConnectivityManager#bindProcessToNetwork?如何使用此方法加入设置网络的过程?似乎没有选择给予这个过程.
解决方法
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,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.如果你想让它在Lollipop上工作,你应该使用ConnectivityManager.setProcessDefaultNetwork(Network)而不是ConnectivityManager.bindProcesstoNetwork(网络).此代码在Android 5.0之前无法在设备上运行.
更新:
对于非Android进程,您可以创建套接字,使用Network.bindSocket(Socket)将其绑定到nework,并将套接字描述符传递给子进程.
如果以前的方法不适合您,您可以从multinetwork.h调用NDK函数android_setsocknetwork,或者甚至尝试执行Android将进程绑定到给定网络时执行的操作.您可能感兴趣的所有内容都发生在netd client.NetdClient向fwmarkd here发送一条消息,通过网络ID.实际的消息发送发生在here.但我建议使用这种方法作为解决问题的最后机会.