Anwendung per Handy steuern

    • VB.NET

      Anwendung per Handy steuern

      Hey,

      ein kleines Langeweile-Projekt von mir. Ich dachte, ich teile die kleine Spielerei mit Euch, evtl. mach einer was draus. Los gehts....

      In diesem Tutorial möchte ich erklären, wie man eine .Net-Anwendung vom Android-Handy aus fernsteuern kann. Was braucht man dafür?

      1. Ein aktuelles Android-Handy.
      2. Die App QPython qpython.com/ oder im PlayStore einfach QPython eingeben (QPython 3L).
      3. Handy muss im selben Netzwerk angemeldet sein, wie der PC auf dem die .NET-Anwendung läuft.
      4. Die Newtonsoft.JSON-Library für das VB-Projekt github.com/JamesNK/Newtonsoft.Json/releases (Version 12.0.3), ältere sollten auch ohne Probleme gehen.

      Ist die App installiert, so solltet ihr einen Ordner qpython in Eurem MainStorage vorfinden. Bei mir sieht dies so aus....



      Das nun folgende Python-Script gehört in den Ordner scripts3

      Quellcode

      1. import androidhelper
      2. import time
      3. import socket
      4. import json
      5. #benötigt, um auf die Sensoren zugreifen zu können.
      6. droid = androidhelper.Android()
      7. def com():
      8. #erzeugt eine Standard-Socket-Objekt.
      9. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      10. #Verbindung zum Server.
      11. s.connect(("192.168.178.5", 20005))
      12. #startet die Abfrage der Sensoren.
      13. droid.startSensingTimed(1, 250)
      14. while True:
      15. try:
      16. #sendet die JSON-Daten an den Server.
      17. s.send(readAcc().encode("utf8"))
      18. #empfängt das ok des Servers.
      19. r = s.recv(1024).decode("utf8")
      20. #wartet 0.1 Sekunden bis zur nächsten
      21. #Übertragung
      22. time.sleep(0.1)
      23. except:
      24. #tritt ein Fehler auf, so wird aus dem
      25. #While-Loop ausgebrochen.
      26. break
      27. #beendet die Abfrage der Sensoren.
      28. droid.stopSensing()
      29. #schliesst die Verbindung zum Server endgültig.
      30. s.close()
      31. def readAcc():
      32. #liest die gegenwärtigen Daten des Beschleunigungs-
      33. #Sensors.
      34. result = droid.sensorsReadAccelerometer().result
      35. #gibt die Daten als Json-Objekt zurück.
      36. return json.dumps(result)
      37. #Einstiegspunkt ins Programm.
      38. com()


      Hier die Code-Datei.... accelerometer.txt (Die Endung .txt bitte nach .py abändern. Das Forum erlaubt Dateien mit der Endung .py nicht). Die IP-Adresse müsst ihr natürlich auf die Adresse abändern, auf der dann die VB-Anwendung läuft!!!!

      Dieses Python-Script liest die Werte des Beschleunigsungssensors aus und sendet diese als JSON-String an die .NET Anwendung.... Meine Kenntnisse in Python sind eher beschränkt, der Code könnte bestimmt besser aussehen, aber gut.

      Der .NET-Teil ist eine Windows-Forms-Anwendung (.NET-Framework).

      VB.NET-Quellcode

      1. Imports System.Net
      2. Imports System.Net.Sockets
      3. Imports System.Text
      4. Imports Newtonsoft.Json
      5. Public Class Form1
      6. Private _server As Socket
      7. Private _location As PointF
      8. Public Sub New()
      9. InitializeComponent()
      10. 'Puffer aktivieren, damit die Animation etwas flüssiger läuft.
      11. Me.DoubleBuffered = True
      12. 'Mitte der Form.
      13. _location = New PointF(Me.ClientSize.Width \ 2, Me.ClientSize.Height \ 2)
      14. 'Standard-Socket.
      15. _server = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
      16. 'Bindet den Socket an alle verfügbaren Interfaces auf dem PC, Port ist willkürlich gewählt.
      17. _server.Bind(New IPEndPoint(IPAddress.Any, 20005))
      18. 'Versetzt den Socket in den Listening-Modus. Benötigt, um Verbindungen anzunehmen.
      19. _server.Listen(10)
      20. 'Startet den Thread, der auf Verbindungsanfragen horcht und reagiert.
      21. Task.Run(Sub() Accept())
      22. End Sub
      23. Private Sub Accept()
      24. While True
      25. 'Blockiert solange, bis eine Verbindungsanfrage eingeht, darum ein extra Thread.
      26. Dim client = _server.Accept()
      27. 'Startet abermals einen neuen Thread, der die Nachrichten vom Client verarbeitet.
      28. Task.Run(Sub() HandleCommunication(client))
      29. End While
      30. End Sub
      31. Private Sub HandleCommunication(client As Socket)
      32. 'Ein Byte-Array für die eingehenden Nachrichten. 4kb sollten reichen.
      33. Dim buffer(4096) As Byte
      34. While True
      35. Try
      36. 'Blockiert, bis Daten zu lesen an der Schnittstelle anstehen. Sind Daten vorhanden,
      37. 'so werden diese in das Byte-Array kopiert und die Anzahl der gelesenen Bytes
      38. 'werden in der Variablen r gespeichert.
      39. Dim r = client.Receive(buffer, SocketFlags.None)
      40. 'Gibt die Receive-Funktion 0 zurück, so hat die Gegenstelle die Verbindung geschlossen
      41. 'und die Kommunikation wird beendet.
      42. If r = 0 Then Throw New Exception()
      43. 'Die empfangenen Bytes werden dem Format (utf-8) entsprechend in einen String umgewandelt.
      44. 'GetString beginnt beim Array (buffer) bei 0 und liest die Anzahl der empfangenen Bytes (r)
      45. 'und dekodiert diese.
      46. Dim message = Encoding.UTF8.GetString(buffer, 0, r)
      47. 'Dem Client wird eine Bestätigung gesendet.
      48. client.Send(Encoding.UTF8.GetBytes("ok"), SocketFlags.None)
      49. 'Die empfangene Nachricht wird mit Hilfe der Newtonsoft-Json-Lib in eine Liste von
      50. 'Doubles gecastet. X=0, Y=1, Z=2.
      51. Dim data = JsonConvert.DeserializeObject(Of List(Of Single))(message)
      52. 'Abarbeitung der Daten.
      53. OnUpdate(data)
      54. Catch ex As Exception
      55. 'Tritt ein Fehler auf, so wird die Client geschlossen und der While-Loop beendet.
      56. client.Close()
      57. Exit While
      58. End Try
      59. End While
      60. End Sub
      61. Private Sub OnUpdate(data As List(Of Single))
      62. 'X-Wert ist das erste Element im Array.
      63. _location.X -= data(0)
      64. 'Y-Wert ist das zweite Element im Array.
      65. _location.Y += data(1)
      66. 'Form neu zeichnen.
      67. Me.Invalidate()
      68. End Sub
      69. Protected Overrides Sub OnPaint(e As PaintEventArgs)
      70. 'Bessere Darstellungsqualität.
      71. e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
      72. 'Zeichnen des Rechtecks.
      73. e.Graphics.FillRectangle(Brushes.Red, New RectangleF(_location, New SizeF(10, 10)))
      74. MyBase.OnPaint(e)
      75. End Sub
      76. End Class


      Diese Anwendung erstellt im ersten Schritt einen Server, auf den sich das Python-Script verbindet (evtl. müsst ihr den Port bei Euch anpassen. Mag sein, dass dieser belegt ist.). Die Daten werden vom Python-Script aus als JSON-String gesendet. Auf VB-Seite wird dieser String wieder in eine Liste von Single gecastet und verarbeitet. Ich weise die Daten aus dem Sensor hier nur rudimentär an ein PointF-Objekt zu. Das kann man mit Sicherheit noch verfeinern und die Bewegungen flüssiger machen. Hat nun alles geklappt, so startet ihr die VB-Anwendung und das Python-Skript. Ihr solltet nun ein rotes Rechteck auf der Form haben, welches ihr mit dem Handy bewegen könnt. Liegt das Handy der Länge nach flach auf dem Tisch vor Euch, entspricht dies keiner Bewegung...

      Hier das VB-Projekt (VS2019): WindowsApp11.zip Nicht vergessen, die Newtonsoft-DLL einzubinden....!

      Und noch ein kleines Demo-Video: https://www.youtube.com/watch?v=c7thqx5J8dw


      Bei Fragen einfach hier posten, stehe meistens zur Verfügung....!
      Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
      Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o