Android runtime exec with NetworkRequest

I am using the command line argument in my android application, for example:

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

Where cmds is a list of arguments to run. My teams validate the remote URL through an http connection. My device is connected to a WiFi network that does not have access to the Internet, but hosts a URL that I want to check. My device also has a cellular connection that has access to the Internet, but not a URL. Android 6.0 Marshmallow runs on my device.

Typically, in Lollipop or higher, Android is by default used on a network with an Internet connection. In order to access Wi-Fi networks without the Internet, you need to use NetworkRequest , for example: https://stackoverflow.com/a/212616/169 .

How to transfer the received Network above Process so that the connection passes through my WiFi network, and not my cellular network?

Do I need to use ConnectivityManager # bindProcessToNetwork ? How do I join a process to configure a network using this method? It seems that there is no way to give this process.

+7
android android-6.0-marshmallow networking wifi connection
source share
1 answer

Starting with Lollipop Network there is Parcelable , so you can write it to an array of bytes and then read it. Start with the recording part.

 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(); } 

And the reading part.

 // 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(); } 

This code will only work on Android 6.0. If you want it to work on Lollipop, you should use ConnectivityManager.setProcessDefaultNetwork(Network) instead of ConnectivityManager.bindProcessToNetwork(Network) . And this code will not work on devices prior to Android 5.0.

UPDATE

For a process other than Android, you can create a socket, bind it to nework using Network.bindSocket(Socket) and pass the socket handle to the child process.

If the previous approach does not work for you, you can call the NDK function android_setsocknetwork from multinetwork.h or even try and do what Android does when you bind the process to this network. Everything that may interest you occurs in the netd client . NetdClient sends a NetdClient message here , passing the network identifier. The actual sending of the message takes place here . But I would recommend using this approach as the last possible way to solve your problem.

+6
source share

All Articles