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即可实现双向通信。

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