由于本人学习Android也挺长时间了,一直把日记记在evernote里面,由于刚离职比较空闲就打算把evernote里的日志一遍遍整理出来发布到网上分享。
本篇将分别使用C#和java语言,来实现和android端通讯的PC客户端代码。
通过adb和Android通讯需要引用adb相关的组件到项目中,分别为:adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll。
可以在XXX\sdk\platform-tools目录下找到
首先看C#语言的实现:
界面效果如下:
namespace AndUsbClient { public partial class Form1 : Form { public const int WaitMs = 2000; public const int TimeOut = 5000; private readonly TcpClient _tcpClient = new TcpClient(); private Boolean _flag = true; private Thread _thread; public Form1() { InitializeComponent(); btnConnect.Click += btnConnect_Click; FormClosed += new FormClosedEventHandler(Form1_FormClosed); btnSend.Click += btnSend_Click; btnClear.Click += btnClear_Click; } private void btnSend_Click(object sender, EventArgs e) { if (_tcpClient.Connected) { var writer = new BinaryWriter(_tcpClient.GetStream()); String content = rtxtContent.Text; try { byte[] bytes = new UTF8Encoding(false).GetBytes(content); writer.Write(Int32ToByteArray(bytes.Length)); writer.Write(bytes); writer.Flush(); SetResult(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " PC: " + content); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } private void btnClear_Click(object sender, EventArgs e) { txtResult.Text = ""; } private void btnConnect_Click(object sender, EventArgs e) { try { btnConnect.Enabled = false; if (_thread != null && _thread.IsAlive) { _thread.Abort(); _thread = null; } _thread = new Thread(() => { OutMsg(@"开始连接Android手机..."); DoConnect(); }); _thread.Start(); } catch (Exception ex) { Console.WriteLine(ex.Message); } btnConnect.Enabled = true; } private void OutMsg(String msg) { AsyncAction(() => { lblInfo.Text = msg; }); } private void SetResult(String msg) { AsyncAction(() => { txtResult.Text += @"\r\n" + msg; }); } public void AsyncAction(Action action) { if (InvokeRequired) { Invoke(new Action<Action>(AsyncAction), action); return; } action(); } //连接 public void DoConnect() { try { ExecuteCmd("kill-server", 0); ExecuteCmd("devices", 0); string strCmd = "shell am broadcast -a NotifyServiceStop"; //利用adb shell am broadcast命令发送广播 ExecuteCmd(strCmd, 0); strCmd = "forward tcp:13333 tcp:10101"; //利用adb命令转发端口 ExecuteCmd(strCmd, 0); strCmd = "shell am broadcast -a NotifyServiceStart"; ExecuteCmd(strCmd, 0); IPAddress ipaddress = IPAddress.Parse("127.0.0.1"); _tcpClient.Connect(ipaddress, 13333); OutMsg("连接成功!"); NetworkStream networkkStream = _tcpClient.GetStream(); networkkStream.ReadTimeout = TimeOut; networkkStream.WriteTimeout = TimeOut; //var reader = new BinaryReader(networkkStream); var tempbuffer = new byte[4]; IAsyncResult result = networkkStream.BeginRead(tempbuffer, 0, tempbuffer.Length, null, tempbuffer); _flag = true; while (_flag) { if (result.IsCompleted && _tcpClient.Connected) { tempbuffer = (byte[])result.AsyncState; int length = ByteArrayToInt32(tempbuffer); var buffer = new byte[length]; int size = networkkStream.Read(buffer, 0, length); if (size > 0) { SetResult(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Android: " + Encoding.UTF8.GetString(buffer, 0, size)); } result = networkkStream.BeginRead(tempbuffer, 0, tempbuffer.Length, null, tempbuffer); } Thread.Sleep(200); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } private static byte[] Int32ToByteArray(Int32 m) { var arry = new byte[4]; arry[0] = (byte)(m & 0xFF); arry[1] = (byte)((m & 0xFF00) >> 8); arry[2] = (byte)((m & 0xFF0000) >> 16); arry[3] = (byte)((m >> 24) & 0xFF); return arry; } private static int ByteArrayToInt32(byte[] bytes) { return BitConverter.ToInt32(bytes, 0); } private String ExecuteCmd(string command, int seconds) { string output = ""; //输出字符串 if (!String.IsNullOrEmpty(command)) { Console.WriteLine(command); var process = new Process(); //创建进程对象 var startInfo = new ProcessStartInfo(); startInfo.WorkingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); startInfo.FileName = "adb.exe"; //设定需要执行的命令 startInfo.Verb = "runas"; startInfo.Arguments = command; //“/C”表示执行完命令后马上退出 startInfo.UseShellExecute = false; //不使用系统外壳程序启动 startInfo.RedirectStandardInput = false; //不重定向输入 startInfo.RedirectStandardOutput = true; //重定向输出 startInfo.CreateNoWindow = true; //不创建窗口 process.StartInfo = startInfo; Console.WriteLine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); try { if (process.Start()) //开始进程 { if (seconds == 0) { process.WaitForExit(); //这里无限等待进程结束 } else { process.WaitForExit(seconds); //等待进程结束,等待时间为指定的毫秒 } output = process.StandardOutput.ReadToEnd(); //读取进程的输出 Console.WriteLine(output); } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { process.Close(); } } return output; } public string Obj2Json<T>(T data) { try { var json = new DataContractJsonSerializer(data.GetType()); using (var ms = new MemoryStream()) { json.WriteObject(ms, data); return Encoding.UTF8.GetString(ms.ToArray()); } } catch (Exception ex) { throw ex; } } public object Json2Obj(string strJson, Type t) { try { var json = new DataContractJsonSerializer(t); using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(strJson))) { return json.ReadObject(ms); } } catch (Exception ex) { throw ex; } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { _flag = false; if (_tcpClient != null) { try { if (_tcpClient.Connected) { NetworkStream stream = _tcpClient.GetStream(); var writer = new BinaryWriter(stream); byte[] bytes = new UTF8Encoding(false).GetBytes("EXIT"); writer.Write(Int32ToByteArray(bytes.Length)); writer.Write(bytes); writer.Flush(); stream.Close(); stream.Dispose(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { _tcpClient.Close(); } } } } }
未完待续。。
作者:sufish
出处:http://www.cnblogs.com/dotnetframework/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以邮件:[email protected]联系我,非常感谢。