Geräuschpegel messen

M

Martin2013

Neues Mitglied
0
Hallo,
wie kann ich mein Mikrophone vom Smartphone als Messgerät verwenden ?

Will durch Geräusche eine Art Animation im Hintergrund meiner App machen.

MfG. Martin
 
Ich finde dort nur Möglichkeiten wie man Audio recorded und das aufgenommene dann wieder abspielt. Aber wie kann ich das aufgenommene in Echtzeit verwenden ?

Als Sinusgröße anzeigen zu lassen z.B..
 
Hey,
StefMa hat dich ziemlich sicher mit dem MediaRecorder schon auf die richtige Spur gebracht.

Schau mal hier...
 
Ich hab jetzt ein Programm womit ich Audio aufnehmen kann. Jetz wollte ich mal mit myAudioRecorder.getMaxAmplitude() den Wert auf ein TextView ausgeben lassen. Aber es wird immer 0.0 angezeigt.

Kann mir wer helfen wie ich jetzt die Amplitude immer wieder auf mein TextView ausgeben kann ?


Code:
package com.example.audiocapturetest;

import java.io.IOException;

import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

       private MediaRecorder myAudioRecorder;
       private double amplitude = 0.0;
       private double mEMA = 0.0;
       private String outputFile = null;
       private Button start,stop,play;
       private TextView textview;
      
       static final private double EMA_FILTER = 0.6;

       @Override
       protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          start = (Button)findViewById(R.id.button1);
          stop = (Button)findViewById(R.id.button2);
          play = (Button)findViewById(R.id.button3);
          textview = (TextView)findViewById(R.id.textView1);

          stop.setEnabled(false);
          play.setEnabled(false);
          outputFile = Environment.getExternalStorageDirectory().
          getAbsolutePath() + "/myrecording.3gp";;
          amplitude = getAmplitude();
          textview.setText(amplitude + "");

          myAudioRecorder = new MediaRecorder();
          myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
          myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
          myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
          myAudioRecorder.setOutputFile(outputFile);

       }

       public void start(View view){
          try {
             myAudioRecorder.prepare();
             myAudioRecorder.start();
          } catch (IllegalStateException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
          } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
          }
          start.setEnabled(false);
          stop.setEnabled(true);
          Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_LONG).show();

       }


       public void stop(View view){
          myAudioRecorder.stop();
          myAudioRecorder.release();
          myAudioRecorder  = null;
          stop.setEnabled(false);
          play.setEnabled(true);
          Toast.makeText(getApplicationContext(), "Audio recorded successfully",
          Toast.LENGTH_LONG).show();
       }
       
       public double getAmplitude() {
           if (myAudioRecorder != null)
                   return  (myAudioRecorder.getMaxAmplitude()/2700.0);
           else
                   return 0;

   }
       public double getAmplitudeEMA() {
 
           mEMA = EMA_FILTER * amplitude + (1.0 - EMA_FILTER) * mEMA;
           return mEMA;
   }


       @Override
       public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.main, menu);
          return true;
       }
       public void play(View view) throws IllegalArgumentException,   
       SecurityException, IllegalStateException, IOException{
       
       MediaPlayer m = new MediaPlayer();
       m.setDataSource(outputFile);
       m.prepare();
       m.start();

       Toast.makeText(getApplicationContext(), "Playing audio", Toast.LENGTH_LONG).show();
       

       }

    }
 
Hey,

lass doch mal Logcat zur Laufzeit mitlaufen und dir ausgeben welchen Wert deine Amplitude hat. Vermutlich wird Logcat ebenfalls "0.0" anzeigen.

Code:
mEMA = EMA_FILTER * amplitude + (1.0 - EMA_FILTER) * mEMA;
Sicher, dass diese Rechnung funktioniert, wenn du Anfangs mEMA schon mit 0 initialisierst?
(Hab deinen Code aber auch nur schnell überflogen)
 
Zuletzt bearbeitet:
Code:
mEMA = EMA_FILTER * amplitude + (1.0 - EMA_FILTER) * mEMA;
ist immer 0. mEMA ist immer 0, und der Wert des Feld amplitude ist auch immer 0.

amplitude
wird in onCreate ein Wert zu gewiesen (amplitude = getAmplitude();).
Da dort das Feld myAudioRecorder noch null ist, die Methode getAmplitude() gibt deshalb den Wert 0 zurück.

Der Code deiner Activity sieht so aus, als hättest du ihn einfach nur aus der Klasse Soundmeter (dein Link) in deine Activitiy kopiert. Und jetzt steht er einfach dort nur herum. ;)

Hast du schon mal in die Activity des Projektes geschaut. Da steht die Lösung für dein Problem. NoiseAlert.java - android-labs - Umbrella project for Android applications in progress - Google Project Hosting
 
Hi,
Ich habs erstmal geschafft die Amplitude an einer TextView auszugeben. Da ich das mit einem Thread nicht hinkrieg hab ich halt zum versuchen eine Seekbar genommen. Und immer wenn ich sie bewegt hab, hab die amplitude ausgelesen und am TextView ausgegeben.

Ich will das aber ohne SeekBar machen das die Amplitude sobald ich auf Start drück dauernd ausgelesen und angezeigt wird. Wieso funktioniert das bei mir nicht ? Anbei mein code.

Code:
public class MainActivity extends Activity {

       private MediaRecorder myAudioRecorder;
       private String outputFile = null;
       private Button start,stop,play;

       private double mEMA = 0.0;
       static final private double EMA_FILTER = 0.6;
       static int i = 1;
       
       
       double amplitude;
       @Override
       protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          start = (Button)findViewById(R.id.button1);
          stop = (Button)findViewById(R.id.button2);
          play = (Button)findViewById(R.id.button3);


          stop.setEnabled(false);
          play.setEnabled(false);
          outputFile = Environment.getExternalStorageDirectory().
          getAbsolutePath() + "/myrecording.3gp";;

          myAudioRecorder = new MediaRecorder();
          myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
          myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
          myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
          myAudioRecorder.setOutputFile(outputFile);
          
          
          
           
       }


    
        
       public void start(View view){
           new Thread(new Runnable() {
                public void run() {
                    amplitude = getAmplitude();
                     TextView textview = (TextView)findViewById(R.id.textView1);
                     textview .setText("Amplitude " + amplitude);
                }
            }).start();

          try {
             myAudioRecorder.prepare();
             myAudioRecorder.start();

          } catch (IllegalStateException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
          } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
          }
          start.setEnabled(false);
          stop.setEnabled(true);
          Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_LONG).show();
          
         
         
       }

       public void stop(View view){
          myAudioRecorder.stop();
          myAudioRecorder.release();
          myAudioRecorder  = null;
          stop.setEnabled(false);
          play.setEnabled(true);
          Toast.makeText(getApplicationContext(), "Audio recorded successfully",
          Toast.LENGTH_LONG).show();
       }
       @Override
       public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.main, menu);
          return true;
       }
       public void play(View view) throws IllegalArgumentException,   
       SecurityException, IllegalStateException, IOException{
       
       MediaPlayer m = new MediaPlayer();
       m.setDataSource(outputFile);
       m.prepare();
       m.start();
       Toast.makeText(getApplicationContext(), "Playing audio", Toast.LENGTH_LONG).show();
       
       }
       
       public double getAmplitude() {
           if(myAudioRecorder!=null){
                   return  (myAudioRecorder.getMaxAmplitude()/2700.0);
           }else{
               return 0;
           }

   }
       public double getAmplitudeEMA() {
           amplitude = getAmplitude();

           mEMA = EMA_FILTER * amplitude + (1.0 - EMA_FILTER) * mEMA;
           
           return mEMA;
   }


    }
 
Sers, das mit dem Thread würde ich komplett(!) streichen.
Meiner Erfahrung nach ist ein Thread in 90% der Fälle nicht das was man braucht.

Greife lieber auf die clock zurück und lass das Programm laufen, bis eine Interaktion es abbricht, oder die Zeit abgelaufen ist.

Pseudocode:
Startzeit + Zeit die dein Programm laufen soll = Endzeit
While (aktuelle Zeit < Endzeit) {
...
Aktuelle Zeit = System time() ;
...
}


Ab wann die Logik beginnen soll lässt sich ja recht einfach über einen boolean prüfen (Button pressed?)


PS: das mit der seekbar finde geil :-D du würdest auch einen guten Hacker abgeben - nicht schlecht, auf so Ideen muss man erstmal kommen.

PPS: so wie ich es gerade sehe, kommt dein Thread erst gar nicht zur Ausführung, da run(); fehlt.
Aber wie gesagt, dass mit dem Thread ist hier wahrscheinlich sowieso nicht praktikabel.
 
Zuletzt bearbeitet:
ui_3k1 schrieb:
Pseudocode:
Startzeit + Zeit die dein Programm laufen soll = Endzeit
While (aktuelle Zeit < Endzeit) {
...
Aktuelle Zeit = System time() ;
...
}

Wenn du so eine Schleife im GUI Thread ausführst, wirst du aber bis zum Ende der Zeit nichts anderes mit der App machen können.
Du kannst dann nicht auf Benutzereingaben reagieren, da der aktuelle Thread ja mit der Schleife beschäftigt ist.
ein Thread kann doch immer nur an einer bestimmten Stelle im Code arbeiten.

Deswegen braucht man ja für Netzwerkzugriff zwingend ein Thread.
Weil ansonsten in der ganzen zeit wo nur auf den Download gewartet wird, GAR nichts anderes in der App passiert (ANR).

Deswegen ist für mein dafürhalten hier ein Thread nötig sonst hat man irgendwann zwingend eine ANR Meldung
 
Hey, ich weiß was du meinst und du hast meines Wissens auch recht: die Kombination zwischen Schleife und Thread ist problematisch. Aber das meine ich ja nicht. Meine Vorgehensweise ist: kein Thread und nur die Schleife.
Dass die App weiterhin "nutzbar" bleibt lässt sich durch eine Aktualisierung (zB on Sensor changed, oder Button clicked) und der zugehörigen Prüfung (Grenzwert, bzw Zeit überschritten) darstellen. Gui Anpassung läuft dann ebenfalls in dieser loop.

Ich sehe absolut keinen Grund hier einen Thread zu benutzen, der wahrscheinlich noch deutlich "unflexibler" ist - zb was einen vorzeitigen Abbruch angeht.

Letztlich funktioniert jede "main loop" eines Spiels auf diesem Prinzip (und nicht auf dem des Threads) :)

Für Netzwerkanwendungen oder andere datenverarbeitende Prozesse hast du ebenfalls recht.
 
Ich würde auch lieber einen eigenen Thread benutzen. Das mit den loop im main Thread, ist schon sehr gewagt. Würde mal sagen, das ist der heißere Anwärter für ein ANR.

Eine GUI verarbeitet teilweise schon sehr viel Daten, das macht es schon Sinn andere Arbeiten in einen Thread oder Service auszulagern.
 
Zuletzt bearbeitet:
Hmm, mich wundert es gerade, dass ihr das beide anders seht. Ich habe über zwei Nächte an einer Logik von einem Thread gesessen, der nie korrekt vorzeitig beendet werden konnte. oO
Habt ihr dazu vielleicht ein Beispiel, oder einen Link zu einer Beschreibung wie man es regeln kann, dass eine Activity über den Thread gesteuert wird?

In meinem Szenario wurde auf den Bewegungssenor "gehört" und gleichzeitig ist ein Countdown abgelaufen. Wenn zu stark bewegt -> Beenden der Activity / Wenn Timer abgelaufen -> Beenden der Activity.

Resultat: Ist die Zeit abgelaufen hat alles gepasst. Was nicht gepasst hat: wenn zu stark bewegt wurde, wurde zwar die neue Activity aufgerufen, der Thread lief allerdings ungestört weiter. Keine Methode konnte das verhindern.

Ich kann mir beim besten Willen nicht vorstellen, dass in obigen Beispiel ein Thread mehr Sinn ergibt als meine Variante mit der Systemzeit. Wichtig: bei der Systemzeit ist es grundsätzlich schon mal ausgeschlossen, dass irgendein Thread sich im Hintergrund selbt reaktiviert bzw. unvorhergesehene Aktionen hervorruft.

Aber gerade weil ich da so vernarrt bin, interessiert es mich wie ihr euch eine mögliche Alternative vorstellt. :smile:

Wenn ihr im PlayStore "Rumms - das Partyspiel" eingebt, findet ihr das "Erzeugnis" meiner Arbeit. :D
 
meiner Meinung nach dürfte im Normalfall keiner der anderen Methoden ausgeführt werden solange man sich in einer Schleife im GUI Thread befindet.

Eigentlich dürfte das relativ einfach sein den Thread zu beenden.
Du baust in deine Thread Klasse eine stop() Methode (muss anders heißen da stop() selbst als deprecated in der Thread Klasse schon exisitiert)

Auf jedenfall kannst du in der Methode dann eine Variable beispielsweise auf false setzen.
In dem Loop des Threads prüfst du dann ob die Variable false ist, wenn sie false ist beendest du den Loop und der Thread ist auch beendet sobald das ende der run() methode erreicht ist.

Eigentlich dürfte in deinem Beispiel die Schleife immer bis zur "Endzeit" laufen und sich durch nichts stören lassen.
Wenn diese Schleife im GUI Thread läuft kann man in der Zeit aber keinerlei anderen Aktionen verarbeiten, also Sensor Change Aktionen oder Clicks auf einen Button.

Zumindest in der Theorie, ich weiß z.B. nicht ob die onsernsorchanged methode nicht intern von einem anderen Thread aufgerufen wird oder so.
 
Hehe, genau das Gegenteil war bei mir der Fall. :D

Aber kann auch sein, dass ich dennoch irgendwas falsch mit dem Thread hatte. Ich muss auch ganz ehrlich sagen, dass ich nicht soooo der peil habe wie das funktioniert. (In Grundzügen natürlich schon, aber wahrscheinlich steckt hinter dem Thema deutlich mehr als nur run(); wenn man sich bspw noch über Asyn.Tasks Gedanken machen muss oder über die möglichen Exceptions)... :p

Hier mal die "Hauptlogik" meines Spiels (der Code funktioniert astrein - so kommt er auch in der Anwendung zum Einsatz)

Code:
@SuppressLint("InlinedApi")
    @Override
    public void onSensorChanged(SensorEvent event) {

        if (boom == false) {

            // long_startInclTimer = Uhrzeit an der die Bombe hochgeht
            Long long_startInclTimer = long_starttime + int_seconds;

            f_colorSuperVisor = f_mAccel / f_sensibility * 100;
            if (f_colorSuperVisor < 0) {
                f_colorSuperVisor *= -1;
            }
            // negative Werte vermeiden
            if (f_colorSuperVisor < 1) {
                f_colorSuperVisor = 1;
            }

            // Vibrationseinstellung
            if (shouldVibrateWhenClose == true) {
                if (f_colorSuperVisor > 67) {
                    Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                    v.vibrate(10);
                }
            }

            // Soundeinstellugnen
            if (shouldPlaySoundWhenClose == true
                    && (long_starttime + 500) < long_actualtime) {
                if (f_colorSuperVisor > 67) {
                    beepShotNice.start();
                }
            }

            // FARBEN
            if (shouldShowColors == true
                    && (long_starttime + 500) < long_actualtime) {
                // Hintergrundfarbeinstellung durch Java Klasse someView erhält
                // einen beliebigen View-Inhalt und setzt darüber die
                // Hintergrundfarbe
                View someView = findViewById(R.id.btn_ticking_next_player);
                View root = someView.getRootView();

                // Durch setUprate lässt sich die Updaterate reduzieren
                int setUprate = 1;
                if (reduceUpdateRate % setUprate == 0) {
                    if (f_colorSuperVisor < 20) {
                        root.setBackgroundColor(getResources().getColor(
                                android.R.color.holo_green_dark));
                    }
                    // falls noch gelb gewünscht wäre
                    // if (f_colorSuperVisor > 20 && f_colorSuperVisor < 35) {
                    // root.setBackgroundColor(getResources().getColor(
                    // R.color.yellow));
                    // }
                    if (f_colorSuperVisor > 20 && f_colorSuperVisor < 67) {
                        root.setBackgroundColor(getResources().getColor(
                                android.R.color.holo_orange_dark));
                    }
                    if (f_colorSuperVisor > 67) {
                        root.setBackgroundColor(getResources().getColor(
                                android.R.color.holo_red_dark));
                    }
                }
            }

            // ProgressBar für Sensor zeigen
            if (shouldShowProgressSensor == true) {
                progressSensor.setProgress((int) f_colorSuperVisor);
            }
            if (shouldShowProgressSensor == false) {
                TextView clearSensorTextView = (TextView) findViewById(R.id.tv_ticking_sensor_progress);
                clearSensorTextView.setText("");
                progressSensor.setVisibility(View.INVISIBLE);
            }

            // ProgressBar für Timer zeigen
            if (shouldStartNow == true) {
                if (shouldShowProgressTime == true) {
                    long long_elapsedTime = long_actualtime - long_starttime;
                    int int_elapsedTime = (int) long_elapsedTime;
                    int int_progressTime = (int_elapsedTime / int_seconds_saved) / 10;
                    progressTime.setProgress(int_progressTime);
                }
            }
            if (shouldShowProgressTime == false) {
                TextView clearTimeTextView = (TextView) findViewById(R.id.tv_ticking_time_progress);
                clearTimeTextView.setText("");
                progressTime.setVisibility(View.INVISIBLE);
            }

            // SENSOR-EINSTELLUNGEN
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];
            f_mAccelLast = f_mAccelCurrent;
            f_mAccelCurrent = (float) Math
                    .sqrt((double) (x * x + y * y + z * z));
            float delta = f_mAccelCurrent - f_mAccelLast;
            f_mAccel = f_mAccel * 0.9f + delta; // kleine Reduzierung
            // Entgegennahme eines negativen Beschleunigungswerts
            if (f_mAccel < 0) {
                f_negative_mAccel = f_mAccel;
            }

            if (shouldStartNow == true) {
                long_actualtime = System.currentTimeMillis();
            }

            // ZEIT ABGELAUFEN
            if (long_startInclTimer < long_actualtime) {
                // timeUpWho = 1;
                boom = true;
            }

            // DELAY von 1500ms, da anfangs Werte falsch übertragen werden
            if (long_starttime + 1500 < long_actualtime) {
                // Festhalten des POSITIVIEN MAXIMALWERT
                if (f_maxValue < f_mAccel)
                    f_maxValue = f_mAccel;
                // Festhalten des NEGATIVEN MAXIMALWERT
                if (f_negative_mAccel < f_negative_maxValue)
                    f_negative_maxValue = f_negative_mAccel;
                // SENSOR ZU STARK BEWEGT
                if (f_mAccel > f_sensibility
                        || f_negative_mAccel < f_negative_sensibility) {
                    boom = true;
                }
            }
            if (boom == true) {
                startNextActivity();
            }
            reduceUpdateRate++;
        }
    }
Und so loopt man sich da durch die Anwendung, bis "boom" true ist. In diesem Fall, bis entweder keine Zeit mehr oder der Sensor zu stark bewegt^^

PS: was auf jeden Fall noch schöner geht ist die Endzeit auf 0 zu prüfen. Damit spart man sich noch mal einen weiteren Vergleich :D
 
Zuletzt bearbeitet:
In deinem Spiel hast du doch überhaupt kein Loop.
Zumindest seh ich keinen.

Gerade mal getestet dein Spiel.
Ich weiß nicht genau welchen Sensor du nutzt, aber in dem Fall, dass der Sensor so unempfindlich ist, dass er keinerlei Änderung registriert dürfte in deiner App gar nichts passieren ;)

Bei dir ist das ja kein Loop sondern einfach nur die reaktion auf ein Event.
Das ist was anderes, weil das System deine Methode halt aufruft wenn der Sensorwert sich geändert hat, dann arbeitet der alles ab und danach geht er aus der Methode wieder raus und genau zu dem Zeitpunkt kann deine App wieder "Befehle" annehmen.
Also z.B. ein Button Click event und bleibt deshalb responsive.

Das dürftest du sehen, wenn du im Debugger durch die Methode gehst und irgendwo in dieser Methode einen Breakpoint setzt.
Solange du an diesem Breakpoint bist wird deine App keinerlei Reaktion zeigen.

genauso vehält es sich mit einem Loop
while(true) {
doNothing();
}

Der Thread in dem das ausgeführt wird, wird immer und immer wieder die gleiche Zeile ausführen und reagiert in der Zeit z.B. auch nicht auf Sensorchanged events.
Du kannst dir das so vorstellen, wenn du im Debugger bist ist ja die Zeile die aktuell ausgeführt wird markiert.
Pro Thread hast du quasi nur eine Markierung die immer nur an einer einzigen Stelle sein kann.
Solange dort was getan wird, passiert nirgendswo anders was in deiner App.
 
Hi,
danke für die Antwort.
Ich verstehe nicht was du meinst mit, ich soll auf die Clock zurückgreifen.
Wenn meine App hat ja auch noch andere Funktionen, deswegen kann ich ja nicht einfach eine While-Schleife laufen lassen, die meine sonstigen Funktionen unterbricht.

Ich will ja eig. einen Interrupt.
 
Hmm, ich dachte, dass dein Programm in einer fest eingestellen Zeitspanne Aktion Xy ausführt und dann nach Beenden durch Zeit, oder durch Button drücken in eine anderen Bereich springt und dort dann dort die nächste (Inter)Aktion durchführt.
Aber wenn mehrere Dinge parallel nebeneinander ablaufen sollen, ist meine Variante wirklich nicht das was du brauchst.

Leider kenne ich mich mit Threads nicht besonders gut aus. Vielleicht kann dir amfa da mehr weiterhelfen. Interessant fände ich eine Lösung auch - denn bis dato ist fast alles schief gegangen was ich im Bezug zu Threads probiert habe.
 
Hier mal ein Beispielcode mit einem Thread
Du kannst dir sowas ähnliches bauen, da wo ich das TextView ändere kannst du dann
entweder die amplitude auch erst mal in ein textfeld schreiben oder aber die entsprechende grafik schreiben

Wenn du den Code testn willst brauchst du eine TextView mit der ID textView1
(oder du änderst das im Code)

Eigentlich ist das relativ einfach

Code:
package de.amfa.newtestapp;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity implements Callback {

    TextView textView;
    int count = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView1);
        

        // Hier wird der Handler definiert welcher die Message entgegen nimmt (siehe unten)
        final Handler handler = new Handler(this);
        
        // Runnable hier wird festgelegt was passiert
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                // hier machst du eigentlich gar nichts nur eine Schleife die immer eine leere Message an deinen Handler schickt
                while (true){
                    handler.sendEmptyMessage(0);
                    try {
                        // Hier warte ich eine Sekunde, die Zeit kannst du natürlich nach belieben ändern
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // Nichts machen (eigentlich unschön aber ist ja nur ne demo ;))
                    }
                }
            }
        };
        // Hier wird der Thread erstellt mit dem runnable von oben
        // der runnable enthält den eigentlichen Code
        Thread thread = new Thread(runnable);
        thread.start();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean handleMessage(Message msg) {
        // Hier wird die (leere) Message die der Thread oben schickt verarbeitet
        // in Meinem Fall gebe ich nur den Wert von count in einem Textfeld aus
        textView.setText(String.valueOf(count++));
        return true;
    }

}
 
  • Danke
Reaktionen: ui_3k1

Ähnliche Themen

Muecke1982
Antworten
8
Aufrufe
1.034
Skyhigh
Skyhigh
fromfuture
  • fromfuture
Antworten
0
Aufrufe
874
fromfuture
fromfuture
Zurück
Oben Unten