www.mikrocontroller.net

Forum: PC-Programmierung JavaME Input Stream


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Su Si (sannchen)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo Leute,

ich möchte ein Programm für ein Digitalfunkgerät schreiben.
Dieses soll seriell Daten ausgeben aber auch einlesen. Der Output Stream 
funktioniert, nur der Input Stream nicht.
Ich gebe in meinem Hyperterminal aufn PC Daten ein, aber das Programm 
sagt mir immer "Fehler: null", sprich das keine Daten ankommen.
 private void sendeDaten(byte[] b)
    {
        try
        {
            os = cc.openOutputStream();
            os.write(b);
            os.flush();
            os.close();
        }
        catch(IOException io)
        {
            textBox.setString("Fehler beim Senden der Daten: " + io.getMessage());
        }    
    }
    
    private void empfangeDaten()
    {
        try 
        {
            is = cc.openInputStream();
            byte[] data = new byte[150];
            int num;
            while(is.available() > 0) 
            {
    num = is.read(data, 0, data.length);
    textBox.setString("Empfange: "+ new String(data, 0, num));
            }
           is.close();
  }
        catch (IOException e) 
        {
            textBox.setString("Fehler beim Lesen empfangener Daten");
  }
    }
    
    private void open() 
    { 
      try
        {  
           cc= (CommConnection)Connector.open("comm:COM0");
 
            if(cc != null)
            {
                textBox.setString("Port offen"); 
                sendeDaten("AT D64A769F221E8".getBytes());
                empfangeDaten();                            
                cc.close();
                textBox.setString("Port geschlossen");        
            }
        }      
      catch(IOException io)
      {
           textBox.setString("Fehler " +io.getMessage());
      }
      finally
      {
          if (cc != null)
          {
             try
             {
                 cc.close(); 
                 os.close();
                 is.close();
             }
             catch(IOException e)
             {
                 textBox.setString("Fail: " + e.getMessage()); 
             }
          }
      }

Danke!
Sannchen

Autor: Läubi .. (laeubi) (Moderator) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
In deiner open Methode schließt du alles gleich wieder, das kann so 
nicht gut gehen.
Auch das Vermischen von GUI und Daten/Kommunikationscode ist nicht so 
schön.

Su Si schrieb:
> "Fehler: null", sprich das keine Daten ankommen

Das würde ich so nicht sagen, du greifst eher auf eine Variable zu 
welche null ist, also am besten mal den Stacktrace immer mit ausgeben 
und nicht nur lapidar die Meldung.

All diese Dinge haben übrigens gar nichts mit JavaME direkt zu tun, wie 
ich schon in einem anderem Thread schrieb, dir wird nichts anderes 
übrigbleiben als sich etwas mehr mit Java bzw. Programmieren allgemein 
zu beschäftigen sonst wird das nix.

Autor: Su Si (sannchen)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Danke Läubi für deine Antwort! :)
Du meinst also, ich solle in der finally nicht den In- und Output Stream 
wieder schließen?
Wie solle ich es denn sonst machen?

Ich habe mich davor schon mit Java beschäftigt. Finde allerdings das 
sich das zu JavaME doch schon unterscheidet. Und leider bleibt mir nicht 
so viel Zeit mich damit noch neben her zu beschäftigen, da es für eine 
Bachelorarbeit ist.

Wie würdest du denn den Code umschreiben?

Autor: Läubi .. (laeubi) (Moderator) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Die Streams und der Port müssen/sollten Member der Klasse sein, dan 
benötigst du für deine Klasse natürlich noch eine Close Methode welche 
ganz am ende des Programms aufgerufen wird (z.B. beim schließen der GUI 
oder als Shutdown-Hook).

Am besten lagert man das in eine eigene Klasse aus z.B. so:
public class SerialCommunicator implements Closeable {

  private final ExceptionListener listener;
  private CommConnection cc;
  private final String port;
  private BufferedReader is;
  private OutputStreamWriter os;

  public SerialCommunicator(String port, ExceptionListener listener) {
    this.port = port;
    this.listener = listener;
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

      @Override
      public void run() {
        SerialCommunicator.this.close();
      }
    }));
  }

  public void close() {
    closeSilent(cc);
    cc = null;
    closeSilent(is);
    is = null;
    closeSilent(os);
    os = null;
  }

  private void closeSilent(Closeable closeable) {
    if (closeable != null) {
      try {
        closeable.close();
      } catch (IOException e) {
        //ignore...
      }
    }
  }

  public boolean sendeDaten(String data) {
    try {
      if (os != null) {
        os.write(data);
        os.flush();
        return true;
      }
    } catch (IOException io) {
      listener.exceptionThrown(io);
    }
    return false;
  }

  public String empfangeDaten() {
    if (is != null) {
      try {
        return is.readLine();
      } catch (IOException e) {
        listener.exceptionThrown(e);
      }
    }
    return null;
  }

  public boolean open() {
    try {
      cc = (CommConnection) Connector.open(port);
      if (cc == null) {
        throw new IOException("Kann Port " + port + "nicht öffnen");
      } else {
        is = new BufferedReader(new InputStreamReader(cc.openInputStream()));
        os = new OutputStreamWriter(cc.openOutputStream());
        return true;
      }
    } catch (IOException io) {
      listener.exceptionThrown(io);
    }
    return false;
  }
}
In deiner GUI erzeugst du dir nun eine SerialCommunicator Objekt z.B. so
SerialCommunicator com = new SerialCommunicator("comm:COM0", new ExceptionListener() {

      @Override
      public void exceptionThrown(Exception e) {
        textBox.setString("Fehler " + e.getMessage());
        e.printStackTrace();
      }
    });
  com.open();
  com.sendeDaten("Hallo");
  String daten = com.empfangeDaten();
  textBox.setString("Empfangen: "+daten);
  com.close();
 und arbeitest dann mit diesem.

Su Si schrieb:
> Finde allerdings das
> sich das zu JavaME doch schon unterscheidet.

In dem ganzem Code gibt es eine Zeile welche JavaME spezifisch ist, 
der Rest ist plain Java.

Su Si schrieb:
> Und leider bleibt mir nicht so viel Zeit mich
> damit noch neben her zu beschäftigen, da es für
> eine Bachelorarbeit ist.

Vermutlich nicht für eine sonder für deine und somit gehört es 
entweder zu deiner Arbeit dazu, oder du musst dir vom Betreuer helfen 
lassen, das ist ja keine Forenarbeit oder?

Autor: Su Si (sannchen)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hey Läubi, danke für deine Hilfe und deinen Code!!

Mein Problem ist aber auch, dass das Funkgerät ein Midlet braucht, also 
noch diese Standardmethoden, welche ich beispielweise nicht in deinem 
Code sehe.
Und ich finde, dass unterscheidet sich auch zu Java.

Ja das stimmt, es ist meine Bachelorarbeit. Nur leider, kann mir mein 
Betreuer nicht sonderlich helfen. Deswegen habe ich gehofft, dass hier 
ein paar Leute mehr Erfahrung haben und mir helfen können. Und ich bin 
sehr glücklich und dankbar, dass du mir hilfst und Tipps gibst!!

Autor: Läubi .. (laeubi) (Moderator) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Su Si schrieb:
> Mein Problem ist aber auch, dass das Funkgerät ein Midlet braucht

In deinem Midlet kannst du doch aber Klassen verwenden welche keines 
sind. Man zwingt dich doch nicht alles in eine Klasse zu stopfen.

Deswegen schrieb ich ja das es wichtig ist wenigstens die Grundkonzepte 
verstanden zu haben. Und das kann man z.B. durch Bücher oder Tutorials 
fern ab der eigentlichen Aufgabe auch mal nebenbei in der "Freizeit" 
machen.

Su Si schrieb:
> Nur leider, kann mir mein
> Betreuer nicht sonderlich helfen.

In so einem Fall hilft es manchmal auch einfach mal Mitstudenten/innen 
um Hilfe zu bitten, vieles lässt sich im Gespräch einfacher klären als 
per PC Tastatur.

Autor: Su Si (sannchen)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Das war mir bisher nich so klar. Ich ging davon aus, dass immer alles 
ein Midlet sein muss. Ich wurde mit dem Ganzen ins kalte Wasser geworfen 
und versuch jetzt mir das alles anzueignen und auf die Reihe zu 
bekommen.

Ich bin jetzt dabei deinen Code auszuprobieren. Allerdings meckert er 
immer beim BufferedReader obwohl den aus java.io.BufferedReader 
importiere. Und mit dem "addShutdownHook" hat er seine Probleme.

Da alle mit ihren Bachelorarbeiten genug zu tun haben, bleibt sowas 
leider auf der Strecke.

Autor: Läubi .. (laeubi) (Moderator) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Su Si schrieb:
> Allerdings meckert er immer beim
> BufferedReader obwohl den aus
> java.io.BufferedReader importiere
Was meckert er?

Su Si schrieb:
> und mit dem "addShutdownHook" hat er seine Probleme
lass das erst mal weg, das war nur zum veranschaulichen, achte einfach 
darauf, dass es einen definierten Punkt gibt wo der Port geschlossen 
wird.

Autor: Su Si (sannchen)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Das er den nicht findet und er möchte, dass ich ihn in einer Klasse 
erstelle. In der JavaME gibst den scheinbar auch nicht.
http://docs.oracle.com/javame/config/cldc/ref-impl...

oder kann ich eine ganze normale Javaklasse erstellen und diese im 
Midlet einbinden? Mir wurde bisher erzählt, dass das nicht geht.

Wenn ich das "addShutdownHook" weglasse, funktionieren das ganze 
Closeable nicht mehr.

Autor: Läubi .. (laeubi) (Moderator) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Nur den Part weglöschen:
 Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

      @Override
      public void run() {
        SerialCommunicator.this.close();
      }
    }));

Su Si schrieb:
> In der JavaME gibst den scheinbar auch nicht

Dann nimm erst mal nur die Reader Klasse, dann musst du nur das lesen 
einer Zeile selbst implementieren.

Su Si schrieb:
> oder kann ich eine ganze normale Javaklasse erstellen und diese im
> Midlet einbinden? Mir wurde bisher erzählt, dass das nicht geht.

Warum sollte das nicht gehen? String, Inputstream, Outputstream, ... 
sind auch ganz 'normale' Klassen.

Autor: Su Si (sannchen)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ich werde es ausprobieren!

Dann schreibe ich das als normale Javaklasse.
Ich danke dir so sehr!!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net