当前位置: 首页 > 工具软件 > pc > 使用案例 >

android app 和PC通过usb(adb)通信(全双工)

段干宾白
2023-12-01

app和PC通信可实现方式

1、app和PC通过socket通信(需要网络)

2、app和PC通过usb通信(不需要网络)

PC之间通过adb控制android手机属于半双工,我们的实现方式是app和PC实现全双工通信。

1、 adb forward 原理概述

如:adb forward tcp:8000 tcp:9000 的意思是,将PC端的 8000 端口收到的数据,转发给手机中的 9000 端口。
但是光执行这个命令还不能转发数据,还需要完成下面两个步骤才能传数据:

(a)在手机端,建立一个端口为9000的 server,并打开 server 到监听状态。
(b)在PC端,建立一个 socket client 端,连接到端口为8000的 server 上。

PC端应用与手机端应用 通信建立过程:
(1)执行 adb forward tcp:8000 tcp:9000
(2)启动手机端应用,建立端口为9000的 server,并处于监听状态(LISTENING)
(3)启动PC端应用,连接端口为8000的 server(adb 创建的)
之后,就可以传输数据了

PC端应用与手机端应用之间传输数据的过程:
(1)PC端应用将数据发送给端口为8000的 server(adb 创建的)
(2)adb 将数据转发给手机端 adbd 进程(通过USB传输)
(3)adbd 进程将数据发送给端口为9000的 server(手机端应用创建的)
传递是双向的,第(1)和第(3)步是通过socket实现的,所以通过 socket 的读和写就完成了PC端和手机端的数据传递。

PC端实现代码

//package com.socket.txt;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class adbSocketCont extends Thread {
        Socket client;
        BufferedOutputStream out;
        BufferedInputStream in;

        public adbSocketCont() {
                try {
                        client = new Socket("127.0.0.1", 8000);
                        out = new BufferedOutputStream(client.getOutputStream());
                        in = new BufferedInputStream(client.getInputStream());
                } catch (UnknownHostException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }
        @Override
        public void run() {
                try {
                         Scanner scanner = new Scanner(System.in);
                            String msg = scanner.next();
                            if (!client.isConnected()) {
                                        return;
                                }
                            out.write(msg.getBytes());
                            out.flush();

                        while (true) {
                                String readMsg = "";
                                if (!client.isConnected()) {
                                        break;
                                }
                                readMsg = readMsgFromSocket(in);
                                System.out.println(readMsg);
                                if (readMsg.length() == 0) {
                                        break;
                                }
                                 readMsg = scanner.next();

                                out.write((readMsg ).getBytes());
                            out.flush();
                        }
                         in.close();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }

        }

        public static String readMsgFromSocket(InputStream in) {

                String msg = "";
                byte[] tempbuffer = new byte[1024];
                try {
                        int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);
                        msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

                } catch (Exception e) {
                        e.printStackTrace();
                }
                return msg;
        }

        public static void main(String args[]) {
                adbSocketCont asc = new adbSocketCont();
                asc.start();
        }
}

app端实现代码

package com.example.modle;

import android.util.Log;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerThread extends Thread {
    private static final String TAG = "ServerThread";

    boolean isLoop = true;

    public void setIsLoop(boolean isLoop) {
        this.isLoop = isLoop;
    }

    @Override
    public void run( ) {
        Log.d("anzi", "running");

        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(9000);

            while (isLoop) {
                final Socket socket = serverSocket.accept();
                new Thread(new SocketReadThread(socket)).start();
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            Log.d("anzi", "destory");

            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public static void sendToast(String msg) throws IOException {
        Socket socket = new Socket("127.0.0.1", 8000);
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeUTF(msg);
        socket.close();
    }

    class SocketReadThread implements Runnable {

        private BufferedInputStream in;
        private BufferedOutputStream outputStream;
        Socket mSocket;

        public SocketReadThread(Socket mSocket) throws IOException {

            this.in = new BufferedInputStream(mSocket.getInputStream());
            outputStream = new BufferedOutputStream(mSocket.getOutputStream());
            this.mSocket = mSocket;
        }

        public void run( ) {
            try {
                String readMsg = "yyyy";
                String currCMD = "";
                while (true) {
                    try {
                        if (!mSocket.isConnected()) {
                            break;
                        }

                        //   读到后台发送的消息  然后去处理
                        currCMD = readMsgFromSocket(in);
                        //    处理读到的消息(主要是身份证信息),然后保存在sp中;
                        if (currCMD.length() == 0) {
                            Log.d(TAG,"length = 0");
                            break;
                        }
                        if (currCMD.equals("0002")) {
                            Log.d(TAG,"0002 0002 0002");
                            outputStream.write((currCMD + "vclusters").getBytes());
                        } else {
                            //  将要返回的数据发送给 pc
                            outputStream.write((currCMD + "flag").getBytes());
                        }
                        outputStream.flush();


                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
            }
        }
    }

    public String readMsgFromSocket(InputStream in) {
        int MAX_BUFFER_BYTES = 2048;
        String msg = "";
        byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];
        try {
            int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);
            msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return msg;
    }
}

代码中只能映射127.0.0.1,需要映射所有ip,参考博客中第四篇:android - adb port forwarding to listen on all interfaces - Stack Overflow

参考博客:

Android -- adb forward实现PC和App的通讯_一只驴在敲代码-CSDN博客_adb forward 原理

Android adb与PC端通信_anqingcheng的博客-CSDN博客_adb通信

Android和C/C++通过原生socket实现通信 - 灰信网(软件开发博客聚合)

android - adb port forwarding to listen on all interfaces - Stack Overflow

 类似资料: