Android设备和PC端通过USB线通信

Android设备和PC端通过USB线通信_第1张图片

一、原理

通过 adb forward来实现,adb forward tcp:7777 tcp:8888。将本机7777端口收到的数据,转发到android设备的8888端口上。

二、实现步骤

1、在android设备上建立一个端口为8888的SocketServer,并打开server到监听状态,即serverSocket.accept()。
2、监听PC上的7777端口,即执行adb forward tcp:7777 tcp:8888。
3、在PC上开启端口为7777的socket客户端
4、socket建立成功后,通过输入输出流来进行通信

三、代码实现

1、android端

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

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

/**
 * @author lixm
 *
 * 这里没有处理多客户端连接,可以开子线程,处理每一个socket
 */
public class MainActivity extends AppCompatActivity {

    ServerThread serverThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        serverThread = new ServerThread();
        serverThread.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        serverThread.setIsLoop(false);
    }

    /**
     * socket线程
     */
    class ServerThread extends Thread {
        private static final String TAG = "lixm";
        DataInputStream inputStream = null;
        DataOutputStream outputStream = null;

        boolean isLoop = true;
        private Socket socket = null;
        private boolean isStartSend = false;

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

        @Override
        public void run() {
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(8888);
                socket = serverSocket.accept(); // 这里开始阻塞,如果有人连上,则开始发送信息
                inputStream = new DataInputStream(socket.getInputStream());
                outputStream = new DataOutputStream(socket.getOutputStream());
                receiveData();
            } catch (Exception e) {
                e.printStackTrace();
                Log.d(TAG, "Exception ",e);
            } finally {
                if (serverSocket != null) {
                    try {
                        serverSocket.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        /**
         * 接收PC端过来的数据
         */
        private void receiveData(){
            new Thread(){                 // 接收数据的线程
                public void run(){
                    byte[] buffer = new byte[1024];
                    while (isLoop){
                        if(inputStream != null){
                            try {
                                Log.d("lixm","here will blocking");
                                int len = inputStream.read(buffer);
                                String receiveData = new String(buffer,0,len,"UTF-8");
                                Log.d("lixm","Server,receiveData = " + receiveData);
                                if(!TextUtils.isEmpty(receiveData) && receiveData.toLowerCase().equals("start")){
                                    isStartSend = true;
                                    sendData2Pc();
                                }else if(!TextUtils.isEmpty(receiveData) && receiveData.toLowerCase().equals("stop")){
                                    isStartSend = false;
                                    isLoop = false;
                                    socket.close();
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            Toast.makeText(MainActivity.this,"服务端关闭",Toast.LENGTH_SHORT).show();
                                        }
                                    });
                                }
                            } catch (IOException e) {
                                Log.d("lixm","IOException : ",e);
                            }
                        }
                    }
                }
            }.start();
        }

        private void sendData2Pc(){  // 发送数据的线程
            new Thread(){
                public void run(){
                    int times = 1;
                    while(isStartSend){
                        String echo = "  send data: " + times + ", 这里是android端发出的信息。";
                        try {
                            outputStream.write(echo.getBytes("UTF-8"));
                            outputStream.flush();
                            Log.d(TAG, echo);
                            times ++;
                            Thread.sleep(1000);
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
    }
}

2、pc端代码


/**

* @author 作者:lixm

* @createDate 创建时间:2019年7月12日

*/

public class DeviceManager {
	
	private static DeviceManager deviceManager = null;
	
	/**
	 * 和android设备之间的连接
	 */
	private Socket mSocket;
	
	/**
	 * 输入流,接收来自android设备的数据
	 */
	private DataInputStream inputStream;
	
	/**
	 * 输出流,向android设备发出数据
	 */
	private DataOutputStream outputStream;
	
	/**
	 * 接收数据的线程
	 */
	private ReceiveMsgThread receiveMsgThread = null;
	
	/**
	 * 发送数据的线程
	 */
	private SendMsgThread sendMsgThread = null;
	
	/**
	 * 用于接收android端返回的数据
	 */
	private IDataCallbackListener dataCallbackListener;
	
	private DeviceManager() {}
	
	public static DeviceManager getInstance() {
		if(deviceManager == null) {
			synchronized (DeviceManager.class) {
				if(deviceManager == null) {
					deviceManager = new DeviceManager();
				}
			}
		}
		return deviceManager;
	}


	public IDataCallbackListener getDataCallbackListener() {
		return dataCallbackListener;
	}

	public void setDataCallbackListener(IDataCallbackListener dataCallbackListener) {
		this.dataCallbackListener = dataCallbackListener;
	}
	

	public void init() {
		stopSendThread();
		stopReceiveThread();
		releaseSocket();
	}

	/**
	 * 初始化本地设备 
	 * @param localPort    本地socket端口
	 * @param androidPort  android设备端socketserver端口
	 * @return true 成功 ,false 失败
	 */
	public boolean initLoaclSocket(int localPort,int androidPort) {
		boolean isOk = false;
		try {
			Runtime.getRuntime().exec("adb forward tcp:" + localPort + " tcp:" + androidPort);
			isOk = true;
		} catch (IOException e) {
			e.printStackTrace();
			isOk = false;
		}
		if(isOk) {
			isOk = connectAndroidDevice(localPort);
		}
		return isOk;		
	}

	/**
	 * 连接Android设备 , adb forward ,端口转发
	 */
	private boolean connectAndroidDevice(int port) {
		boolean isOk = false;
		String ip;
		try {
			ip = InetAddress.getLocalHost().getHostAddress();
			System.out.println("ip = " + ip + ", port = " + port);
			ip = "127.0.0.1";
			mSocket = new Socket(ip,port);
			inputStream = new DataInputStream(mSocket.getInputStream());
			outputStream = new DataOutputStream(mSocket.getOutputStream());
			isOk = true;
		} catch (UnknownHostException e) {
			e.printStackTrace();
			isOk = false;
		}  catch (IOException e) {
			e.printStackTrace();
			isOk = false;
		}
		return isOk;
	}
	
	/**
	 * 通过输入流接收android设备传来的数据
	 */
	public void receiveData() {
		if(receiveMsgThread == null) {
			receiveMsgThread = new ReceiveMsgThread(inputStream);
			receiveMsgThread.setMsgReceive(true);
			receiveMsgThread.setDataCallbackListener(new IDataCallbackListener() {
				@Override
				public void onDataReceived(String data) {
					if(dataCallbackListener != null) {
						dataCallbackListener.onDataReceived(data);
					}
				}
			});
		}
		receiveMsgThread.start();
	}

	/**
	 * 发送数据
	 * @param msg
	 */
	public void sendData(String msg) {
		if(sendMsgThread == null) {
			sendMsgThread = new SendMsgThread(outputStream);
			sendMsgThread.start();
		}
		sendMsgThread.sendMsg(msg);
	}

	/**
	 * 停止接收数据的线程
	 */
	public void stopReceiveThread() {
		if(receiveMsgThread != null) {
			receiveMsgThread.release();
			receiveMsgThread = null;
		}
	}
	
	/**
	 * 停止发送数据的线程
	 */
	public void stopSendThread() {
		if(sendMsgThread != null) {
			sendMsgThread.release();
			sendMsgThread = null;
		}
		try {
			if(mSocket != null) {
				mSocket.close();
				mSocket = null;
			}			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void releaseSocket() {
		try {
			if(inputStream != null) {
				inputStream.close();
				inputStream = null;
			}
			if(outputStream != null) {
				outputStream.close();
				outputStream = null;
			}
			if(mSocket != null) {
				mSocket.close();
				mSocket = null;
			}
			
		}catch(IOException e) {
			System.out.println("releaseSocket(),IOException :" + e.getMessage());
		}
		
	}
}

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class UI extends JFrame implements ActionListener
{

	JPanel jpannelConnect = null;
	JPanel jpannelReceiverTitle = null;
	JPanel jpannelStop = null;
	JPanel jpannelReceiverContent = null;  // 用于显示收到的内容

     //定义组件
	JButton jBtnConnect = null;  // 连接android设备
	JButton jBtnReceiveData = null;  // 接收数据
	
	JButton jBtnStopReceive = null;  // 停止接收数据

	JLabel  jLbConnectState;  // 连接状态的显示
	JLabel  jLbReceiveState;  // 数据接收状态的显示
	
	JTextArea jTxtReceiveContent = null;  //接收数据内容的显示 
	

	public static void main(String[] args) {
	}
	
    //构造函数
	public UI() 
	{
		
		jpannelConnect = new JPanel();
		jpannelReceiverTitle = new JPanel();
		jpannelReceiverContent = new JPanel();
		jpannelStop = new JPanel();

		//创建组件
		jBtnConnect = new JButton("建立连接");
		jBtnReceiveData = new JButton("接收数据");
		jBtnStopReceive = new JButton("停止接收数据");
		
		jLbConnectState = new JLabel("未连接");
		jLbReceiveState = new JLabel("未接收");		
		jTxtReceiveContent = new JTextArea(10,20);
		
		jTxtReceiveContent.setText("这里显示接收到的信息");
		
		jpannelConnect.add(jBtnConnect,LEFT_ALIGNMENT);
		jpannelConnect.add(jLbConnectState,LEFT_ALIGNMENT);
		jpannelStop.add(jBtnStopReceive);
		
		jpannelReceiverTitle.add(jBtnReceiveData);
		jpannelReceiverTitle.add(jLbReceiveState);
		jpannelReceiverContent.add(jTxtReceiveContent);
		
		this.add(jpannelConnect);
		this.add(jpannelReceiverTitle);
		this.add(jpannelReceiverContent);
		this.add(jpannelStop);
		
		initListener();
		
		//设置布局管理器
		this.setLayout(new GridLayout(3,3,50,50));
		this.setTitle("PC端和Android端的通信小工具");
		this.setSize(500,400);
		this.setLocation(300, 300);		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);

	}
	
	private IDataCallbackListener dataCallbackListener = new IDataCallbackListener() {
		
		@Override
		public void onDataReceived(String data) {
			if(jTxtReceiveContent != null && data != null && data.length() > 0) {
				jTxtReceiveContent.setText(data);
			}
		}
	};
	
	private void initListener() {
		jBtnConnect.addActionListener(this);		
		jBtnReceiveData.addActionListener(this);
		jBtnStopReceive.addActionListener(this);		
	}
	
	@Override
	public void actionPerformed(ActionEvent event) {
		String command = event.getActionCommand();
		if(command.equals("建立连接")) {
			DeviceManager.getInstance().init();
			boolean isOk = DeviceManager.getInstance().initLoaclSocket(7777, 8888);
			if(isOk) {
				jLbConnectState.setText("已连接");
			}
		}else if(command.equals("接收数据")) {
			DeviceManager.getInstance().setDataCallbackListener(dataCallbackListener);
			DeviceManager.getInstance().receiveData();
			DeviceManager.getInstance().sendData("start"); // 通知服务端开始发送数据
			jLbReceiveState.setText("数据接收中...");
		}else if(command.endsWith("停止接收数据")) {
			DeviceManager.getInstance().sendData("stop"); // 通知服务端停止发送数据
			DeviceManager.getInstance().stopReceiveThread();			
			jLbReceiveState.setText("数据接收停止");
		}		
	}
}

源码下载地址:
https://download.csdn.net/download/dami_lixm/11342681

你可能感兴趣的:(网络)