Android設備和PC設備有線USB連接雙向通信預研報告

預研目標

Android設備和PC設備在有線USB連接情況下能否雙向通信,如何實現?

測試代碼

PC端代碼實現

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class Test {
	public static void main(String[] args) {
        try {
        	//adb 的路徑
        	String adbHome = "/Users/yinhaide/Library/Android/sdk/platform-tools/adb ";
        	//adb查看版本號
            String versionCmd = adbHome + "--version";
            //pc和手機的端口轉發命令,可參考:https://blog.csdn.net/u013553529/article/details/80036227
            //不執行轉發的話會出現:Connection refused 異常
            String forwardCmd = adbHome + "forward tcp:8004 tcp:8004";
            //pc和手機的端口轉發,兩邊端口號可一樣也可以不一樣,自行定義,不執行的話兩邊無法通信
            exec(forwardCmd);
            //測試讀取adb版本號
            System.out.println("versionCmd: " + exec(versionCmd));
            //連接adb服務器,本地ip,也就是通過有線方式,需要手機端先開啓服務器監聽來自pc的socket連接
            Socket socket = new Socket("127.0.0.1", 8004);
            //socket的輸出流,用來給手機端寫數據
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            //給手機端發送數據
            dos.writeUTF("我是來自pc端的數據");
            //拿到socket的輸入流,也就是手機端發來的數據流
            DataInputStream inputStream = new DataInputStream(socket.getInputStream());
            //讀取來自手機端的數據
            String msg = inputStream.readUTF();
            System.out.println("收到來自手機端發來的數據: " + msg);
            //最後關閉socket
            socket.close();
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
    }
	
	/**
	 * 執行adb指令
	 * @param cmd adb指令
	 * @return 返回執行結果的字符串
	 */
	public static String exec(String cmd){
        Process process;
        try {
            process=Runtime.getRuntime().exec(cmd);
            return InputStream2String(process.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
	}
	
	/**
	 * adb指令的InputStream轉成字符串輸出
	 * @param inputStream adb指令inputStream
	 * @return 返回執行結果的字符串
	 */
	public static String InputStream2String(InputStream inputStream){
        String result="";
        BufferedReader br=new BufferedReader(new InputStreamReader(inputStream));
        try {
            String temp="";
            while ((temp=br.readLine())!=null){
                result+=temp+"\n";
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
}
  • Android端代碼實現
package com.example.myapplication;

import android.util.Log;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

class AndroidServer extends Thread {

    @Override
    public void run() {
        //如果出現端口占用  請參考解決方案:https://www.cnblogs.com/mantti/p/5262902.html
        ServerSocket serverSocket = null;
        try {
            //建立socket服務器,監聽手機8004端口,這的端口與pc端的端口不屬於同個端口,需要adb forward指令去關聯轉換才能通信
            serverSocket = new ServerSocket(8004);
            while (true) {
                //接受客戶端連接
                Socket socket = serverSocket.accept();
                //讀取連接的輸入流,也就是pc端發來的數據
                DataInputStream inputStream = new DataInputStream(socket.getInputStream());
                //拿到pc端發來的數據
                String msg = inputStream.readUTF();
                Log.d("AndroidServer", "收到來自pc端的數據: " + msg);
                //拿到socket的輸出流,給pc端寫數據
                DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
                //給pc端寫數據
                outputStream.writeUTF("我是來自手機端的數據");
                //關閉單次連接的socket
                socket.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

測試步驟

測試前提是pc端已經安裝好adb驅動,正常情況下要跟手機設備通信都是需要adb驅動的

  • 1、Android端啓動socket服務,監聽8004端口
new AndroidServer().start();
  • 2、pc端執行adb端口轉發指令
adb forward tcp:8004 tcp:8004
  • 3、pc端發起socket連接本地服務器的8004端口
Socket socket = new Socket("127.0.0.1", 8004);
  • 4、雙方進行數據傳輸
//讀取數據
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
String msg = inputStream.readUTF();
//寫入數據
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
outputStream.writeUTF("我是來自手機端的數據");

測試結果

  • pc代碼執行結果
versionCmd: Android Debug Bridge version 1.0.41
Version 30.0.2-6538114
Installed as /Users/yinhaide/Library/Android/sdk/platform-tools/adb

收到來自手機端發來的數據: 我是來自手機端的數據
  • 手機代碼執行結果
2020-06-20 14:14:41.755 6923-6973/com.example.myapplication D/AndroidServer: 收到來自pc端的數據: 我是來自pc端的數據

測試結論

方案可行,在有線連接下藉助adb驅動和socket即可實現雙向通信。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章