diff --git a/app/build.gradle b/app/build.gradle index 59d5a4a..3731623 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -57,5 +57,5 @@ android { dependencies { testImplementation 'junit:junit:4.12' - implementation 'com.github.axet:android-audio-library:1.0.140' // implementation project(':android-audio-library') + implementation 'com.github.axet:android-audio-library:1.0.141' // implementation project(':android-audio-library') } diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java index 8010273..ede24ef 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java @@ -8,6 +8,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.media.AudioFormat; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -23,17 +24,17 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; +import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toast; import com.github.axet.androidlibrary.animations.MarginBottomAnimation; -import com.github.axet.androidlibrary.app.SuperUser; import com.github.axet.androidlibrary.sound.AudioTrack; import com.github.axet.androidlibrary.widgets.AppCompatThemeActivity; import com.github.axet.androidlibrary.widgets.ErrorDialog; import com.github.axet.androidlibrary.widgets.OpenFileDialog; +import com.github.axet.androidlibrary.widgets.Toast; import com.github.axet.audiolibrary.app.RawSamples; import com.github.axet.audiolibrary.app.Sound; import com.github.axet.audiolibrary.encoders.Factory; @@ -85,7 +86,13 @@ public class RecordingActivity extends AppCompatThemeActivity { View done; PitchView pitch; + ScreenReceiver screen; + + AudioApplication.RecordingStorage recording; + RecordingReceiver receiver; + + AlertDialog muted; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { @@ -93,15 +100,57 @@ public class RecordingActivity extends AppCompatThemeActivity { pitch.add((Double) msg.obj); if (msg.what == AudioApplication.RecordingStorage.UPDATESAMPLES) updateSamples((Long) msg.obj); - if (msg.what == AudioApplication.RecordingStorage.END) + if (msg.what == AudioApplication.RecordingStorage.MUTED) { + if (Build.VERSION.SDK_INT >= 28) + muted = new ErrorDialog(RecordingActivity.this, getString(R.string.mic_muted_pie)).setTitle(getString(R.string.mic_muted_error)).show(); + else + muted = ErrorDialog.Error(RecordingActivity.this, getString(R.string.mic_muted_error)); + RecordingActivity.startActivity(RecordingActivity.this, true); + } + if (msg.what == AudioApplication.RecordingStorage.UNMUTED) { + if (muted != null) { + Runnable run = new Runnable() { + int count = 5; + AlertDialog d = muted; + + @Override + public void run() { + if (count <= 0) { + d.dismiss(); + return; + } + Button b = d.getButton(DialogInterface.BUTTON_NEUTRAL); + b.setText(getString(R.string.auto_close, count)); + b.setVisibility(View.VISIBLE); + b.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + } + }); + count--; + handler.postDelayed(this, 1000); + } + }; + run.run(); + muted = null; + } + } + if (msg.what == AudioApplication.RecordingStorage.END) { pitch.drawEnd(); + if (!recording.interrupt.get()) { + stopRecording(getString(R.string.recording_status_pause)); + String text = "Error reading from stream"; + if (Build.VERSION.SDK_INT >= 28) + new ErrorDialog(RecordingActivity.this, getString(R.string.mic_muted_pie)).setTitle(text).show(); + else + ErrorDialog.Error(RecordingActivity.this, getString(R.string.mic_muted_error)); + RecordingActivity.startActivity(RecordingActivity.this, true); + } + } if (msg.what == AudioApplication.RecordingStorage.ERROR) Error((Exception) msg.obj); } }; - ScreenReceiver screen; - - AudioApplication.RecordingStorage recording; public static void startActivity(Context context, boolean pause) { Log.d(TAG, "startActivity"); @@ -144,22 +193,6 @@ public class RecordingActivity extends AppCompatThemeActivity { done.performClick(); return; } - if (a.equals(AudioApplication.RecordingStorage.PINCH)) { - pitch.add(intent.getDoubleExtra("data", 0)); - return; - } - if (a.equals(AudioApplication.RecordingStorage.UPDATESAMPLES)) { - updateSamples(intent.getLongExtra("data", 0)); - return; - } - if (a.equals(AudioApplication.RecordingStorage.END)) { - pitch.drawEnd(); - return; - } - if (a.equals(AudioApplication.RecordingStorage.ERROR)) { - Error((Throwable) intent.getSerializableExtra("data")); - return; - } MediaButtonReceiver.handleIntent(msc, intent); } } @@ -202,7 +235,7 @@ public class RecordingActivity extends AppCompatThemeActivity { if (t == null) t = e; } - return SuperUser.toMessage(t); + return ErrorDialog.toMessage(t); } public void Error(Throwable e) { @@ -278,9 +311,7 @@ public class RecordingActivity extends AppCompatThemeActivity { receiver.filter.addAction(ACTION_FINISH_RECORDING); receiver.registerReceiver(this); - final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); AudioApplication app = AudioApplication.from(this); - try { if (app.recording == null) app.recording = new AudioApplication.RecordingStorage(this, pitch.getPitchTime()); @@ -290,7 +321,7 @@ public class RecordingActivity extends AppCompatThemeActivity { } } catch (RuntimeException e) { Log.d(TAG, "onCreate", e); - Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); + Toast.Error(this, e); finish(); return; } @@ -299,6 +330,7 @@ public class RecordingActivity extends AppCompatThemeActivity { title.setText(Storage.getName(this, recording.targetUri)); + final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); if (shared.getBoolean(AudioApplication.PREFERENCE_CALL, false)) { TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); tm.listen(pscl, PhoneStateListener.LISTEN_CALL_STATE); @@ -730,6 +762,7 @@ public class RecordingActivity extends AppCompatThemeActivity { final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences.Editor editor = shared.edit(); editor.remove(AudioApplication.PREFERENCE_TARGET); + editor.commit(); } void startRecording() { diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java index 5007fd3..35143d1 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java @@ -58,7 +58,7 @@ public class SettingsActivity extends AppCompatSettingsThemeActivity implements public static final int RESULT_STORAGE = 1; public static final int RESULT_CALL = 2; - Handler handler = new Handler(); + Storage storage = new Storage(this); public static String[] PREMS = new String[]{Manifest.permission.READ_PHONE_STATE}; @@ -197,7 +197,7 @@ public class SettingsActivity extends AppCompatSettingsThemeActivity implements } } if (key.equals(AudioApplication.PREFERENCE_STORAGE)) { - Storage.migrateLocalStorageDialog(this, handler, new Storage(this)); + storage.migrateLocalStorageDialog(); } if (key.equals(AudioApplication.PREFERENCE_RATE)) { int sampleRate = Integer.parseInt(sharedPreferences.getString(AudioApplication.PREFERENCE_RATE, "")); diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/AudioApplication.java b/app/src/main/java/com/github/axet/audiorecorder/app/AudioApplication.java index 5843d7f..edc551e 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/app/AudioApplication.java +++ b/app/src/main/java/com/github/axet/audiorecorder/app/AudioApplication.java @@ -36,6 +36,7 @@ import com.github.axet.audiorecorder.services.RecordingService; import java.io.File; import java.nio.ShortBuffer; import java.util.ArrayList; +import java.util.Arrays; import java.util.Locale; import java.util.concurrent.atomic.AtomicBoolean; @@ -59,6 +60,8 @@ public class AudioApplication extends com.github.axet.audiolibrary.app.MainAppli public static final int UPDATESAMPLES = 2; public static final int END = 3; public static final int ERROR = 4; + public static final int MUTED = 5; + public static final int UNMUTED = 6; public Context context; public final ArrayList handlers = new ArrayList<>(); @@ -191,6 +194,9 @@ public class AudioApplication extends com.github.axet.audiolibrary.app.MainAppli android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO); + boolean silenceDetected = false; + long silence = samplesTime; // last silence 0-frame + try { long start = System.currentTimeMillis(); recorder.startRecording(); @@ -242,6 +248,11 @@ public class AudioApplication extends com.github.axet.audiolibrary.app.MainAppli } readSizeUpdate = dbSize / samplesUpdateStereo * samplesUpdateStereo; for (int i = 0; i < readSizeUpdate; i += samplesUpdateStereo) { + for (int k = 0; k < samplesUpdateStereo; k++) { + int off = i + k; + if (dbBuf[off] != 0) + silence = samplesTime + off / Sound.getChannels(context); + } double dB = RawSamples.getDB(dbBuf, i, samplesUpdateStereo); Post(PINCH, dB); } @@ -260,6 +271,16 @@ public class AudioApplication extends com.github.axet.audiolibrary.app.MainAppli Post(UPDATESAMPLES, m); samplesTimeCount -= samplesTimeUpdate; } + + if (samplesTime - silence > 2 * sampleRate) { // 2 second of mic muted + if (!silenceDetected) { + silenceDetected = true; + Post(MUTED, null); + } + } else { + Post(UNMUTED, null); + silenceDetected = false; + } } } } catch (final RuntimeException e) { @@ -335,6 +356,12 @@ public class AudioApplication extends com.github.axet.audiolibrary.app.MainAppli } } + public boolean isForeground() { + synchronized (bufferSizeLock) { + return bufferSize == this.samplesUpdate * Sound.getChannels(context); + } + } + public void Post(Exception e) { Post(ERROR, e); } diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java b/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java index 2801a7b..f4912fc 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java +++ b/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java @@ -23,6 +23,7 @@ public class Storage extends com.github.axet.audiolibrary.app.Storage { super(context); } + @Override public Uri getNewFile() { SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context); String ext = shared.getString(AudioApplication.PREFERENCE_ENCODING, ""); @@ -36,9 +37,9 @@ public class Storage extends com.github.axet.audiolibrary.app.Storage { Uri path = getStoragePath(); String s = path.getScheme(); - if (Build.VERSION.SDK_INT >= 21 && s.startsWith(ContentResolver.SCHEME_CONTENT)) { + if (Build.VERSION.SDK_INT >= 21 && s.equals(ContentResolver.SCHEME_CONTENT)) { return getNextFile(context, path, format, ext); - } else if (s.startsWith(ContentResolver.SCHEME_FILE)) { + } else if (s.equals(ContentResolver.SCHEME_FILE)) { File f = getFile(path); if (!f.exists() && !f.mkdirs()) throw new RuntimeException("Unable to create: " + path); diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 66b6213..747ca4e 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -67,4 +67,7 @@ pause (bluetooth disconnected) Search Save as WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index edfefd2..9174425 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -61,4 +61,7 @@ παύση (αποσύνδεση bluetooth) Αναζήτηση Save as WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 0254b95..ea95c66 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -67,4 +67,7 @@ pausar (bluetooth desconectado) Buscar Guardar como WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 7ea4552..8556288 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -67,4 +67,7 @@ pause (bluetooth disconnected) Search Save as WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index b0eade6..9acc6cc 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -67,4 +67,7 @@ jeda (bluetooth terputus) Cari Simpan sebagai WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 48d6d2e..e923b68 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -67,4 +67,7 @@ pause (bluetooth disconnected) Search Save as WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 68c0991..ecef4f5 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -67,4 +67,7 @@ pause (bluetooth disconnected) Search Save as WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 759575f..1d38aae 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -67,4 +67,7 @@ pauza (bluetooth rozłaczony) Szukaj Zapisz jako WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 4b81293..63c48dc 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -67,4 +67,7 @@ pause (bluetooth disconnected) Search Save as WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 9307d66..da00e03 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -67,4 +67,7 @@ Кодирование на лету отключает редактирование и восстановление в случае ошибок Поиск Save as WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 1e128dc..a72fa6d 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -69,4 +69,7 @@ Pozastavené (odpojené bluetooth) Hľadať Uložiť vo formáte WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values-zh-rCH/strings.xml b/app/src/main/res/values-zh-rCH/strings.xml index f0483ff..f9abea7 100644 --- a/app/src/main/res/values-zh-rCH/strings.xml +++ b/app/src/main/res/values-zh-rCH/strings.xml @@ -67,4 +67,7 @@ 暂停 (蓝牙未连接) 搜索 另存为WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version! diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c1fbdbd..4194e73 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,4 +67,7 @@ pause (bluetooth disconnected) Search Save as WAV + Auto close in (%1$d) + Mic muted + Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version!