2015-12-02 49 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