Created
November 17, 2016 15:43
-
-
Save TedaLIEz/9f1d422b5c2aa33dac7ea9bf1ac69de7 to your computer and use it in GitHub Desktop.
Socket using command adb forward to set up a tcp connection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.io.PrintWriter; | |
import java.net.Socket; | |
import java.net.SocketException; | |
import java.net.UnknownHostException; | |
import java.text.SimpleDateFormat; | |
import java.util.Arrays; | |
import java.util.Date; | |
import java.util.Scanner; | |
import java.util.concurrent.atomic.AtomicBoolean; | |
/** | |
* Created by JianGuo on 11/9/16. | |
* Client | |
*/ | |
public class AdbSocket { | |
private String[] deviceList; | |
private String[] deviceId; | |
private String deviceName; | |
private String device; | |
private AtomicBoolean isClientShutDown = new AtomicBoolean(false); | |
private boolean isConnected = false; | |
private static int PORT = 38300; | |
Socket socket; | |
PrintWriter out; | |
BufferedReader in; | |
public AdbSocket() { | |
} | |
public void execute() { | |
deviceList = CommandExecutor.execute("adb devices").split("\\r?\\n"); | |
System.out.println(Arrays.toString(deviceList)); | |
if (deviceList.length > 1) { | |
if (deviceList[1].matches(".*\\d.*")) { | |
deviceId = deviceList[1].split("\\s+"); | |
deviceName = "" + CommandExecutor.execute("adb -s " + deviceId[0] + " shell getprop ro.product.manufacturer") + | |
CommandExecutor.execute("adb -s " + deviceId[0] + " shell getprop ro.product.model"); | |
deviceName = deviceName.replaceAll("\\s+", " "); | |
System.out.println("\n device " + deviceName + " : " + deviceId[0]); | |
device = deviceId[0]; | |
System.out.println("\n deviceId " + device); | |
if (tcpForward()) { | |
connect(); | |
} | |
} else { | |
System.out.println("Please attach a device"); | |
} | |
} else { | |
System.out.println("Please attach a device"); | |
} | |
} | |
private boolean tcpForward() { | |
String rst = CommandExecutor.execute("adb -s " + device + " forward tcp:" + PORT + " tcp:" + PORT); | |
if (rst.length() == 0) { | |
return checkConnection(); | |
} else { | |
System.out.println(rst); | |
return false; | |
} | |
} | |
private boolean checkConnection() { | |
String[] connections = CommandExecutor.execute("adb forward --list").split("\\r?\\n"); | |
if (connections.length > 0) { | |
for (String connection : connections) { | |
String[] info = connection.split(" "); | |
String id = info[0]; | |
String remote = info[1]; | |
String local = info[2]; | |
System.out.println("Establish connection: " + "id : " + id + ", remote " + remote + ", local " + local); | |
} | |
return true; | |
} else { | |
System.out.println("No connection established!"); | |
return false; | |
} | |
} | |
public void removeAllConnection() { | |
CommandExecutor.execute("adb forward --remove-all"); | |
} | |
void onClientShutDown() { | |
System.exit(0); | |
} | |
private void connect() { | |
// reconnect(); | |
try { | |
socket = new Socket("localhost", PORT); | |
out = new PrintWriter(socket.getOutputStream(), true); | |
new Thread(readFromServer).start(); | |
Thread closeSocketOnShutdown = new Thread() { | |
public void run() { | |
try { | |
out.println("Device " + deviceName + " destroyed!"); | |
isClientShutDown.set(true); | |
socket.close(); | |
removeAllConnection(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
}; | |
Runtime.getRuntime().addShutdownHook(closeSocketOnShutdown); | |
out.println("Device " + deviceName + " ready!"); | |
Scanner scanner = new Scanner(System.in); | |
while (scanner.hasNextLine()) { | |
String message = scanner.nextLine(); | |
if (message.equals("exit")) { | |
onClientShutDown(); | |
break; | |
} | |
String time = formatDateTime(System.currentTimeMillis()); | |
String showedMsg = "client " + time + ":" + message; | |
out.println(showedMsg); | |
} | |
} catch (UnknownHostException e) { | |
System.out.println("Socket connection problem (Unknown host)" + e.getStackTrace()); | |
} catch (IOException e) { | |
System.out.println("Could not initialize I/O on socket " + e.getStackTrace()); | |
} | |
} | |
private Runnable readFromServer = new Runnable() { | |
@Override | |
public void run() { | |
if (!isClientShutDown.get()) { | |
String buffer = null; | |
try { | |
System.out.println("Reading From Server"); | |
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); | |
while ((buffer = in.readLine()) != null) { | |
dosomething(buffer); | |
} | |
} catch (SocketException e) { | |
System.err.println("Socket server not connected..."); | |
} catch (IOException e) { | |
try { | |
in.close(); | |
} catch (IOException e1) { | |
e1.printStackTrace(); | |
} | |
isClientShutDown.set(true); | |
System.err.println("Socket client closed, exiting..."); | |
} | |
} | |
} | |
}; | |
private void dosomething(String msg) { | |
System.out.println(msg); | |
} | |
public static void main(String[] args) { | |
AdbSocket adbSocket = new AdbSocket(); | |
adbSocket.execute(); | |
} | |
private String formatDateTime(long time) { | |
return new SimpleDateFormat("(HH:mm:ss)").format(new Date(time)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.hustunique.jianguo.adbsocket; | |
import android.app.Service; | |
import android.content.Intent; | |
import android.os.Binder; | |
import android.os.Handler; | |
import android.os.HandlerThread; | |
import android.os.IBinder; | |
import android.os.Message; | |
import android.support.v4.content.LocalBroadcastManager; | |
import android.util.Log; | |
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.io.PrintWriter; | |
import java.lang.ref.WeakReference; | |
import java.net.ServerSocket; | |
import java.net.Socket; | |
import java.net.SocketException; | |
import java.net.SocketTimeoutException; | |
/** | |
* Created by JianGuo on 11/9/16. | |
* We use Android devices as server. | |
*/ | |
public class AdbTcpService extends Service { | |
private boolean mIsServiceDestroyed; | |
private TcpConnection mConnection; | |
private volatile HandlerThread mThread; | |
private Handler mServiceHandler; | |
private LocalBroadcastManager mLocalBroadcastManager; | |
private UiHandler mUiHandler; | |
private static class UiHandler extends Handler { | |
private final WeakReference<LocalBroadcastManager> mManagerRef; | |
private final WeakReference<TcpConnection> mTcpRef; | |
UiHandler(LocalBroadcastManager manager, TcpConnection tcpConnection) { | |
super(); | |
mManagerRef = new WeakReference<LocalBroadcastManager>(manager); | |
mTcpRef = new WeakReference<TcpConnection>(tcpConnection); | |
} | |
@Override | |
public void handleMessage(Message msg) { | |
switch (msg.what) { | |
case SEND_FROM_CLIENT: | |
Intent intent = new Intent(ACTION); | |
intent.putExtra("data", (String) msg.obj); | |
LocalBroadcastManager manager = mManagerRef.get(); | |
if (manager != null) { | |
manager.sendBroadcast(intent); | |
} | |
break; | |
case SEND_FROM_SERVER: | |
TcpConnection connection = mTcpRef.get(); | |
if (connection != null && connection.socketOut != null) { | |
connection.socketOut.println((String) msg.obj); | |
} | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
private static final int SEND_FROM_CLIENT = 0; | |
private static final int SEND_FROM_SERVER = 1; | |
private static final String TAG = "TcpService"; | |
public static final String ACTION = "com.hustunique.jianguo.AdbTcpService"; | |
private final IBinder mBinder = new LocalBinder(); | |
public AdbTcpService() { | |
mIsServiceDestroyed = false; | |
} | |
public class LocalBinder extends Binder { | |
AdbTcpService getService() { | |
return AdbTcpService.this; | |
} | |
} | |
public void sendMessage(String message) { | |
Message msg = mUiHandler.obtainMessage(); | |
msg.obj = message; | |
msg.what = SEND_FROM_SERVER; | |
mUiHandler.sendMessage(msg); | |
} | |
@Override | |
public IBinder onBind(Intent intent) { | |
return mBinder; | |
} | |
@Override | |
public void onCreate() { | |
super.onCreate(); | |
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); | |
mConnection = new TcpConnection(); | |
mThread = new HandlerThread("TcpHandlerThread"); | |
mThread.start(); | |
mUiHandler = new UiHandler(mLocalBroadcastManager, mConnection); | |
mServiceHandler = new Handler(mThread.getLooper()); | |
mServiceHandler.post(mConnection); | |
} | |
@Override | |
public void onDestroy() { | |
super.onDestroy(); | |
// refuse to receive any other tasks in future | |
mThread.quit(); | |
mIsServiceDestroyed = true; | |
mConnection.closeServer(); | |
} | |
private class TcpConnection implements Runnable { | |
private static final int TIMEOUT = 10; | |
private ServerSocket mServer; | |
private Socket mClient; | |
private static final int PORT = 38300; | |
private BufferedReader socketIn; | |
private PrintWriter socketOut; | |
@Override | |
public void run() { | |
try { | |
mServer = new ServerSocket(PORT); | |
mServer.setSoTimeout(TIMEOUT * 10000); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
Log.e(TAG, "create server failed"); | |
return; | |
} | |
Log.d(TAG, "create server success!"); | |
while (!mIsServiceDestroyed) { | |
try { | |
mClient = mServer.accept(); | |
socketOut = new PrintWriter(mClient.getOutputStream(), true); | |
Thread readThread = new Thread(readFromClient); | |
readThread.setPriority(Thread.NORM_PRIORITY); | |
readThread.start(); | |
} catch (SocketTimeoutException e) { | |
Log.e(TAG, "Socket timeout "); | |
} catch (SocketException e) { | |
Log.e(TAG, "No socket connected"); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
private Runnable readFromClient = new Runnable() { | |
String line; | |
@Override | |
public void run() { | |
while (!mIsServiceDestroyed) { | |
try { | |
Log.d(TAG, "Reading from client"); | |
socketIn = new BufferedReader(new InputStreamReader(mClient.getInputStream())); | |
while ((line = socketIn.readLine()) != null) { | |
//Do something with line | |
Log.d(TAG, "Message from client: " + line); | |
Message msg = mUiHandler.obtainMessage(); | |
msg.what = SEND_FROM_CLIENT; | |
msg.obj = line; | |
mUiHandler.sendMessage(msg); | |
} | |
socketIn.close(); | |
Log.e(TAG, "OUT OF WHILE"); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
break; | |
} | |
} | |
closeClientConnection(); | |
} | |
}; | |
private void closeClientConnection() { | |
Log.d(TAG, "Closing client connection"); | |
if (mClient != null) { | |
try { | |
socketOut.close(); | |
mClient.close(); | |
} catch (IOException e) { | |
Log.e(TAG, "closing client connection failed : " + e.getMessage()); | |
} | |
} | |
} | |
void closeServer() { | |
Log.d(TAG, "Closing server"); | |
if (mServer != null) { | |
try { | |
mServer.close(); | |
closeClientConnection(); | |
} catch (IOException e) { | |
Log.e(TAG, "Close server failed : " + e.getMessage()); | |
} | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
/** | |
* Created by JianGuo on 11/9/16. | |
*/ | |
public class CommandExecutor { | |
public CommandExecutor() { | |
} | |
public static String execute(String command) { | |
System.err.println("Execute : " + command); | |
StringBuilder sb = new StringBuilder(); | |
String[] commands = new String[]{"/bin/sh","-c", command}; | |
try { | |
Process proc = new ProcessBuilder(commands).start(); | |
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); | |
BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream())); | |
String s = null; | |
while ((s = stdInput.readLine()) != null) | |
{ | |
sb.append(s); | |
sb.append("\n"); | |
} | |
while ((s = stdError.readLine()) != null) | |
{ | |
sb.append(s); | |
sb.append("\n"); | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return sb.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment