diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 08bd489..9286303 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ + + diff --git a/app/src/main/java/com/example/greenwatch/Beschleunigungssensor.java b/app/src/main/java/com/example/greenwatch/Beschleunigungssensor.java index 252fe93..4874abe 100644 --- a/app/src/main/java/com/example/greenwatch/Beschleunigungssensor.java +++ b/app/src/main/java/com/example/greenwatch/Beschleunigungssensor.java @@ -20,15 +20,12 @@ public class Beschleunigungssensor extends AppCompatActivity implements SensorEv private SensorManager bsmanager; private ArrayList Gesamt_be; - private int sensorType = Sensor.TYPE_GYROSCOPE, zaehler_runde =0, listen_groesse = 500, kalibrieren, Offset_shared = 0, shared_merk, mittelwertsumme_shared; + private int sensorType = Sensor.TYPE_GYROSCOPE, zaehler_runde =0, listen_groesse = 500, kalibrieren, Offset_shared = 0; private Sensor sens, sensor_l; private float x_value = 0, y_value, z_value, Vorbesetzung = 0, gesamt_runde =0; private double Schwellwert = 0.15, mittelwertsumme = 0.0, Offset = 0.1; - String Daten, Warnung, Zeitstempel, Array_shared; - private final static String KEY_kalibirieren = "KEY_KALIBRIEREN_"+Beschleunigungssensor.class.getSimpleName(); - private final static String KEY_Gesamt_be = "KEY_GESAMT_BE_"+Beschleunigungssensor.class.getSimpleName(); - private final static String KEY_Offset = "KEY_OFFSET_"+Beschleunigungssensor.class.getSimpleName(); - private final static String KEY_Mittelwertsumme = "KEY_MITTELWERTSUMME_"+Beschleunigungssensor.class.getSimpleName(); + String Daten, Warnung, Zeitstempel; + TextView Daten_Bsensor, Warnung_Bsensor, test; private boolean toggle = true, ts_setzen = true, start_messen; @@ -137,29 +134,7 @@ public class Beschleunigungssensor extends AppCompatActivity implements SensorEv } else { Daten = "Das anmelden hat nicht geklappt"; } - } - //SharedPreferences p = getPreferences(Context.MODE_PRIVATE); - //mittelwertsumme_shared = p.getInt(KEY_Mittelwertsumme, 0); - //kalibrieren = p.getInt(KEY_kalibirieren, 0); - //Offset_shared = p.getInt(KEY_Offset, 0 ); - //Array_shared = p.getString(KEY_Gesamt_be, ""); - - //mittelwertsumme = (double) mittelwertsumme_shared; - //mittelwertsumme /= 1000000.0; - - //Offset = (double) Offset_shared; - //Offset /= 1000000.0; - - //String zw[] = Array_shared.split(";", listen_groesse); - - //if(shared_merk == 2){ - //for (int i=0; i Gesamt_be; + private int sensorType = Sensor.TYPE_GYROSCOPE, zaehler_runde =0, listen_groesse = 500, kalibrieren; + private Sensor sens, sensor_l; + private float x_value = 0, y_value, z_value, Vorbesetzung = 0, gesamt_runde =0; + private double Schwellwert = 0.15, mittelwertsumme = 0.0, Offset = 0.1; + String Daten, Warnung, Zeitstempel; + + TextView Daten_Bsensor, Warnung_Bsensor, test; + private boolean toggle = true, ts_setzen = true, start_messen; + + private AufnahmeTask aufnahmeTask; + private TextView textViewMaxAmp; + private TextView textViewMaxAmpdb; + private TextView textViewZeitstempel; + private static final int RECHTEANFORDERUNG_MIKROFON = 1; + private boolean detection_mic = false; + private String zeit = "0"; + private boolean kalibrierung_do = true; + private float threshold = 40; + private float sensitivity = 5; + private final static String KEY_WERT = "KEY_WERT_" + Mikrofon.class.getSimpleName(); + private final static String KEY_KALIBRIERUNG = "KEY_KALIBRIERUNG_" + Mikrofon.class.getSimpleName(); + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mikrofon_beschleunigung); + + Daten_Bsensor = (TextView) findViewById(R.id.DatenBsensor2); + Warnung_Bsensor = (TextView) findViewById(R.id.WarnungBsensor2); + test = (TextView) findViewById(R.id.test2); + + textViewMaxAmp = (TextView) findViewById(R.id.textViewMaxAmp2); + textViewMaxAmpdb = (TextView) findViewById(R.id.textViewMaxAmpdb2); + textViewZeitstempel = (TextView) findViewById(R.id.textViewZeitstempel2); + + bsmanager = (SensorManager) getSystemService(SENSOR_SERVICE); + if (bsmanager.getSensorList(Sensor.TYPE_GYROSCOPE).size() == 0) { + sens = null; + Daten = "kein B Sensor voranden"; + } else { + sens = bsmanager.getSensorList(sensorType).get(0); + } + Gesamt_be = new ArrayList(); + for (int i = 0; i < listen_groesse ; i++){ + Gesamt_be.add(Vorbesetzung); + } + kalibrieren = 0; + start_messen = false; + kalibrierung_do = true; + } + + public static String getTimestamp(){ + Long tslong = System.currentTimeMillis(); + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); + Date date = new Date(tslong); + String result = sdf.format(date); + + return result; + } + + @Override + public void onSensorChanged(SensorEvent event) { + StringBuilder sb = new StringBuilder(); + sb.append("x=").append(event.values[0])//.append(event.timestamp) + .append("\ny=").append(event.values[1]) + .append("\nz=").append(event.values[2]); + Daten = sb.toString(); + Daten_Bsensor.setText(Daten); + gesamt_runde = event.values[0] + event.values[1] + event.values[2]; + Gesamt_be.remove(zaehler_runde); + Gesamt_be.add(zaehler_runde, gesamt_runde); + mittelwertsumme = 0.0; + + //Mittelwert des Arrays berechnen + for (int i = 0; i < listen_groesse; i++){ + if (Gesamt_be.get(i) < 0){ + mittelwertsumme += (Gesamt_be.get(i) * (-1)); + }else { + mittelwertsumme += Gesamt_be.get(i); + } + } + mittelwertsumme = mittelwertsumme/listen_groesse; + if (kalibrieren < listen_groesse){ + Offset = mittelwertsumme; + kalibrieren++; + }else { + start_messen = true; + } + StringBuilder testsb = new StringBuilder(); + testsb.append(mittelwertsumme); + String tests = testsb.toString(); + test.setText(tests); + + if((mittelwertsumme > (Schwellwert+Offset) ) & (ts_setzen == true) &(start_messen == true)){ + Zeitstempel = getTimestamp(); + StringBuilder ts = new StringBuilder(); + ts.append(Zeitstempel) + .append(", Gruppe3") + .append(", An") + .append(", Bewegung, ") + .append(mittelwertsumme); + Warnung = ts.toString(); + Warnung_Bsensor.setText(Warnung); + ts_setzen = false; + }else if((mittelwertsumme > (Schwellwert+Offset)) & (ts_setzen == false)){ + } else if ((mittelwertsumme < (Schwellwert+Offset)) & (ts_setzen == false)) { + Warnung_Bsensor.setText(""); + ts_setzen = true; + } + + if (zaehler_runde < (listen_groesse -1)){ + zaehler_runde++; + }else { + zaehler_runde = 0; + } + } + //mittelwertsumme ist kein int in diesem programm + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + private boolean istZugriffAufMikrofonErlaubt() { + if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { + return false; + } else { + return true; + } + } + + private void zugriffAufMikrofonAnfordern() { + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, RECHTEANFORDERUNG_MIKROFON); + } + + public static String Zeitpunkt(){ + Long tslong = System.currentTimeMillis(); + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); + Date date = new Date(tslong); + String resultdate = sdf.format(date); + + return resultdate; + } + + class AufnahmeTask extends AsyncTask { + private AudioRecord recorder; + private final int sampleRateInHz = 44100; + private final int channelConfig = AudioFormat.CHANNEL_IN_MONO; + private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT; + private int minPufferGroesseInBytes; + private int pufferGroesseInBytes; + private RingPuffer ringPuffer = new RingPuffer(10); + + AufnahmeTask() { + minPufferGroesseInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); + pufferGroesseInBytes = minPufferGroesseInBytes * 2; + recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat, pufferGroesseInBytes); + + int anzahlBytesProAbtastwert; + String s; + switch (recorder.getAudioFormat()) { + case AudioFormat.ENCODING_PCM_8BIT: + s = "8 Bit PCM "; + anzahlBytesProAbtastwert = 1; + break; + case AudioFormat.ENCODING_PCM_16BIT: + s = "16 Bit PCM"; + anzahlBytesProAbtastwert = 2; + break; + case AudioFormat.ENCODING_PCM_FLOAT: + s = "Float PCM"; + anzahlBytesProAbtastwert = 4; + break; + default: + throw new IllegalArgumentException(); + } + + switch (recorder.getChannelConfiguration()) { + case AudioFormat.CHANNEL_IN_MONO: + s = "Mono"; + break; + case AudioFormat.CHANNEL_IN_STEREO: + s = "Stereo"; + anzahlBytesProAbtastwert *= 2; + break; + case AudioFormat.CHANNEL_INVALID: + s = "ungültig"; + break; + default: + throw new IllegalArgumentException(); + } + + } + + + @Override + protected Void doInBackground(Long... params) { + + recorder.startRecording(); + short[] puffer = new short[pufferGroesseInBytes / 2]; + long lastTime = System.currentTimeMillis(); + float verarbeitungsrate = 0; + final int maxZaehlerZeitMessung = 10; + int zaehlerZeitMessung = 0; + int anzahlVerarbeitet = 0; + GleitenderMittelwert gleitenderMittelwert = new GleitenderMittelwert(0.3f); + GleitenderMittelwert gleitenderMittelwertdB = new GleitenderMittelwert(0.1f); + float db = 0; + boolean erlaubt_rise = true; + boolean erlaubt_fall = true; + + + + for (; ; ) { + if (isCancelled()) { + break; + } else { + int n = recorder.read(puffer, 0, puffer.length); + Verarbeitungsergebnis ergebnis = verarbeiten(puffer, n); + anzahlVerarbeitet += n; + + //kalibrierung + if(kalibrierung_do){ + // Warten für 3 Sekunden + /*long startTime = System.currentTimeMillis(); // Startzeit + while (System.currentTimeMillis() - startTime < 3000) { + //Warten + }*/ + //3s warten auf weitere Ausführung + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + //int z = recorder.read(puffer, 0, puffer.length); + //Verarbeitungsergebnis kalibrierung = verarbeiten(puffer, z); + int anzahlIterationen = 3000; + float sum = 0; + for(int i = 0; i < anzahlIterationen; i++){ + sum += ergebnis.db; + } + threshold = sum/anzahlIterationen; + kalibrierung_do = false; + } + + + zaehlerZeitMessung++; + if (zaehlerZeitMessung == maxZaehlerZeitMessung) { + long time = System.currentTimeMillis(); + long deltaTime = time - lastTime; + verarbeitungsrate = 1000.0f * anzahlVerarbeitet / deltaTime; + verarbeitungsrate = gleitenderMittelwert.mittel(verarbeitungsrate); + zaehlerZeitMessung = 0; + anzahlVerarbeitet = 0; + lastTime = time; + } + + db = (float) ergebnis.db; + db = gleitenderMittelwertdB.mittel(db); + ergebnis.db = (int) db; + ergebnis.verarbeitungsrate = (int) verarbeitungsrate; + + //Hysterese beim Setzen bzw. Rücksetzen ob detektiert + //beim ersten detektieren wird Zeitpunkt gespeichert + if(ergebnis.db >= (threshold+sensitivity)){ + detection_mic = true; + erlaubt_fall = true; + while(erlaubt_rise){ + erlaubt_rise = false; + zeit = Zeitpunkt() + " - " + ergebnis.db + " - " + (threshold+sensitivity); //Überschreiben des Zeitpunkts beim Erkennen der Detektion + //nur zum Testen in zeit noch ergebnis.db und threshold ausgegeben -> muss am Ende nur Zeitpunkt() rein, Rest weg + } + } else if (ergebnis.db <= (threshold)) { + detection_mic = false; + erlaubt_rise = true; + while(erlaubt_fall){ + erlaubt_fall = false; + zeit = Zeitpunkt(); //erneutes Überschreiben des Zeitpunkts beim Verschwinden der Detektion + } + } + + publishProgress(ergebnis); + + + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + recorder.release(); + return null; + } + + private Verarbeitungsergebnis verarbeiten(short[] daten, int n) { + String status; + short maxAmp = -1; + int db = 0; + + if (n == AudioRecord.ERROR_INVALID_OPERATION) { + status = "ERROR_INVALID_OPERATION"; + } else if (n == AudioRecord.ERROR_BAD_VALUE) { + status = "ERROR_BAD_VALUE"; + } else { + status = "OK"; + short max = 0; + for (int i = 0; i < n; i++) { + if (daten[i] > max) { + max = daten[i]; + } + } + ringPuffer.hinzufuegen(max); + maxAmp = ringPuffer.maximum(); + } + //Umwandlung Amplitudenwert in dB + db = (int) (20*Math.log10(maxAmp)); + + return new Verarbeitungsergebnis(status, maxAmp,0, db); + } + + ///////////////////////////////////////////// + @Override + protected void onProgressUpdate(Verarbeitungsergebnis... progress) { + super.onProgressUpdate(progress); + + + System.out.println(detection_mic); + System.out.println(zeit); + textViewZeitstempel.setText(zeit); + + textViewMaxAmpdb.setText("" + progress[0].db); + textViewMaxAmp.setText("" + progress[0].maxAmp); + + } + } + ///////////////////////////////////////////// + class Verarbeitungsergebnis { + String status; + short maxAmp; + int db; + int verarbeitungsrate; + + Verarbeitungsergebnis(String status, short maxAmp, int verarbeitungsrate, int db) { + this.status = status; + this.maxAmp = maxAmp; + this.db = db; + this.verarbeitungsrate = verarbeitungsrate; + } + } + + class RingPuffer { + private short[] puffer; + private final int laenge; + private int anzahlEnthaltenerDaten; + private int position; + + public RingPuffer(int n) { + laenge = n; + anzahlEnthaltenerDaten = 0; + position = 0; + puffer = new short[laenge]; + } + + public void hinzufuegen(short wert) { + puffer[position] = wert; + position++; + if (position >= laenge) { + position = 0; + } + if (anzahlEnthaltenerDaten < laenge) { + anzahlEnthaltenerDaten++; + } + } + + public void hinzufuegen(short[] daten) { + for (short d : daten) { + puffer[position] = d; + position++; + if (position >= laenge) { + position = 0; + } + } + if (anzahlEnthaltenerDaten < laenge) { + anzahlEnthaltenerDaten += daten.length; + if (anzahlEnthaltenerDaten >= laenge) { + anzahlEnthaltenerDaten = laenge; + } + } + } + + public short maximum() { + short max = 0; + for (int i = 0; i < anzahlEnthaltenerDaten; i++) { + if (puffer[i] > max) { + max = puffer[i]; + } + } + return max; + } + + public float mittelwert() { + float summe = 0; + for (int i = 0; i < anzahlEnthaltenerDaten; i++) { + summe += puffer[i]; + } + return summe / anzahlEnthaltenerDaten; + } + } + + class GleitenderMittelwert { + private final float wichtungNeuerWert; + private final float wichtungAlterWert; + private float mittelwert = 0; + private boolean istMittelwertGesetzt = false; + + GleitenderMittelwert(float wichtungNeuerWert) { + this.wichtungNeuerWert = wichtungNeuerWert; + this.wichtungAlterWert = 1 - this.wichtungNeuerWert; + } + + float mittel(float wert) { + if (istMittelwertGesetzt) { + mittelwert = wert * wichtungNeuerWert + mittelwert * wichtungAlterWert; + } else { + mittelwert = wert; + istMittelwertGesetzt = true; + } + return mittelwert; + } + + + } + + + @Override + protected void onResume() { + super.onResume(); + if (sens != null) { + if (bsmanager.registerListener(this, sens, SensorManager.SENSOR_DELAY_GAME)) { + Daten = "Wir haben uns beim Sensor angemeldet"; + } else { + Daten = "Das anmelden hat nicht geklappt"; + } + SharedPreferences p = getPreferences(Context.MODE_PRIVATE); + threshold = p.getFloat(KEY_WERT, 40); + kalibrierung_do = p.getBoolean(KEY_KALIBRIERUNG, true); + + if (!istZugriffAufMikrofonErlaubt()) { + zugriffAufMikrofonAnfordern(); + } + if (istZugriffAufMikrofonErlaubt()) { + aufnahmeTask = new AufnahmeTask(); + aufnahmeTask.execute(); + } + }} + + @Override + protected void onPause () { + super.onPause(); + if (sens != null) { + bsmanager.unregisterListener(this, sens); + } + SharedPreferences p = getPreferences(Context.MODE_PRIVATE); + SharedPreferences.Editor editor = p.edit(); + editor.putFloat(KEY_WERT, threshold); + if(isFinishing()==true){ + editor.putBoolean(KEY_KALIBRIERUNG, true); //? + }else { + editor.putBoolean(KEY_KALIBRIERUNG, false); + } + editor.commit(); + if(aufnahmeTask!=null) { + aufnahmeTask.cancel(true); + aufnahmeTask = null; + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 1947c8f..3ce0ca9 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -31,6 +31,12 @@ android:layout_height="wrap_content" android:text="Beschleunigungssensor" /> +