Androidデバむスからコンピュヌタヌを制埡したす

開始する



それはすべお、将軍が私に電話をかけお、「電話が芋えたすか そこにボタンが必芁で、それをクリックするず、ラップトップで映画がオンになりたす。 別のボタンを抌すず、音楜が流れたす。」ず圌は倚くのこずを蚀った、芚えおいない。 「タスクは明確ですか」 フォロヌ」なぜ圌にそのようなニヌズがあったのかわかりたせん。 星がその角床に立っおいないか、なんお倢か。 芁するに、あなたはこれらの金持ちを理解しおいたせん...たあ、倧䞈倫。



最初に、圌は適切なプログラムを探しおグヌグルに登りたした、そしお、圌は考えたした-䞀䜓䜕だ 自分で曞きたす。 さらに、このタスクは難しくはないようで、「コヌドの呌び出し」は既に感じられたしたある皮のプロのit-breaking。 そこで、私は自分でWindowsずAndroidを接続するこずにしたした。



圌が尋ねたもの、私は数日でやった。 しかし、ここでは、倚くのコヌド、チェック、䟋倖凊理などをフェンスしたくありたせん。 蚘事はむしろ、基瀎ずしお最小のものを意図しおおり、それに基づいお、より倧きなものを構築するこずが可胜です。 私はオリゞナルのふりをしおはいけたせん。明らかに誰かが䌌たようなものを曞いたので、自分のバヌゞョンを提䟛しおいたす。 䞀般的に、それは興味のあるすべおの人に捧げられおいたす。



䜕がありたすか



そうです。 䞀方では、Android搭茉の携垯電話があり、他方では、プログラムがむンストヌルされたWindowsがあり、これらのプログラムの䞀郚は、携垯電話からコマンドを発行しお実行する必芁がありたす。

電話ずコンピュヌタヌをロヌカルネットワヌク経由で接続したす。ここではオプションはありたせんSMSを送信しないでください。 したがっお、2぀のプログラムを䜜成したす。 1぀はコンピュヌタヌで実行されおいるサヌバヌです。このプログラムのタスクは、ポヌトを開いおリッスンするこずです。 このポヌトに䜕か圹に立぀ものがあれば、蚭定したアクションを実行したす。 2番目のプログラムは、電話で実行されおいるクラむアントです。そのタスクは、ナヌザヌアクションの凊理、サヌバヌぞの接続、および情報の送信です。



゜ケットに぀いお少し



゜ケットのプログラミングのトピックはすでにハックされおいたすが、これは特別なこずではありたせん。 しかし、リンクをたどるのが奜きでない人のために、ただ簡単に蚀えば。



゜ケットは、tcp / ipプロトコルを䜿甚しお2぀のプロセス間の通信を確立できる゜フトりェアむンタヌフェむスです。 ゜ケットは、IPアドレスずポヌトずいう2぀の偎面に関連付けられおいたす。 IPアドレスがネットワヌク䞊のホストコンピュヌタヌのアドレスである堎合、IPプロトコルはそれを䜿甚したす。 ポヌトは、接続の宛先ずなるアプリケヌションの識別子であり、ここではTCPプロトコルが機胜したす。 ポヌトはTCPたたはUDPのいずれかです。この蚘事では、TCPのみを䜿甚したす。 IPアドレスはむンタヌネットずロヌカルネットワヌクの䞡方で䞀意であるため、送信者のアドレスず受信者のアドレスを䞀意に決定したす。 ポヌトはオペレヌティングシステム内で䞀意であり、やり取りするアプリケヌションを定矩したす。 ポヌトは暙準です。たずえば、80をHTTPに割り圓おたり、3389をRDPにしたりできたす。 空いおいるポヌトであればどれでも䜿甚できたすが、暙準のポヌトはそのたたにしおおくのが最善です。 非垞によく、゜ケットに関する䟋ずずもに、 ここに曞かれおいたす 。



サヌバヌ フヌリガンを開始



Aimp、Windows Media Playerなどを起動したす。 電話からでも-面癜くありたせん。この蚘事に基づいお、コヌドを少しやり盎すこずで簡単に実装できたす。 もっず良くしたしょう。 必芁に応じおモニタヌ画面をツむストツむストするか、予期しないメッセヌゞ䞀方向の地獄のメッセンゞャヌを衚瀺したす。最悪の事態はコンピュヌタヌの電源を切るこずです 確かに、このために圌らはフォヌクを眮くこずもできたす。 たあ、最初に捕たえたしょう。



それでは始めたしょう。 Visual Studioで、FunnyJokeなどの名前で新しいWindowsフォヌムアプリケヌションを䜜成したす。 Program.csファむルを開き、Main関数の本䜓内のすべおのコヌドを削陀したす。 このコヌドはアプリケヌションのメむンフォヌムを初期化したす。サヌバヌにはりィンドりは必芁ありたせん。静かに座っおコマンドを埅぀必芁がありたす。



Programクラスで、次の倉数を定矩したす。



//  static int port = 10000; //  static IPAddress ipAddress = IPAddress.Parse("0.0.0.0"); //   const byte codeMsg = 1; //   const byte codeRotate = 2; //   const byte codePoff = 3;
      
      





ポヌト10000を取埗したした。これは、サヌバヌがリッスンするものです。0.0.0.0に蚭定したIPアドレスの代わりに、䜿甚可胜なすべおのネットワヌクむンタヌフェむスが凊理されたす。 これは完党に正しいわけではありたせんが、初心者には圹立ちたす。 次に、クラむアントから送信されるコマンドコヌドを指定する3぀の定数を定矩したした。 プロゞェクトの開始時に、接続するこずを忘れないでください



 using System.Net; using System.Net.Sockets;
      
      





ここで、Main関数のリモヌトコヌドの代わりに、次を挿入したす。



メむン
 static void Main() { //     IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port); //    Socket socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { //      socket.Bind(ipEndPoint); //    "" socket.Listen(1); while (true) { //  .       Socket Socket handler = socket.Accept(); // ,    . byte[] recBytes = new byte[1024]; int nBytes = handler.Receive(recBytes); switch (recBytes[0]) //     { case codeMsg: //  nBytes = handler.Receive(recBytes); //    if (nBytes != 0) { //       String msg = Encoding.UTF8.GetString(recBytes, 0, nBytes); MessageBox.Show(msg, " !"); } break; case codeRotate: //   RotateScreen(); break; case codePoff: //  System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo.FileName = "shutdown.exe"; p.StartInfo.Arguments = "-s -t 00"; p.Start(); socket.Close(); break; } //   handler.Shutdown(SocketShutdown.Both); handler.Close(); } } catch (Exception ex) { } }
      
      







䟋はよくコメントされおいたす。 しかし、それでも説明したす。 たず、ロヌカル゚ンドポむントを䜜成し、それをIPアドレスずポヌトに関連付けたす。 次に、メむン゜ケットを定矩し、゚ンドポむントにバむンドしお、リスニングモヌドにしたす。 その埌、無限ルヌプに入り、次の行から開始したす。



 Socket handler = socket.Accept();
      
      





サヌバヌは接続埅機状態になりたす。 接続に成功するず、Socketの新しいむンスタンスが䜜成され、それを通じおクラむアントず通信したす。 接続が確立された埌、デヌタの読み取りを開始したす。



 int nBytes = handler.Receive(recBytes
      
      





クラむアントコマンドはシングルバむトコヌドプログラムの冒頭で説明で゚ンコヌドされ、サヌバヌはコマンドコヌドを解読しお実行を開始し、その埌スタンバむモヌドに戻りたす。 䟋倖はcodeMsgです 。 その埌、メッセヌゞ文字列を含むバむトのセットが期埅されたす。 したがっお、このコマンドを受信するず、サヌバヌは再び゜ケットからデヌタを読み取りたす。



  nBytes = handler.Receive(recBytes); if (nBytes != 0) { String msg = Encoding.UTF8.GetString(recBytes, 0, nBytes); MessageBox.Show(msg, " !"); }
      
      





クラむアントから到着する行にはUTF-8文字゚ンコヌドが䜿甚されおいるため、䞍幞なナヌザヌに衚瀺する前に、暙準圢匏にする必芁がありたす。



プログラムを単玔化し、䞍芁なダむアログを䜜成しないために、暙準のMessageBoxクラスを䜿甚したしたが、このアプロヌチには1぀の欠点がありたす。 MessageBoxは、アプリケヌション党䜓のフロヌをブロックするモヌダルりィンドりを䜜成したす。 ぀たり、メッセヌゞボックスが開いおいる間、サヌバヌは䜕もしたせん。 もちろんマむナスですが、シンプルさを犠牲にしなければなりたせん。



手順をペむントせずに、画面の向きを倉曎したす。Microsoftがここで掚奚しおいるように、コヌドを完成させたした 。 .NETを䜿甚しお画面を回転させる方法は芋぀かりたせんでした。 これはモバむルプラットフォヌムでは簡単に実行できたすが、通垞のPCでは解決できない問題であるこずが刀明したした。 しかし、叀き良きWINAPIが助けになり、すべおを台無しにしたした。

適切なフラグを付けおshutdownコマンドを呌び出すこずにより、通垞のWindowsツヌルを䜿甚しおコンピュヌタヌの電源をオフにしたす。



サヌバヌがあれば、おそらくそれだけです。 蚘事の最埌にプロゞェクトの゜ヌスコヌドを添付したす。



お客様



EclipseよりもこのIDEが奜きなので、Android Studioでクラむアントを䜜成したす。 埌者の愛奜家は、プロゞェクトをやり盎すこずはそれほど難しくないず思いたす。 デバッグには、Androidの仮想マシンをむンストヌルした状態でVirtualBoxを䜿甚したした。これは、ネむティブ゚ミュレヌタヌが非垞に䜎速であり、それを䜿甚しおデバッグするのに十分な寿呜がないためです。 たあ、定期的に「ラむブ」電話でチェックしたした。 そこで、FunnyJokeずいうプロゞェクトを䜜成し、お䜿いの携垯電話がプルできるAPIの最小バヌゞョン16個ありたすを蚭定し、Empty Activityを遞択したす。 それ以倖はすべおデフォルトです。 プレれンテヌションのマヌクアップを䜜成したす。 矎しいボタンを描いたり、颚氎に眮いたりする必芁のあるデザむンに぀いおは、私はあたり倉質したせんでした。 EditTextタむプの2぀のフィヌルド、制埡されたコンピュヌタヌのIPアドレスを入力するための最初のフィヌルド、メッセヌゞのテキストのための2番目のフィヌルド、およびデスクトップを回転させるボタン。 しかし、シャットダりンボタンは倧きくお恐ろしい赀になりたした。 これは、誀っおクリックしないようにするためです。



activity_main.xml
 <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:weightSum="1" android:layout_marginTop="20dp"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="20dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="IP address:" android:id="@+id/textView" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/edIPaddress" android:digits="0123456789." /> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" > <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/etMsg" android:layout_gravity="center_vertical" android:layout_weight="1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send Msg" android:layout_weight="0" android:id="@+id/btnSMsg" android:layout_gravity="center_vertical" android:onClick="onClick" /> </LinearLayout> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Rotate Screen" android:id="@+id/btnRotate" android:layout_weight="0" android:layout_gravity="center_horizontal" android:layout_marginBottom="20dp" android:layout_marginTop="20dp" android:onClick="onClick" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnPowerOff" android:layout_gravity="center" android:src="@drawable/button_img" android:background="@null" android:onClick="onClick" /> </LinearLayout>
      
      







ここでは、 edIPaddressフィヌルドに泚意を払う䟡倀がありたす。数倀のみを入力するフィルタリングがありたす。 ピリオド、フィヌルドはIPアドレスを入力するためのものです。 これは入力されたデヌタの正確性に関する唯䞀のチェックであり、他のすべおはナヌザヌの良心にずどたるず蚀わなければなりたせん。 たた、 btnPowerOffボタンに぀いおも説明したす。そのセレクタヌは状態を監芖し、抌されおいるかどうかに応じお画像を倉曎したすそうでない堎合、ボタンが抌されたかどうかは䞍明で、ボタンは静的な画像のように芋えたす。 button_img.xmlセレクタコヌドは次のずおりです。



 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/poweroffs"/> <item android:drawable="@drawable/poweroff"/> </selector>
      
      





したがっお、リ゜ヌスには2぀の画像が必芁です。1぀は抌された状態、もう1぀は通垞の状態です。 次の画面が衚瀺されたす。



画像



これをマヌクアップで終了したす。 MainActivity.javaファむルに移動したす。 たず、サヌバヌず同様に、コマンドコヌドずいく぀かの倉数を決定したす。



 String serIpAddress; //   int port = 10000; //  String msg; //  final byte codeMsg = 1; //   final byte codeRotate = 2; //   final byte codePoff = 3; //   byte codeCommand;
      
      





次に、ボタンクリックハンドラヌに移動したす。 ハンドラヌは1぀だけであり、抌された掘り手はその識別子によっお識別されるこずに泚意しおください。 たず、 edIPaddressフィヌルドから行を取埗したす。フィヌルドに入力されおいない堎合は、IPアドレスを入力する必芁があるこずを瀺すメッセヌゞを衚瀺し、それ以倖は䜕もしたせん。



 public void onClick (View v) { //     ip  EditText etIPaddress = (EditText)findViewById(R.id.edIPaddress); serIpAddress = etIPaddress.getText().toString(); //    ,      if (serIpAddress.isEmpty()){ Toast msgToast = Toast.makeText(this, " ip ", Toast.LENGTH_SHORT); msgToast.show(); return; } . . . . }
      
      





Androidでは、メむンスレッドで長時間実行されるプロセスを䜜成するこずはお勧めしたせん。これは、プログラムが「フリヌズ」する可胜性があり、ナヌザヌたたはシステムが応答を埅たずにアプリケヌションを単玔に閉じるこずができるためです。 このような長期にわたるプロセスには、ネットワヌキングが含たれたす。 この堎合、「長い」コヌドを実行する远加のストリヌムを䜜成する必芁がありたす。 Javaには、 スレッドを制埡できる暙準のThreadクラスがありたすが、䜿甚したせん。 Androidには、このために特別に蚭蚈されたAsyncTaskクラスがありたす。 詳现はこちらたたはこちらをご芧ください。

メッセヌゞを送信し、 AsyncTaskを芪にし、メむンコヌドが配眮されるdoInBackgroundメ゜ッドを再定矩するクラスを䜜成したす。



センダスレッド
 class SenderThread extends AsyncTask <Void, Void, Void> { @Override protected Void doInBackground(Void... params) { try { // ip   InetAddress ipAddress = InetAddress.getByName(serIpAddress); //   Socket socket = new Socket(ipAddress, port); //   / OutputStream outputStream = socket.getOutputStream(); DataOutputStream out = new DataOutputStream(outputStream); switch (codeCommand) { //        case codeMsg: //  out.write(codeMsg); //    UTF-8 byte[] outMsg = msg.getBytes("UTF8"); out.write(outMsg); break; case codeRotate: //   out.write(codeRotate); break; case codePoff: //  out.write(codePoff); break; } } catch (Exception ex) { ex.printStackTrace(); } return null; } }
      
      







最初に、IPサヌバヌを含むInetAddressクラスのむンスタンスを䜜成したす。 次に、゜ケットを䜜成し、リモヌトアドレスずポヌトにバむンドし、暙準の入力/出力ストリヌムを芁求したすクラむアントは䜕も受信しないため、出力のみを芁求したす。 そしお最埌に、 codeCommand倉数の倀に応じお、サヌバヌにメッセヌゞを送信したす。



次に、ボタンクリックハンドラに戻り、 SenderThreadクラスのむンスタンスを䜜成し、抌されたボタンに応じおcodeCommand倉数を初期化し、 それからストリヌムを決定したす。 最埌に、 executeメ゜ッドを呌び出しおアクティブ化したす。



 . . . SenderThread sender = new SenderThread(); //      switch (v.getId()) // id  { case R.id.btnSMsg: //   if (!msg.isEmpty()) { codeCommand = codeMsg; sender.execute(); } else { //    ,     Toast msgToast = Toast.makeText(this, " ", Toast.LENGTH_SHORT); msgToast.show(); } break; case R.id.btnRotate: //  codeCommand = codeRotate; sender.execute(); break; case R.id.btnPowerOff: //  codeCommand = codePoff; sender.execute(); break; } }
      
      





アプリケヌションマニフェストを少し修正し、ネットワヌクずWi-Fiを䜿甚する蚱可を䞎えたす。それなしでは䜕も機胜したせん。



 <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
      
      





それだけです 収集しお確認できたす。 結果は次のずおりです。



画像



画像



参照資料






All Articles