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.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

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 异常,pc或者手机端任意一端执行都可以
            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());
            OutputStream writer = socket.getOutputStream();
            //writer.write("WXU138|0|1.0.0|{\"action\":\"pay_success\",\"cardid\":\"1245444\",\"userid\":\"haideyin\",\"total\":1,\"order_time\":126548951}|01a09092c13a58dd288f0e9bd7b641d7\r\n".getBytes());
            writer.write("WXU69|12|1.0.0|{\"action\":\"pay\",\"total\":1}|cc3d4f642efb68525ea4a7d21ff5ad7e\r\n".getBytes());
            //writer.write("WXU65|18|1.0.0|{\"action\":\"heartbeat\"}|153e2de52b54c5138f75112217138d47\r\n".getBytes());
            //writer.write("WXU62|19|1.0.0|{\"action\":\"cancel\"}|767f0c839210383786b371bd10094ea3\r\n".getBytes());
            //writer.write("WXC83|1|{\"action\":\"cancel\",\"errmsg\":\"哈哈哈哈\",\"errcode\":0}|2dc2f47c203b1a62d02031de9f5211ac\r\n".getBytes());
            writer.flush();
            //给手机端发送数据
            //dos.writeUTF("我是来自pc端的数据");
            //拿到socket的输入流,也就是手机端发来的数据流
            InputStream inputStream = socket.getInputStream();
            while (true) {
     
            	final int MLEN = 1024;
                byte[] buff = new byte[MLEN];
                int size = inputStream.read(buff); 
                //读取来自手机端的数据
                if (size >= 0) {
      // 包超缓冲
                    String data = new String(buff, StandardCharsets.UTF_8);
                    System.out.println("收到来自手机端的数据:"+ data);
                }
            }
            
            //dos.writeUTF("我是来自pc端的数据222");
            //最后关闭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即可实现双向通信。

你可能感兴趣的:(商业方案,adb,android,socket,USB双向通信,pc和手机双向通信)