diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index dd513a7..ff2c6a0 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,16 +1,17 @@ # Translations - * japanese translation thanks to @naofumi - * german translation thanks to @s72785 - * brazilian translation thanks to @vrozsas - * itallian tralslation thanks to @Agno94 - * slovak translation thanks to @pvagner - * french thanks to @Nonot - * turkish thanks to @tneonflo - * spanish thanks to @sguinetti - * greek tanks to @cryoranger - * Indonesian thanks to @ditokp, @zmni - * polish thanks to @krkk - * Chinese thanks to @itoy + * Chinese translation thanks to @itoy * Chinese (Taiwan) translation thanks to @cges30901 + * Brazilian translation thanks to @vrozsas * Danish translation thanks to @lianergoist + * Dutch translation thanks to @Stephan-P + * French translation thanks to @Nonot + * German translation thanks to @s72785 + * Greek translation thanks to @cryoranger + * Indonesian translation thanks to @ditokp, @zmni + * Italian translation thanks to @Agno94 + * Japanese translation thanks to @naofumi + * Polish translation thanks to @krkk + * Slovak translation thanks to @pvagner + * Spanish translation thanks to @sguinetti + * Turkish translation thanks to @tneonflo diff --git a/README.md b/README.md index 3975dd1..302d477 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,4 @@ If you want to translate 'Audio Recorder' to your language please read this: # Screenshots -![shot](/docs/shot.png) +![screenshot1](./metadata/screenshots/screenshot1.png) diff --git a/app/build.gradle b/app/build.gradle index dbaeeb3..0ceceb5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "com.github.axet.audiorecorder" minSdkVersion 9 targetSdkVersion 31 - versionCode 377 - versionName "3.5.21" + versionCode 378 + versionName "3.5.22" } signingConfigs { release { @@ -53,7 +53,7 @@ android { dependencies { testImplementation 'junit:junit:4.12' - implementation ('com.github.axet:android-audio-library:1.1.23') // implementation project(':android-audio-library') + implementation ('com.github.axet:android-audio-library:1.1.24') // implementation project(':android-audio-library') implementation ('com.github.axet:wget:1.7.0') { exclude group: 'org.json', module: 'json' } - assets('com.google.android.exoplayer:exoplayer:2.7.3') { exclude group: 'com.android.support' } + assets('com.github.axet.exoplayer:exoplayer:2.7.3') { exclude group: 'com.android.support' } } diff --git a/app/src/androidTest/java/com/github/axet/audiorecorder/ApplicationTest.java b/app/src/androidTest/java/com/github/axet/audiorecorder/ApplicationTest.java deleted file mode 100644 index df0797a..0000000 --- a/app/src/androidTest/java/com/github/axet/audiorecorder/ApplicationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.axet.audiorecorder; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } - - public void testFFT() { - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e490927..516f560 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,15 +23,18 @@ android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher" android:supportsRtl="true" - android:theme="@style/Translucent"> - + android:theme="@android:style/Theme.Translucent.NoTitleBar"> + + android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"> @@ -39,14 +42,15 @@ + android:label="@string/app_name" + android:theme="@android:style/Theme.Translucent.NoTitleBar" /> + android:theme="@android:style/Theme.Translucent.NoTitleBar"> @@ -62,7 +66,8 @@ android:configChanges="orientation|keyboardHidden|screenSize" android:exported="true" android:launchMode="singleInstance" - android:showOnLockScreen="true"> + android:showOnLockScreen="true" + android:theme="@android:style/Theme.Translucent.NoTitleBar"> @@ -79,14 +84,18 @@ - + - + diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java index b85f0b5..df0815e 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java @@ -35,6 +35,7 @@ import android.widget.Toast; import com.github.axet.androidlibrary.activities.AppCompatThemeActivity; import com.github.axet.androidlibrary.preferences.AboutPreferenceCompat; import com.github.axet.androidlibrary.preferences.OptimizationPreferenceCompat; +import com.github.axet.androidlibrary.preferences.ScreenlockPreference; import com.github.axet.androidlibrary.services.StorageProvider; import com.github.axet.androidlibrary.widgets.ErrorDialog; import com.github.axet.androidlibrary.widgets.OpenFileDialog; @@ -54,6 +55,7 @@ import com.github.axet.audiorecorder.services.RecordingService; import org.json.JSONException; import java.io.File; +import java.io.IOException; public class MainActivity extends AppCompatThemeActivity { public final static String TAG = MainActivity.class.getSimpleName(); @@ -398,7 +400,7 @@ public class MainActivity extends AppCompatThemeActivity { @Override public int getAppTheme() { - return AudioApplication.getTheme(this, R.style.RecThemeLight_NoActionBar, R.style.RecThemeDark_NoActionBar); + return AudioApplication.getTheme(this, R.style.RecThemeLight_NoActionBar, R.style.RecThemeDark_NoActionBar, R.style.RecThemeDarkBlack_NoActionBar); } @Override @@ -488,8 +490,7 @@ public class MainActivity extends AppCompatThemeActivity { getMenuInflater().inflate(R.menu.menu_main, menu); - KeyguardManager myKM = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); - if (myKM.inKeyguardRestrictedInputMode()) + if (ScreenlockPreference.isLocked(this)) menu.findItem(R.id.action_settings).setVisible(false); MenuItem item = menu.findItem(R.id.action_show_folder); @@ -513,11 +514,10 @@ public class MainActivity extends AppCompatThemeActivity { return false; } }); - searchView.setOnCloseListener(new SearchView.OnCloseListener() { + searchView.setOnCollapsedListener(new SearchView.OnCollapsedListener() { @Override - public boolean onClose() { + public void onCollapsed() { recordings.searchClose(); - return true; } }); @@ -636,7 +636,7 @@ public class MainActivity extends AppCompatThemeActivity { if (Storage.permitted(MainActivity.this, permissions)) { try { storage.migrateLocalStorage(); - } catch (RuntimeException e) { + } catch (RuntimeException | IOException e) { ErrorDialog.Error(MainActivity.this, e); } recordings.load(false, null); 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 66bcb3d..d8439aa 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 @@ -10,8 +10,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Rect; -import android.media.AudioFormat; -import android.media.MediaRecorder; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -22,7 +20,6 @@ import android.provider.MediaStore; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.view.WindowCallbackWrapper; -import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.DisplayMetrics; import android.util.Log; @@ -38,6 +35,7 @@ import android.widget.TextView; import com.github.axet.androidlibrary.activities.AppCompatThemeActivity; import com.github.axet.androidlibrary.animations.MarginBottomAnimation; +import com.github.axet.androidlibrary.app.PhoneStateChangeListener; import com.github.axet.androidlibrary.services.FileProvider; import com.github.axet.androidlibrary.services.StorageProvider; import com.github.axet.androidlibrary.sound.AudioTrack; @@ -61,12 +59,7 @@ import com.github.axet.audiorecorder.services.EncodingService; import com.github.axet.audiorecorder.services.RecordingService; import java.io.File; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.nio.ShortBuffer; -import java.util.concurrent.Executor; +import java.io.IOException; public class RecordingActivity extends AppCompatThemeActivity { public static final String TAG = RecordingActivity.class.getSimpleName(); @@ -86,7 +79,7 @@ public class RecordingActivity extends AppCompatThemeActivity { public static final String START_RECORDING = RecordingService.class.getCanonicalName() + ".START_RECORDING"; public static final String STOP_RECORDING = RecordingService.class.getCanonicalName() + ".STOP_RECORDING"; - PhoneStateChangeListener pscl = new PhoneStateChangeListener(); + PhoneStateChangeListener pscl; Headset headset; Intent recordSoundIntent = null; @@ -300,65 +293,29 @@ public class RecordingActivity extends AppCompatThemeActivity { } } - class PhoneStateChangeListener extends PhoneStateListener { - public boolean wasRinging; + class PhoneStateChangeListener extends com.github.axet.androidlibrary.app.PhoneStateChangeListener { public boolean pausedByCall; - @TargetApi(31) - TelephonyCallback e; - @TargetApi(31) - public class TelephonyCallback extends android.telephony.TelephonyCallback implements android.telephony.TelephonyCallback.CallStateListener { - @Override - public void onCallStateChanged(int i) { - PhoneStateChangeListener.this.onCallStateChanged(i, ""); - } + public PhoneStateChangeListener(Context context) { + super(context); } - public void create() { - Context context = RecordingActivity.this; - TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - if (Build.VERSION.SDK_INT >= 31 && getApplicationInfo().targetSdkVersion >= 31) { - if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { - e = new TelephonyCallback(); - tm.registerTelephonyCallback(getMainExecutor(), e); - } - } else { - tm.listen(this, PhoneStateListener.LISTEN_CALL_STATE); - } - } - - public void close() { - Context context = RecordingActivity.this; - TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - if (Build.VERSION.SDK_INT >= 31 && getApplicationInfo().targetSdkVersion >= 31) { - if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) - tm.unregisterTelephonyCallback(e); - } else { - tm.listen(this, PhoneStateListener.LISTEN_NONE); + @Override + public void onAnswered() { + super.onAnswered(); + if (recording.thread != null) { + stopRecording(getString(R.string.hold_by_call), false); + pausedByCall = true; } } @Override - public void onCallStateChanged(int s, String incomingNumber) { - switch (s) { - case TelephonyManager.CALL_STATE_RINGING: - wasRinging = true; - break; - case TelephonyManager.CALL_STATE_OFFHOOK: - wasRinging = true; - if (recording.thread != null) { - stopRecording(getString(R.string.hold_by_call), false); - pausedByCall = true; - } - break; - case TelephonyManager.CALL_STATE_IDLE: - if (pausedByCall) { - if (receiver.isRecordingReady()) - ; // startRecording(); - } - wasRinging = false; - pausedByCall = false; - break; + public void onIdle() { + super.onIdle(); + if (pausedByCall) { +// if (receiver.isRecordingReady()) +// startRecording(); + pausedByCall = false; } } } @@ -413,7 +370,7 @@ public class RecordingActivity extends AppCompatThemeActivity { @Override public int getAppTheme() { - return AudioApplication.getTheme(this, R.style.RecThemeLight, R.style.RecThemeDark); + return AudioApplication.getTheme(this, R.style.RecThemeLight, R.style.RecThemeDark, R.style.RecThemeDarkBlack); } @Override @@ -439,6 +396,7 @@ public class RecordingActivity extends AppCompatThemeActivity { receiver.filter.addAction(ACTION_FINISH_RECORDING); receiver.registerReceiver(this); + pscl = new PhoneStateChangeListener(this); final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); if (shared.getBoolean(AudioApplication.PREFERENCE_CALL, false)) pscl.create(); 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 9616ae7..b0c83bb 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 @@ -60,7 +60,7 @@ public class SettingsActivity extends AppCompatSettingsThemeActivity implements @Override public int getAppTheme() { - return AudioApplication.getTheme(this, R.style.RecThemeLight, R.style.RecThemeDark); + return AudioApplication.getTheme(this, R.style.RecThemeLight, R.style.RecThemeDark, R.style.RecThemeDarkBlack); } @Override diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/EncodingStorage.java b/app/src/main/java/com/github/axet/audiorecorder/app/EncodingStorage.java index 26ed56d..ab541f1 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/app/EncodingStorage.java +++ b/app/src/main/java/com/github/axet/audiorecorder/app/EncodingStorage.java @@ -22,6 +22,7 @@ import org.json.JSONObject; import java.io.File; import java.io.FilenameFilter; +import java.io.IOException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; @@ -201,8 +202,8 @@ public class EncodingStorage extends HashMap { }, new Runnable() { @Override public void run() { // or error - Storage.delete(storage.getContext(), fly.targetUri); // fly has fd, delete target manually try { + Storage.delete(storage.getContext(), fly.targetUri); // fly has fd, delete target manually Intent intent = new Intent() .putExtra("in", encoder.in) .putExtra("info", info.save().toString()) diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/RecordingStorage.java b/app/src/main/java/com/github/axet/audiorecorder/app/RecordingStorage.java index db10e9c..9270ed5 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/app/RecordingStorage.java +++ b/app/src/main/java/com/github/axet/audiorecorder/app/RecordingStorage.java @@ -1,6 +1,5 @@ package com.github.axet.audiorecorder.app; -import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.media.AudioFormat; @@ -18,20 +17,8 @@ import com.github.axet.audiolibrary.app.Sound; import com.github.axet.audiolibrary.encoders.Encoder; import com.github.axet.audiolibrary.encoders.OnFlyEncoding; import com.github.axet.audiorecorder.BuildConfig; -import com.github.axet.audiorecorder.R; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.FilenameUtils; -import org.json.JSONException; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Locale; import java.util.concurrent.atomic.AtomicBoolean; public class RecordingStorage { @@ -78,7 +65,7 @@ public class RecordingStorage { info = new RawSamples.Info(format, sampleRate, Sound.getChannels(context)); } - public void startRecording(int source) { + public void startRecording(final int source) { final SharedPreferences shared = android.preference.PreferenceManager.getDefaultSharedPreferences(context); sound.silent(); @@ -240,17 +227,20 @@ public class RecordingStorage { } session += samples; - if (samplesTime - silence > 2 * sampleRate) { // 2 second of mic muted - if (!silenceDetected) { - silenceDetected = true; - Post(MUTED, null); - } - } else { - if (silenceDetected) { - silenceDetected = false; - Post(UNMUTED, null); + if (source != Sound.SOURCE_INTERNAL_AUDIO) { + if (samplesTime - silence > 2 * sampleRate) { // 2 second of mic muted + if (!silenceDetected) { + silenceDetected = true; + Post(MUTED, null); + } + } else { + if (silenceDetected) { + silenceDetected = false; + Post(UNMUTED, null); + } } } + diff = (now - start) * sampleRate / 1000; // number of samples we expect by this moment if (diff - session > 2 * sampleRate) { // 2 second of silence / paused by os Post(PAUSED, null); 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 1676ca6..685b4bf 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 @@ -10,6 +10,8 @@ import android.preference.PreferenceManager; import com.github.axet.androidlibrary.services.StorageProvider; import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -135,7 +137,7 @@ public class Storage extends com.github.axet.audiolibrary.app.Storage { } @Override - public void migrateLocalStorage() { + public void migrateLocalStorage() throws IOException { super.migrateLocalStorage(); deleteTmp(); } diff --git a/app/src/main/res/raw-nl/about.html b/app/src/main/res/raw-nl/about.html new file mode 100644 index 0000000..00a4c96 --- /dev/null +++ b/app/src/main/res/raw-nl/about.html @@ -0,0 +1,23 @@ + + + + + + +

Over

+

+ Android-vriendelijk! +

+ +

Audio Recorder met aangepaste map voor opnames, fraaie indicatie van opnamevolume, opnamemelding, opname-activiteit op het vergrendelingsscherm.

+ +
+
Licentie:
+
GPLv3
+
Broncode:
+
https://gitlab.com/axet/android-audio-recorder
+
+ + diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml new file mode 100644 index 0000000..a7e5114 --- /dev/null +++ b/app/src/main/res/values-nl/strings.xml @@ -0,0 +1,74 @@ + + Audio Recorder + + + 48 kHz + 44.1 kHz (CD) + 32 kHz + 22 kHz + 16 kHz (standaard) + 11 kHz + 8 kHz (telefoon) + + + + Microfoon + Onbewerkt + Bluetooth + Interne audio + + + + Mono (standaard) + Stereo + + + Geen app voor bestandsbeheer beschikbaar + pauzeren (onderbreking bij oproep) + opname + coderen + pauze + bewerken + Annulering bevestigen + Coderen… + Pauzeren… + Opname + Map met opnames openen + Opnamelijst is leeg\n\nKlik om een opname te starten + Opname + Knippen + Stoppen + Annuleren + Pauzeren + + Map met opnames + Samplerate + Codering + Uitvoerformaat (.wav, .m4a, …) + Audiokanalen + Opnamekanalen + Bestandsnaam-opmaak + Pauzeren tijdens oproep + Stop de opname bij een oproep en hervat deze bij het ophangen + Stille modus + \'Stille modus\' activeren tijdens opname + Bediening op vergrendelingsscherm + Bediening weergeven als de telefoon vergrendeld is + App-thema + App-thema instellen (donker/licht) + Applicatie + Opnames + Direct coderen + Met Direct coderen is bewerking niet mogelijk, evenals herstel van een crash + pauze (bluetooth niet verbonden) + Zoeken + Opslaan als WAV + Automatisch sluiten in (%1$d) + Microfoon gedempt + Android 9 (Pie) en hoger verhinderen dat inactieve achtergrondapps de microfoon gebruiken. Schakel SeLinux uit of downgrade naar een eerdere Android-release! + De microfoon is door Android gepauzeerd. De opnametijd is korter dan de geregistreerde gegevens. Controleer of jouw apparaat opnames in de achtergrond ondersteunt of dat het krachtig genoeg is voor de geselecteerde instellingen + Opname starten + Opname beëindigen + Achtergrondcodering onderbroken door Android-batterijoptimalisatie. Sta toe dat deze applicatie in de achtergrond kan werken + /s + diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 62871fc..6a3b014 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -28,7 +28,7 @@ 16-bit PCM - 24-bit PCM (float) + 32-bit float diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 657e03b..8320de5 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -6,20 +6,31 @@ #b1b1b1 + + - - + + + + diff --git a/app/src/test/java/com/github/axet/audiorecorder/ExampleUnitTest.java b/app/src/test/java/com/github/axet/audiorecorder/ExampleUnitTest.java deleted file mode 100644 index 7c4e1fa..0000000 --- a/app/src/test/java/com/github/axet/audiorecorder/ExampleUnitTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.axet.audiorecorder; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * To work on unit tests, switch the Test Artifact in the Build Variants view. - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index c257577..9a7f85b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -32,16 +32,18 @@ For example: # Raw format - * Signed 16-bit PCM or float (depends on user settings) +Temporary recordings stored inside application specific data folders (described in Recording locations) with following format: + + * Signed 16-bit PCM (2 bytes) or (4 bytes) Float (depends on Settings/Audio Format user setup) * Big Endian - * 1 or 2 channels (depends on user settings). First 2 bytes for left channel, Second 2 bytes for right channel. + * 1 or 2 channels (depends on user settings). First 2/4 bytes for left channel, second 2/4 bytes for right channel. * 16hz to 48hz Sample Rate / Frequincy (depends on user settings) Android supports 16-bit PCM format or PCM float. Android recomends to use PCM float over 24-bit PCM format or 16-bit PCM if possible. * https://developer.android.com/reference/android/media/AudioFormat#encoding -float mantisa is 23 bits (plus sign bit and float point bits) persition in range from -1..1 can hold about 2130706431 unique numbers which is equivalent to 31 bits integer. When 24-bit PCM only gives you 2^24=16,777,216 unique values. +float mantisa is 23 bits (plus sign bit and float point bits) persition in range from -1..1 can hold about 2,130,706,431 unique numbers which is equivalent to 31 bits integer. When 24-bit PCM only gives you 2^24=16,777,216 unique values. # Adb commands diff --git a/docs/google-play-badge.png b/docs/google-play-badge.png deleted file mode 100644 index 877bf74..0000000 Binary files a/docs/google-play-badge.png and /dev/null differ diff --git a/docs/shot.png b/metadata/screenshots/screenshot1.png similarity index 100% rename from docs/shot.png rename to metadata/screenshots/screenshot1.png