仿豌豆荚实现android连接pc方法

本文详细介绍了如何使用ADB建立Android设备与PC之间的Socket连接,包括adb模式设置、端口转发、服务启动与停止、数据传输及文件交换。通过PC端发送命令启动Android服务,实现数据交互,支持文件传输。利用adb forward命令进行端口映射,确保通信成功。
摘要由CSDN通过智能技术生成

需求:

     1.一个android端的service后台运行的程序,作为socket的服务器端;用于接收Pc client端发来的命令,来处理数据后,把结果发给PC client

     2.PC端程序,作为socket的客户端,用于给android手机端发操作命令

 

难点分析:

     1.手机一定要有adb模式,即插上USB线时马上提示的对话框选adb。好多对手机的操作都可以用adb直接作。

        不过,我发现LG GW880就没有,要去下载个

     2.android默认手机端的IP为“127.0.0.1”

     3.要想联通PC与android手机的sokcet,一定要用adb forward 来作下端口转发才能连上socket.

[java]   view plain copy
  1. Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");  
  2.             Thread.sleep(3000);  

       4.android端的service程序Install到手机上容易,但是还要有方法来从PC的client端来启动手机上的service ,这个办法可以通过PC端adb命令来发一个Broastcast ,手机端再写个接收BroastcastReceive来接收这个Broastcast,在这个BroastcastReceive来启动service

     

    pc端命令:

  

[java]   view plain copy
  1. Runtime.getRuntime().exec(  
  2. "adb shell am broadcast -a NotifyServiceStart");  

 android端的代码:ServiceBroadcastReceiver.java

 

 

[java]   view plain copy
  1. package com.otheri.service;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.util.Log;  
  7.   
  8. public class ServiceBroadcastReceiver extends BroadcastReceiver {  
  9.     private static String START_ACTION = "NotifyServiceStart";  
  10.     private static String STOP_ACTION = "NotifyServiceStop";  
  11.   
  12.     @Override  
  13.     public void onReceive(Context context, Intent intent) {  
  14.         Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
  15.                 + "ServiceBroadcastReceiver onReceive");  
  16.   
  17.         String action = intent.getAction();  
  18.         if (START_ACTION.equalsIgnoreCase(action)) {  
  19.             context.startService(new Intent(context, androidService.class));  
  20.   
  21.             Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
  22.                     + "ServiceBroadcastReceiver onReceive start end");  
  23.         } else if (STOP_ACTION.equalsIgnoreCase(action)) {  
  24.             context.stopService(new Intent(context, androidService.class));  
  25.             Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
  26.                     + "ServiceBroadcastReceiver onReceive stop end");  
  27.         }  
  28.     }  
  29.   
  30. }  

 

  5.由于是USB连接,所以socket就可以设计为一但连接就一直联通,即在new socket和开完out,in流后,就用个while(true){}来循环PC端和android端的读和写

    android的代码:

[java]   view plain copy
  1. public void run() {  
  2.         Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"  
  3.                 + "a client has connected to server!");  
  4.         BufferedOutputStream out;  
  5.         BufferedInputStream in;  
  6.         try {  
  7.             /* PC端发来的数据msg */  
  8.             String currCMD = "";  
  9.             out = new BufferedOutputStream(client.getOutputStream());  
  10.             in = new BufferedInputStream(client.getInputStream());  
  11.             // testSocket();// 测试socket方法  
  12.             androidService.ioThreadFlag = true;  
  13.             while (androidService.ioThreadFlag) {  
  14.                 try {  
  15.                     if (!client.isConnected()) {  
  16.                         break;  
  17.                     }  
  18.   
  19.                     /* 接收PC发来的数据 */  
  20.                     Log.v(androidService.TAG, Thread.currentThread().getName()  
  21.                             + "---->" + "will read......");  
  22.                     /* 读操作命令 */  
  23.                     currCMD = readCMDFromSocket(in);  
  24.                     Log.v(androidService.TAG, Thread.currentThread().getName()  
  25.                             + "---->" + "**currCMD ==== " + currCMD);  
  26.   
  27.                     /* 根据命令分别处理数据 */  
  28.                     if (currCMD.equals("1")) {  
  29.                         out.write("OK".getBytes());  
  30.                         out.flush();  
  31.                     } else if (currCMD.equals("2")) {  
  32.                         out.write("OK".getBytes());  
  33.                         out.flush();  
  34.                     } else if (currCMD.equals("3")) {  
  35.                         out.write("OK".getBytes());  
  36.                         out.flush();  
  37.                     } else if (currCMD.equals("4")) {  
  38.                         /* 准备接收文件数据 */  
  39.                         try {  
  40.                             out.write("service receive OK".getBytes());  
  41.                             out.flush();  
  42.                         } catch (IOException e) {  
  43.                             e.printStackTrace();  
  44.                         }  
  45.   
  46.                         /* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */  
  47.                         byte[] filelength = new byte[4];  
  48.                         byte[] fileformat = new byte[4];  
  49.                         byte[] filebytes = null;  
  50.   
  51.                         /* 从socket流中读取完整文件数据 */  
  52.                         filebytes = receiveFileFromSocket(in, out, filelength,  
  53.                                 fileformat);  
  54.   
  55.                         // Log.v(Service139.TAG, "receive data =" + new  
  56.                         // String(filebytes));  
  57.                         try {  
  58.                             /* 生成文件 */  
  59.                             File file = FileHelper.newFile("R0013340.JPG");  
  60.                             FileHelper.writeFile(file, filebytes, 0,  
  61.                                     filebytes.length);  
  62.                         } catch (IOException e) {  
  63.                             e.printStackTrace();  
  64.                         }  
  65.                     } else if (currCMD.equals("exit")) {  
  66.   
  67.                     }  
  68.                 } catch (Exception e) {  
  69.                     // try {   
  70.                     // out.write("error".getBytes("utf-8"));  
  71.                     // out.flush();  
  72.                     // } catch (IOException e1) {   
  73.                     // e1.printStackTrace();  
  74.                     // }  
  75.                     Log.e(androidService.TAG, Thread.currentThread().getName()  
  76.                             + "---->" + "read write error111111");  
  77.                 }  
  78.             }  
  79.             out.close();  
  80.             in.close();  
  81.         } catch (Exception e) {  
  82.             Log.e(androidService.TAG, Thread.currentThread().getName()  
  83.                     + "---->" + "read write error222222");  
  84.             e.printStackTrace();  
  85.         } finally {  
  86.             try {  
  87.                 if (client != null) {  
  88.                     Log.v(androidService.TAG, Thread.currentThread().getName()  
  89.                             + "---->" + "client.close()");  
  90.                     client.close();  
  91.                 }  
  92.             } catch (IOException e) {  
  93.                 Log.e(androidService.TAG, Thread.currentThread().getName()  
  94.                         + "---->" + "read write error333333");  
  95.                 e.printStackTrace();  
  96.             }  
  97.         }  

  6.如果是在PC端和android端的读写操作来while(true){}循环,这样socket流的结尾不好判断,不能用“-1”来判断,因为“-1”是只有在socket关闭时才作为判断结尾。

  7.socket在out.write(bytes);时,要是数据太大时,超过socket的缓存,socket自动分包发送,所以对方就一定要用循环来多次读。最好的办法就是服务器和客户端协议好,比如发文件时,先写过来一个要发送的文件的大小,然后再发送文件;对方用这个大小,来循环读取数据。

   android端接收数据的代码:

[java]   view plain copy
  1. /** 
  2.      * 功能:从socket流中读取完整文件数据 
  3.      *  
  4.      * InputStream in:socket输入流 
  5.      *  
  6.      * byte[] filelength: 流的前4个字节存储要转送的文件的字节数 
  7.      *  
  8.      * byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk) 
  9.      *  
  10.      * */  
  11.     public static byte[] receiveFileFromSocket(InputStream in,  
  12.             OutputStream out, byte[] filelength, byte[] fileformat) {  
  13.         byte[] filebytes = null;// 文件数据  
  14.         try {  
  15.             int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int  
  16.             String strtmp = "read file 
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值