標籤:
由於本人學習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]聯絡我,非常感謝。
Android筆記之adb命令應用執行個體1(手機端與PC端socket通訊下)