Wifi scanner als Thread

H

hatschy

Neues Mitglied
0
Hi!
Ich versuche neben dem Beschleunigungssensor und Kompass auch Wifiscan aufzuzeichnenden. Der Sinn ist die Daten von einem Testlauf festzuhalten bei dem man sich durch das Gebäude bewegt. Grundsätzlich habe ich alles schon mal Implementiert.
Jetzt möchte ich den Wifi scan als thread ausführen mit der nebenbedingung dass ich zb. max 1 Sekunde auf den Scan warte und das nehme was ich habe. ( Als nicht den vollständigen Scan abwarte - habe ich schon mit dem Broadcastreceiver gemacht - das dauert aber bis zu 4,5sekunden)

Okay. Leider Scheiter ich jetzt schon daran ein Thread zu starten und
1 Sekunde zu warten. Bei Thread.sleep() funktioniert was nicht.
Mit Thread hab ich noch nicht viel gemacht. Hab ich da einen Denkfehler?
Für Tipps wäre ich sehr dankbar. Murx schon den ganzen Tag drum rum.
Darum ist es auch a bissal Chaotisch ;)


Das ist der Code für die Runnable Klasse:
Code:
public class MyWifiScanner implements Runnable 
{
    public MyWifiScanner(WifiManager WM, TextView c)
    {
        mainWifi = WM; // Den WifiManger will ich dann übergeben 
        ConnectTViewconsle(c); // Ist zum Testen 
    }
     public void ConnectTViewconsle(TextView c)
        {
        
            console=c;
            console.setText("Thread startet");
        }
    
    @Override
   
        console.setText("Thread run startet");
        // Hier Starte ich dann den Wifi scan 
        try {
            Thread.sleep(1000);
            //  Hier will ich dann denn Scan auslesen 
            // nebenbedinung könnte noch werden dass ich auch schon früher stoppe 
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        console.setText("habe gewarete");
        }
}
In der Activity habe ich einen Button lisen auf START und STOP.
Initialisert wird so:
Code:
 neuerthread = new MyWifiScanner(mainWifi, (TextView)findViewById(R.id.TVconsoleWifitest));
         meinThread = new Thread(neuerthread);
Button Start
Code:
    bstart=(Button) findViewById(R.id.bstart);
    bstart.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                  if(!meinThread.isAlive()) meinThread.start();
    }
                });


Der ursprüngliche Beitrag von 16:15 Uhr wurde um 16:21 Uhr ergänzt:

Das ist noch aus dem LogCat
03-12 11:20:04.060: E/AndroidRuntime(842): FATAL EXCEPTION: Thread-53
03-12 11:20:04.060: E/AndroidRuntime(842): Process: com.example.tunavi, PID: 842
03-12 11:20:04.060: E/AndroidRuntime(842): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-12 11:20:04.060: E/AndroidRuntime(842): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
03-12 11:20:04.060: E/AndroidRuntime(842): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:857)
03-12 11:20:04.060: E/AndroidRuntime(842): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4320)
03-12 11:20:04.060: E/AndroidRuntime(842): at android.view.View.invalidate(View.java:10935)
03-12 11:20:04.060: E/AndroidRuntime(842): at android.view.View.invalidate(View.java:10890)
03-12 11:20:04.060: E/AndroidRuntime(842): at android.widget.TextView.checkForRelayout(TextView.java:6587)
03-12 11:20:04.060: E/AndroidRuntime(842): at android.widget.TextView.setText(TextView.java:3813)
03-12 11:20:04.060: E/AndroidRuntime(842): at android.widget.TextView.setText(TextView.java:3671)
03-12 11:20:04.060: E/AndroidRuntime(842): at android.widget.TextView.setText(TextView.java:3646)
03-12 11:20:04.060: E/AndroidRuntime(842): at com.example.tunavi.MyWifiScanner.run(MyWifiScanner.java:42)
03-12 11:20:04.060: E/AndroidRuntime(842): at java.lang.Thread.run(Thread.java:841)
03-12 11:20:08.560: I/Process(842): Sending signal. PID: 842 SIG: 9
 
Du darfst aus einem Thread nicht aufs GUI zugreifen. Android bietet dafür den AsyncTask, dort hast du die Methoden onPreExecute, onProgressUpdate und onPostExecute, die auf dem UI-Thread ausgeführt werden. Dort hast du dann Zugriff auf deine Views.

Für normale Threads kannst du auch Handler verwenden. Damit kannst du von/an Threads Messages senden/empfangen und schlussendlich dasselbe (und noch mehr) machen wie mit einem AsyncTask.
 
  • Danke
Reaktionen: hatschy
Okay. Danke! Die Views hab ich eigentlich nur zum Testen ob auch alles passiert wie ich will. ;)

Der ursprüngliche Beitrag von 16:52 Uhr wurde um 17:20 Uhr ergänzt:

Und so geht jetzt auch :)
Übergebe dem Thread einen Handler

meine Run schaut jetzt so aus
Code:
public void run() {
        // TODO Auto-generated method stub
         try {
             Thread.sleep(500);
         } catch (InterruptedException e) {
         }
        handler.post(new Runnable() {
             @Override
             public void run() {
                 console.setText("Habe gewartet");
             }
         });
        }
Danke nochmal!
 
Wenn das Programm für längere Zeit im hintergrund laufen soll würde ich einen sogenannten Service empfehlen. Den kannst du von deiner Activity mit einem button starten und beenden. Dieser Service greift auch nicht auf die UI zu so das du nicht mit AsyncTasks oder ähnlichen arbeiten braust.

Services | Android Developers

ein Service muss wie eine Activity in der AndroidManifest.xml eingetragen werden. Starten lässt er sich wie eine Activity über einen Intent.
 
  • Danke
Reaktionen: hatschy
hmm
Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.
 
  • Danke
Reaktionen: hatschy
Danke mal für die Hinweise. Es soll schon so 10-30 min im Hintergrund laufen. Im Moment bin ich mal zufrieden.
Weiß jemand von euch ob es ausreicht den scan des Wifi Manager neu zu starten um aktuelle Resultate zu bekommen.

Die Run von meinem Thread schaut jetzt so aus.

Code:
public void run() {
        // TODO Auto-generated method stub  
        
    try {
        while ( !isInterrupted() )
        {
            a++;
            mainWifi.startScan();
            Thread.sleep(1000);
            size=mainWifi.getScanResults().size();
            // bekomme ich mit getScanResults() immer einen neuen Scan 
            // oder ist das der Alte erweitert?
    
            handler.post(new Runnable() {
                 @Override
                 public void run() 
                 {
                     console.setText("Scan:"+a +" Gefunden AP " +size);
            }});
            
        }
        }
         catch ( InterruptedException e )
          {
           interrupt();
           System.out.println("");
          }       
        }
}
 
amfa schrieb:
hmm
Zitat:
Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.

danke für den Hinweis.
Seltsamerweise läuft mein Code ohne das die UI Probleme bekommt.

Hier ist meine Service der die WLAN SSID ausliest und wenn er die richtige gefunden hat sich mit dieser verbindet. Vielleicht hilft es dir. Es läuft als Service.

https://gist.github.com/CoffeeCode/9529503
Warnung: schlechter Code. waren meine ersten schritte mit Android und Services.
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: hatschy
CoffeeCode schrieb:
danke für den Hinweis.
Seltsamerweise läuft mein Code ohne das die UI Probleme bekommt.

Ein IntentService erzeugt bereits einen eigenen Thread, nur der "normale" Service nicht.
 
  • Danke
Reaktionen: hatschy
Ich habe einen Testlauf entlang eines Gangs gemacht. Verwendet habe ich ein Galaxy S2 ein HTC Desire. Wenn ich einen kompletten Scan abwarte dauert es beim dem S2 gute 4,5 Sekunden beim HTC ca. eine Sekunde. Das lange warte wollte ich ja mit der sleep Funktion umgehen und nehmen was ich bekomme.
Schaut man sich die Scan-Ergebnisse an sieht man aber dass beim S2 Trotzdem nur all 4 Sekunden neue Lev Werte bekomme.
Ich bin mit beiden Handys die Teststrecke abgegangen. Man sieht dass beim Desire die Abtastung besser funktioniert.
Beim S2 ist der erste Scan sogar noch der wo ich noch in meinem Zimmer neben dem AP war.
Weiß jemand wie ich die Abtastrate auch beim S2 verkürzen kann?
 

Anhänge

  • AP_run_S2.png
    AP_run_S2.png
    1,2 KB · Aufrufe: 200
  • AP_run_Desire.png
    AP_run_Desire.png
    1,5 KB · Aufrufe: 188
Also laut Doku
WifiManager | Android Developers
Bekommst du immer das Ergebnis vom letzten Scan zurück ich vermute vom letzten fertigen Scan.

Ich vermute jetzt mal das könnte einfach eine Hardware Sache sein und somit kannst du den Scan vermutlich nicht verkürzen.
 
  • Danke
Reaktionen: hatschy

Ähnliche Themen

Manny87
  • Manny87
Antworten
11
Aufrufe
166
swa00
swa00
R
  • raller
Antworten
15
Aufrufe
549
DOT2010
DOT2010
wernho
Antworten
11
Aufrufe
687
wernho
wernho
Zurück
Oben Unten