一、关于android端和usb的通信问题
原本对usb通信相关并不是很了解,但是涉及到了usb传输数据和pc交互,于是就开始了解起来,开始查阅了很多资料,同时也问了相关的朋友,感觉都很少有涉及到的,这里来做一个简单的总结,android和pc短通过usb通信这里主要是依赖于socket通信,大概的思路如下:
- 第一步,Android端注册一个开启和关闭Android端服务的广播,用于监听pc端要求开启或关闭服务;
- 第二步,Android端开启子线程用于监听pc端传输过来的数据,并且根据数据判断做出相应的操作;
- 第三步,在pc端设置adb 指令开启Android端的服务,并且建立连接 后可以传输数据;
二、代码具体实现
第一步,注册一个开启和关闭Android端服务的广播,然后开启或关闭服务;
/**
* Created by shq on 2017/5/17.
* 监听pc端发送的adb命令开启android端服务
*/
public class ServiceBroadcastReceiver extends BroadcastReceiver {
private static String START_ACTION = "NotifyServiceStart";
private static String STOP_ACTION = "NotifyServiceStop";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (START_ACTION.equalsIgnoreCase(action)){
context.startService(new Intent(context,androidService.class));
Log.e(androidService.TAG,Thread.currentThread().getName()+"------>"
+ "onReceive start");
}else if (STOP_ACTION.equalsIgnoreCase(action)){
context.stopService(new Intent(context,androidService.class));
Log.e(androidService.TAG,Thread.currentThread().getName()+"------>"
+ "onReceive stop");
}
}
}
第二步、开启一个服务来监听数据的通信
/**
* Created by shq on 2017/5/17.
* 这里是监听pc端传输数据的端口
*/
public class androidService extends Service {
public static final String TAG = "shq";
public static Boolean mainThreadFlag = true;
public static Boolean ioThreadFlag = true;
ServerSocket serverSocket = null;
final int SERVER_PORT = 10086;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG,"androidService--onCreate()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG,"androidService--onStartCommand()");
mainThreadFlag = true;
new Thread(){
@Override
public void run() {
doListen();
}
}.start();
return START_NOT_STICKY;
}
/**
* 开启子线程监听端口
*/
private void doListen() {
serverSocket = null;
try {
serverSocket = new ServerSocket(SERVER_PORT);
Log.e(TAG,"doListen()");
while (mainThreadFlag){
Socket socket = serverSocket.accept();
Log.e(TAG,"doListen()mainThread");
new Thread(new ThreadReadWriterIOSocket(this, socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
//关闭线程
mainThreadFlag = false;
ioThreadFlag = false;
Log.e(TAG, Thread.currentThread().getName() + "--"
+ "serverSocket.close()");
//关闭服务
if (serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.e(TAG, Thread.currentThread().getName() + "--onDestroy()");
}
}
第三步,新建一个子线程监听pc端传输过来的数据
/**
* Created by shq on 2017/5/17.
*/
public class ThreadReadWriterIOSocket implements Runnable{
private Socket client;
private Context context;
public ThreadReadWriterIOSocket(Context context, Socket client) {
this.client = client;
this.context = context;
}
@Override
public void run() {
Log.e(androidService.TAG, "a client has connected to server!");
BufferedOutputStream out;
BufferedInputStream in;
/*pc端发来的数据msg*/
String currCMD = "";
try {
out = new BufferedOutputStream(client.getOutputStream());
in = new BufferedInputStream(client.getInputStream());
androidService.ioThreadFlag = true;
while (androidService.ioThreadFlag){
if (!client.isConnected()){
break;
}
/*接收pc端发来的数据*/
Log.e(androidService.TAG, Thread.currentThread().getName()
+ "--is readingData......");
/*读取的操作*/
currCMD = readCMDFromSocket(in);
Log.e(androidService.TAG, Thread.currentThread().getName()
+ "---->" + "**currCMD ==== " + currCMD);
/*根据cmd命令处理数据*/
if (currCMD.equals("1")||currCMD.equals("2")
||currCMD.equals("3")||) {
out.write("OK".getBytes());
out.flush();
}else if (currCMD.equals("4")){
/**
* 这里将json对象传输到pc端
*/
Map<String, String> map = new HashMap<String, String>();
map.put("name","android");
map.put("img","to");
map.put("op","pc");
//将json转化为String类型
JSONObject json = new JSONObject(map);
String jsonString = "";
jsonString = json.toString();
//将String转化为byte[]
byte[] jsonByte = jsonString.getBytes();
out.write(jsonByte);
out.flush();
}else if (currCMD.equalsIgnoreCase("exit")){
out.write("exit ok".getBytes());
out.flush();
}
}
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (client != null) {
Log.e(androidService.TAG, Thread.currentThread().getName()
+ "--client.close()");
client.close();
}
} catch (IOException e) {
Log.e(androidService.TAG, Thread.currentThread().getName()
+ "--read write error");
e.printStackTrace();
}
}
}
/**
* 读取命令
* @param in
* @return
*/
private String readCMDFromSocket(BufferedInputStream 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");
tempbuffer = null;
Log.e(androidService.TAG, Thread.currentThread().getName()
+ "--readFromSocket error");
} catch (IOException e) {
Log.e(androidService.TAG, Thread.currentThread().getName()
+ "--readFromSocket error");
e.printStackTrace();
}
return msg;
}
}
第四步、pc端的数据传输及adb命令
/**
* 测试usb与pc通信 通过adb端口转发方式
*/
public class testPcClient {
public static void main(String[] args) throws InterruptedIOException {
try {
// adb 指令
Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086"); // 端口转换
Thread.sleep(3000);
Runtime.getRuntime().exec("adb shell am broadcast -a NotifyServiceStart");
} catch (Exception e) {
e.printStackTrace();
}
Socket socket = null;
try {
InetAddress serveraddr = null;
serveraddr = InetAddress.getByName("127.0.0.1");
System.out.println("TCP1" + "C: Connecting...");
socket = new Socket(serveraddr, 12580);
System.out.println("TCP2" + "C: Receive");
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
boolean flag = true;
while (flag) {
System.out.print("输入数0进行文件传输,退出输入-1\n");
String strWord = br.readLine();// 从控制台输入
if(strWord.equals("0")){
/* 准备接收文件数据 */
out.write("4".getBytes());
out.flush();
Thread.sleep(300);//等待服务端回复
String strFormsocket = readFromSocket(in);
System.out.println("安卓传来的数据" + strFormsocket);
}else if(strWord.equalsIgnoreCase("EXIT")){
out.write("EXIT".getBytes());
out.flush();
System.out.println("EXIT!");
String strFormsocket = readFromSocket(in);
System.out.println("the data sent by server is:/r/n" +strFormsocket);
flag = false;
}
}
} catch (UnknownHostException e1) {
System.out.println("TCP3" + "ERROR:" + e1.toString());
} catch (Exception e2) {
System.out.println("TCP4" + "ERROR:" + e2.toString());
}finally{
try {
if (socket != null) {
socket.close();
System.out.println("socket.close()");
}
} catch (IOException e) {
System.out.println("TCP5" + "ERROR:" + e.toString());
}
}
}
/* 从InputStream流中读数据 */
public static String readFromSocket(InputStream in) {
int MAX_BUFFER_BYTES = 4000;
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");
tempbuffer = null;
} catch (Exception e) {
e.printStackTrace();
}
return msg;
}