diff --git a/.idea/SoundRecorder.iml b/.idea/SoundRecorder.iml
new file mode 100644
index 00000000..0c051b73
--- /dev/null
+++ b/.idea/SoundRecorder.iml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
new file mode 100644
index 00000000..970ec751
Binary files /dev/null and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml
new file mode 100644
index 00000000..7057d2dc
--- /dev/null
+++ b/.idea/checkstyle-idea.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/checkstyleidea-libs/readme.txt b/.idea/checkstyleidea-libs/readme.txt
new file mode 100644
index 00000000..236f70bc
--- /dev/null
+++ b/.idea/checkstyleidea-libs/readme.txt
@@ -0,0 +1,6 @@
+This folder contains libraries copied from the "SoundRecorder" project.
+It is managed by the CheckStyle-IDEA IDE plugin.
+Do not modify this folder while the IDE is running.
+When the IDE is stopped, you may delete this folder at any time. It will be recreated as needed.
+In order to prevent the CheckStyle-IDEA IDE plugin from creating this folder,
+uncheck the "Copy libraries from project directory" option in the CheckStyle-IDEA settings dialog.
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000..681f41ae
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ xmlns:android
+
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+
+ ^$
+
+
+
+
+
+
+
+
+ style
+
+ ^$
+
+
+
+
+
+
+
+
+ .*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+
+ http://schemas.android.com/apk/res/android
+
+
+ ANDROID_ATTRIBUTE_ORDER
+
+
+
+
+
+
+ .*
+
+ .*
+
+
+ BY_NAME
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 217af471..8144c3cf 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,8 +1,6 @@
-
-
@@ -13,11 +11,6 @@
-
-
-
-
-
+
-
-
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 2a7f5bfc..05ad11cd 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,8 +1,10 @@
+
+
@@ -13,6 +15,7 @@
+
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 2071d1a6..b4d29702 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -1,11 +1,7 @@
-
-
-
-
-
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 00000000..a2e5b526
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index b0a270f5..b39703e7 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,33 +1,51 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
index eb3197b3..ad0f22e6 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,8 +2,8 @@
-
-
+
+
\ No newline at end of file
diff --git a/.idea/modules/app/SoundRecorder-app.iml b/.idea/modules/app/SoundRecorder-app.iml
new file mode 100644
index 00000000..3a36b2be
--- /dev/null
+++ b/.idea/modules/app/SoundRecorder-app.iml
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ generateDebugSources
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules/app/SoundRecorder.app.iml b/.idea/modules/app/SoundRecorder.app.iml
new file mode 100644
index 00000000..f5254ff5
--- /dev/null
+++ b/.idea/modules/app/SoundRecorder.app.iml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ generateDebugSources
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules/app/app.iml b/.idea/modules/app/app.iml
new file mode 100644
index 00000000..eb9bbd9b
--- /dev/null
+++ b/.idea/modules/app/app.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/render.experimental.xml b/.idea/render.experimental.xml
new file mode 100644
index 00000000..8ec256a5
--- /dev/null
+++ b/.idea/render.experimental.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/shelf/Uncommitted_changes_before_Update_at_02_12_2020_15_45_[Default_Changelist]/build_file_checksums.ser b/.idea/shelf/Uncommitted_changes_before_Update_at_02_12_2020_15_45_[Default_Changelist]/build_file_checksums.ser
new file mode 100644
index 00000000..3ea183e4
Binary files /dev/null and b/.idea/shelf/Uncommitted_changes_before_Update_at_02_12_2020_15_45_[Default_Changelist]/build_file_checksums.ser differ
diff --git a/.idea/shelf/Uncommitted_changes_before_Update_at_02_12_2020_15_45_[Default_Changelist]/shelved.patch b/.idea/shelf/Uncommitted_changes_before_Update_at_02_12_2020_15_45_[Default_Changelist]/shelved.patch
new file mode 100644
index 00000000..e69de29b
diff --git a/.idea/shelf/Uncommitted_changes_before_Update_at_02_12_2020_15_45__Default_Changelist_.xml b/.idea/shelf/Uncommitted_changes_before_Update_at_02_12_2020_15_45__Default_Changelist_.xml
new file mode 100644
index 00000000..cf0d66e5
--- /dev/null
+++ b/.idea/shelf/Uncommitted_changes_before_Update_at_02_12_2020_15_45__Default_Changelist_.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index c63efbb2..94a25f7f 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,9 +1,6 @@
-
-
-
-
+
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..c6ee8fe9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,55 @@
+language: android
+
+android:
+ components:
+ - tools
+ - build-tools-29.0.2
+ - android-21
+ # Additional components
+ - extra-android-support
+ - extra-android-m2repository
+ - extra-google-m2repository
+
+# Save time not downloading dependencies ad every build
+cache:
+ directories:
+ ~/.gradle/caches/
+ ~/.gradle/wrapper/
+
+addons:
+ apt:
+ packages:
+ - lynx
+
+before_install:
+ - chmod +x ./gradlew
+ - yes | sdkmanager "platforms;android-21"
+
+stages:
+ - compile
+ - static_analysis
+ - test
+
+jobs:
+ include:
+ - stage: compile
+ name: "Compile"
+ script: ./gradlew build
+ - stage: static_analysis
+ name: "Checkstyle analysis"
+ script: ./gradlew checkstyle
+ after_success: lynx -dump file:///home/travis/build/assuntaDC/SoundRecorder/app/build/reports/checkstyle/checkstyle.html
+ - script: ./gradlew pmd
+ name: "PMD analysis"
+ after_success: lynx -dump file:///home/travis/build/assuntaDC/SoundRecorder/app/build/reports/pmd/pmd.html
+ artifacts:
+ name: "reports_${CI_PROJECT_NAME}_${CI_BUILD_REF_NAME}"
+ expire_in: 4 days
+ paths: app/build/reports/
+ - stage: test
+ name: "Unit Test"
+ script: ./gradlew test
+
+
+notifications:
+ slack: soundrecorderteam:Nut7a5FL3Y7KkjpaJU1yhgMi
diff --git a/SOFTWARE CONFIGURATION MANAGEMENT PLAN OF SOUND RECORDER.pdf b/SOFTWARE CONFIGURATION MANAGEMENT PLAN OF SOUND RECORDER.pdf
new file mode 100644
index 00000000..7eac98c4
Binary files /dev/null and b/SOFTWARE CONFIGURATION MANAGEMENT PLAN OF SOUND RECORDER.pdf differ
diff --git a/SoundRecorder.iml b/SoundRecorder.iml
index 40b8fc4a..18dde8e3 100644
--- a/SoundRecorder.iml
+++ b/SoundRecorder.iml
@@ -1,5 +1,10 @@
-
+
+
+
+
+
+
@@ -8,10 +13,11 @@
-
+
+
diff --git a/app/app.iml b/app/app.iml
deleted file mode 100644
index 1cdca55a..00000000
--- a/app/app.iml
+++ /dev/null
@@ -1,120 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- generateDebugSources
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index ae3d3494..b8f3a3d6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,11 +2,11 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 21
- buildToolsVersion '25.0.0'
+ buildToolsVersion '29.0.2'
defaultConfig {
applicationId "com.danielkim.soundrecorder"
- minSdkVersion 16
+ minSdkVersion 17
targetSdkVersion 21
versionCode 130
versionName "1.3.0"
@@ -19,13 +19,87 @@ android {
}
lintOptions{
disable 'MissingTranslation'
+ abortOnError false
+ }
+
+ testOptions {
+ unitTests.includeAndroidResources = true
+ unitTests.all {
+ reports {
+ junitXml.enabled = true
+ html.enabled = false
+ }
+ }
+ }
+ sourceSets{
+ main { java.srcDirs = ['src/main/java'] }
+ test { java.srcDirs = ['src/test/java'] }
+ androidTest { java.srcDirs = ['src/androidTest/java'] }
+ }
+ configurations.all {
+ resolutionStrategy.dependencySubstitution {
+ substitute module('org.hamcrest:hamcrest-core:1.1') with module('junit:junit:4.10')
+ }
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ maven {
+ url "https://maven.google.com"
+ }
}
}
dependencies {
- compile 'com.android.support:appcompat-v7:21.0.+'
- compile 'com.android.support:cardview-v7:21.0.+'
- compile 'com.android.support:recyclerview-v7:21.0.+'
- compile 'com.melnykov:floatingactionbutton:1.1.0'
- compile 'com.jpardogo.materialtabstrip:library:1.0.6'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ implementation 'com.android.support:appcompat-v7:21.0.+'
+ implementation 'com.android.support:cardview-v7:21.0.+'
+ implementation 'com.android.support:recyclerview-v7:21.0.+'
+ implementation 'com.melnykov:floatingactionbutton:1.1.0'
+ implementation 'com.jpardogo.materialtabstrip:library:1.0.6'
+ implementation 'com.ibm.watson:ibm-watson:8.6.3'
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
+ testImplementation 'junit:junit:4.12'
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
+
}
+
+apply plugin: 'checkstyle'
+apply plugin: 'pmd'
+apply plugin: 'com.github.roroche.plantuml'
+apply plugin: 'jacoco'
+
+checkstyle {
+ configFile = file("${project.rootDir}/app/checkstyle.xml")
+ toolVersion = '8.36'
+ ignoreFailures = false
+}
+
+task checkstyle(type: Checkstyle) {
+ source 'src'
+ include '**/*.java'
+ exclude '**/gen/**'
+ showViolations = true
+ classpath = files()
+ reports {
+ xml.enabled = false
+ html.enabled = true
+ }
+}
+
+task pmd(type: Pmd) {
+ ignoreFailures = true
+ source 'src'
+ include '**/*.java'
+ exclude '**/gen/**'
+ reports {
+ xml.enabled = false
+ html.enabled = true
+ }
+}
+
+task uml{
+ version = "1.0.2"
+}
\ No newline at end of file
diff --git a/app/checkstyle.xml b/app/checkstyle.xml
new file mode 100644
index 00000000..301c4c77
--- /dev/null
+++ b/app/checkstyle.xml
@@ -0,0 +1,228 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/androidTest/java/com/danielkim/soundrecorder/ApplicationTest.java b/app/src/androidTest/java/com/danielkim/soundrecorder/ApplicationTest.java
deleted file mode 100644
index 17e285cb..00000000
--- a/app/src/androidTest/java/com/danielkim/soundrecorder/ApplicationTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.danielkim.soundrecorder;
-
-import android.app.Application;
-import android.test.ApplicationTestCase;
-
-/**
- * Testing Fundamentals
- */
-public class ApplicationTest extends ApplicationTestCase {
- public ApplicationTest() {
- super(Application.class);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3ee713ca..52d1d6dd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,6 +5,12 @@
+
+
+
+
+
+
> 8) & 0xff);
+ header[6] = (byte) ((totalDataLen >> 16) & 0xff);
+ header[7] = (byte) ((totalDataLen >> 24) & 0xff);
+ header[8] = 'W';
+ header[9] = 'A';
+ header[10] = 'V';
+ header[11] = 'E';
+ header[12] = 'f'; // 'fmt ' chunk
+ header[13] = 'm';
+ header[14] = 't';
+ header[15] = ' ';
+ header[16] = 16; // 4 bytes: size of 'fmt ' chunk
+ header[17] = 0;
+ header[18] = 0;
+ header[19] = 0;
+ header[20] = 1; // format = 1
+ header[21] = 0;
+ header[22] = (byte) channels;
+ header[23] = 0;
+ header[24] = (byte) (longSampleRate & 0xff);
+ header[25] = (byte) ((longSampleRate >> 8) & 0xff);
+ header[26] = (byte) ((longSampleRate >> 16) & 0xff);
+ header[27] = (byte) ((longSampleRate >> 24) & 0xff);
+ header[28] = (byte) (byteRate & 0xff);
+ header[29] = (byte) ((byteRate >> 8) & 0xff);
+ header[30] = (byte) ((byteRate >> 16) & 0xff);
+ header[31] = (byte) ((byteRate >> 24) & 0xff);
+ header[32] = (byte) (((RECORDER_CHANNELS == AudioFormat.CHANNEL_IN_MONO) ? 1 : 2) * 16 / 8); // block align
+ header[33] = 0;
+ header[34] = RECORDER_BPP; // bits per sample
+ header[35] = 0;
+ header[36] = 'd';
+ header[37] = 'a';
+ header[38] = 't';
+ header[39] = 'a';
+ header[40] = (byte) (totalAudioLen & 0xff);
+ header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
+ header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
+ header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
+
+ out.write(header, 0, 44);
}
}
diff --git a/app/src/main/java/com/danielkim/soundrecorder/activities/MainActivity.java b/app/src/main/java/com/danielkim/soundrecorder/activities/MainActivity.java
index a2e6bde7..cb474953 100644
--- a/app/src/main/java/com/danielkim/soundrecorder/activities/MainActivity.java
+++ b/app/src/main/java/com/danielkim/soundrecorder/activities/MainActivity.java
@@ -1,9 +1,7 @@
package com.danielkim.soundrecorder.activities;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.os.Bundle;
-import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
@@ -16,14 +14,12 @@
import com.astuetz.PagerSlidingTabStrip;
import com.danielkim.soundrecorder.R;
import com.danielkim.soundrecorder.fragments.FileViewerFragment;
-import com.danielkim.soundrecorder.fragments.LicensesFragment;
import com.danielkim.soundrecorder.fragments.RecordFragment;
public class MainActivity extends ActionBarActivity{
private static final String LOG_TAG = MainActivity.class.getSimpleName();
-
private PagerSlidingTabStrip tabs;
private ViewPager pager;
@@ -42,6 +38,7 @@ protected void onCreate(Bundle savedInstanceState) {
if (toolbar != null) {
setSupportActionBar(toolbar);
}
+
}
@Override
@@ -77,13 +74,14 @@ public MyAdapter(FragmentManager fm) {
@Override
public Fragment getItem(int position) {
- switch(position){
- case 0:{
+ switch(position) {
+ case 0: {
return RecordFragment.newInstance(position);
}
- case 1:{
+ case 1: {
return FileViewerFragment.newInstance(position);
}
+ default: break;
}
return null;
}
@@ -101,4 +99,5 @@ public CharSequence getPageTitle(int position) {
public MainActivity() {
}
+
}
diff --git a/app/src/main/java/com/danielkim/soundrecorder/activities/SettingsActivity.java b/app/src/main/java/com/danielkim/soundrecorder/activities/SettingsActivity.java
index fbb3bfef..ee664c3b 100644
--- a/app/src/main/java/com/danielkim/soundrecorder/activities/SettingsActivity.java
+++ b/app/src/main/java/com/danielkim/soundrecorder/activities/SettingsActivity.java
@@ -1,13 +1,10 @@
package com.danielkim.soundrecorder.activities;
-import android.app.Activity;
import android.os.Bundle;
-import android.os.PersistableBundle;
-import android.preference.PreferenceActivity;
import android.support.annotation.Nullable;
-import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
+import android.support.v7.app.ActionBarActivity;
import com.danielkim.soundrecorder.R;
import com.danielkim.soundrecorder.fragments.SettingsFragment;
@@ -16,7 +13,7 @@
* Created by Daniel on 5/22/2017.
*/
-public class SettingsActivity extends android.support.v7.app.ActionBarActivity {
+public class SettingsActivity extends ActionBarActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/app/src/main/java/com/danielkim/soundrecorder/adapters/FileViewerAdapter.java b/app/src/main/java/com/danielkim/soundrecorder/adapters/FileViewerAdapter.java
index 1d1418cf..69dbb0f3 100644
--- a/app/src/main/java/com/danielkim/soundrecorder/adapters/FileViewerAdapter.java
+++ b/app/src/main/java/com/danielkim/soundrecorder/adapters/FileViewerAdapter.java
@@ -4,12 +4,16 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Environment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
+import android.text.format.DateUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -17,50 +21,56 @@
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
-import android.text.format.DateUtils;
+import com.danielkim.soundrecorder.CustomAlertDialogForExtractedText;
import com.danielkim.soundrecorder.DBHelper;
import com.danielkim.soundrecorder.R;
import com.danielkim.soundrecorder.RecordingItem;
import com.danielkim.soundrecorder.fragments.PlaybackFragment;
import com.danielkim.soundrecorder.listeners.OnDatabaseChangedListener;
+import com.ibm.cloud.sdk.core.security.IamAuthenticator;
+import com.ibm.watson.speech_to_text.v1.SpeechToText;
+import com.ibm.watson.speech_to_text.v1.model.RecognizeOptions;
+import com.ibm.watson.speech_to_text.v1.model.SpeechRecognitionAlternative;
+import com.ibm.watson.speech_to_text.v1.model.SpeechRecognitionResult;
+import com.ibm.watson.speech_to_text.v1.model.SpeechRecognitionResults;
+import com.ibm.watson.speech_to_text.v1.websocket.BaseRecognizeCallback;
import java.io.File;
-import java.util.Locale;
-import java.util.concurrent.TimeUnit;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
/**
* Created by Daniel on 12/29/2014.
*/
public class FileViewerAdapter extends RecyclerView.Adapter
- implements OnDatabaseChangedListener{
+ implements OnDatabaseChangedListener {
private static final String LOG_TAG = "FileViewerAdapter";
-
private DBHelper mDatabase;
-
- RecordingItem item;
- Context mContext;
- LinearLayoutManager llm;
+ private RecordingItem item;
+ private Context mContext;
+ private LinearLayoutManager llm;
public FileViewerAdapter(Context context, LinearLayoutManager linearLayoutManager) {
super();
- mContext = context;
- mDatabase = new DBHelper(mContext);
- mDatabase.setOnDatabaseChangedListener(this);
- llm = linearLayoutManager;
+ this.mContext = context;
+ this.mDatabase = DBHelper.getInstance(mContext);
+ this.mDatabase.checkConsistencyWithFileSystem();
+ this.mDatabase.setOnDatabaseChangedListener(this);
+ this.llm = linearLayoutManager;
}
@Override
public void onBindViewHolder(final RecordingsViewHolder holder, int position) {
-
- item = getItem(position);
+ this.item = getItem(position);
long itemDuration = item.getLength();
long minutes = TimeUnit.MILLISECONDS.toMinutes(itemDuration);
- long seconds = TimeUnit.MILLISECONDS.toSeconds(itemDuration)
- - TimeUnit.MINUTES.toSeconds(minutes);
+ long seconds = TimeUnit.MILLISECONDS.toSeconds(itemDuration) - TimeUnit.MINUTES.toSeconds(minutes);
holder.vName.setText(item.getName());
holder.vLength.setText(String.format("%02d:%02d", minutes, seconds));
@@ -76,44 +86,97 @@ public void onBindViewHolder(final RecordingsViewHolder holder, int position) {
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- try {
- PlaybackFragment playbackFragment =
- new PlaybackFragment().newInstance(getItem(holder.getPosition()));
+ int position = holder.getPosition();
+ File file = new File(getItem(position).getFilePath());
- FragmentTransaction transaction = ((FragmentActivity) mContext)
- .getSupportFragmentManager()
- .beginTransaction();
+ if (file.exists()){
+ try {
+ PlaybackFragment playbackFragment = new PlaybackFragment().newInstance(getItem(holder.getPosition()));
+ FragmentTransaction transaction = ((FragmentActivity) mContext)
+ .getSupportFragmentManager()
+ .beginTransaction();
- playbackFragment.show(transaction, "dialog_playback");
+ playbackFragment.show(transaction, "dialog_playback");
- } catch (Exception e) {
- Log.e(LOG_TAG, "exception", e);
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "exception", e);
+ }
}
+ else Toast.makeText(mContext, mContext.getResources().getString(R.string.toast_file_does_not_exist), Toast.LENGTH_LONG).show();
}
});
holder.cardView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
-
- ArrayList entrys = new ArrayList();
+ final ArrayList entrys = new ArrayList();
+ entrys.add(mContext.getString(R.string.dialog_file_convert));
entrys.add(mContext.getString(R.string.dialog_file_share));
entrys.add(mContext.getString(R.string.dialog_file_rename));
entrys.add(mContext.getString(R.string.dialog_file_delete));
final CharSequence[] items = entrys.toArray(new CharSequence[entrys.size()]);
-
// File delete confirm
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle(mContext.getString(R.string.dialog_title_options));
builder.setItems(items, new DialogInterface.OnClickListener() {
+ @Override
public void onClick(DialogInterface dialog, int item) {
- if (item == 0) {
- shareFileDialog(holder.getPosition());
- } if (item == 1) {
- renameFileDialog(holder.getPosition());
- } else if (item == 2) {
+ if (item == 0){
+ if(isDeviceConnected()){
+ FileInputStream audioInputStream;
+ try {
+ audioInputStream = new FileInputStream(getItem(holder.getPosition()).getFilePath());
+
+ CustomAlertDialogForExtractedText customAlertDialogForExtractedText = new CustomAlertDialogForExtractedText(mContext);
+ customAlertDialogForExtractedText.show();
+ customAlertDialogForExtractedText.setText(mContext.getResources().getString(R.string.textExtractionInProgress));
+
+ AsyncronusRefreshing asyncronusRefreshing = new AsyncronusRefreshing(customAlertDialogForExtractedText);
+ AsyncronusTranscription asyncronusTranscription = new AsyncronusTranscription(customAlertDialogForExtractedText, audioInputStream, asyncronusRefreshing);
+
+ asyncronusRefreshing.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
+ asyncronusTranscription.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
+
+ } catch (FileNotFoundException e) {
+ Toast.makeText(mContext, mContext.getResources().getString(R.string.toast_file_does_not_exist), Toast.LENGTH_LONG).show();
+ }
+ }else{
+ new AlertDialog.Builder(mContext)
+ .setTitle(mContext.getString(R.string.dialog_device_not_connected_title))
+ .setMessage(mContext.getString(R.string.dialog_device_not_connected_message))
+ .setPositiveButton(android.R.string.ok, null)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .show();
+ }
+ }
+ else if (item == 1) {
+ if(isDeviceConnected()){
+ try {
+ shareFileDialog(holder.getPosition());
+ }
+ catch (FileNotFoundException e){
+ Toast.makeText(mContext, mContext.getResources().getString(R.string.toast_file_does_not_exist), Toast.LENGTH_LONG).show();
+ }
+ }else{
+ new AlertDialog.Builder(mContext)
+ .setTitle(mContext.getString(R.string.dialog_device_not_connected_title))
+ .setMessage(mContext.getString(R.string.dialog_device_not_connected_message))
+ .setPositiveButton(android.R.string.ok, null)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .show();
+ }
+ }
+ else if (item == 2) {
+ try {
+ renameFileDialog(holder.getPosition());
+ }
+ catch (FileNotFoundException e){
+ Toast.makeText(mContext, mContext.getResources().getString(R.string.toast_file_does_not_exist), Toast.LENGTH_LONG).show();
+ }
+ }
+ else if (item == 3) {
deleteFileDialog(holder.getPosition());
}
}
@@ -121,6 +184,7 @@ public void onClick(DialogInterface dialog, int item) {
builder.setCancelable(true);
builder.setNegativeButton(mContext.getString(R.string.dialog_action_cancel),
new DialogInterface.OnClickListener() {
+ @Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
@@ -137,9 +201,7 @@ public void onClick(DialogInterface dialog, int id) {
@Override
public RecordingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View itemView = LayoutInflater.
- from(parent.getContext()).
- inflate(R.layout.card_view, parent, false);
+ View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view, parent, false);
mContext = parent.getContext();
@@ -208,20 +270,30 @@ public void removeOutOfApp(String filePath) {
//user deletes a saved recording out of the application through another application
}
+ private boolean newNameAlreadyExists(String newName){
+ boolean nameAlreadyExsists = false;
+
+ for (int i = 0; i < this.mDatabase.getCount() && !nameAlreadyExsists; i++){
+ if (newName.equals(this.mDatabase.getItemAt(i).getName())) nameAlreadyExsists = true;
+ }
+
+ return nameAlreadyExsists;
+ }
+
public void rename(int position, String name) {
//rename a file
-
String mFilePath = Environment.getExternalStorageDirectory().getAbsolutePath();
mFilePath += "/SoundRecorder/" + name;
File f = new File(mFilePath);
if (f.exists() && !f.isDirectory()) {
//file name is not unique, cannot rename file.
- Toast.makeText(mContext,
- String.format(mContext.getString(R.string.toast_file_exists), name),
- Toast.LENGTH_SHORT).show();
-
- } else {
+ Toast.makeText(mContext, String.format(mContext.getString(R.string.toast_file_exists), name), Toast.LENGTH_SHORT).show();
+ }
+ else if (newNameAlreadyExists(name)){
+ Toast.makeText(mContext, mContext.getResources().getString(R.string.nameAlreadyExistsInDB), Toast.LENGTH_SHORT).show();
+ }
+ else {
//file name is unique, rename file
File oldFilePath = new File(getItem(position).getFilePath());
oldFilePath.renameTo(f);
@@ -230,49 +302,64 @@ public void rename(int position, String name) {
}
}
- public void shareFileDialog(int position) {
- Intent shareIntent = new Intent();
- shareIntent.setAction(Intent.ACTION_SEND);
- shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(getItem(position).getFilePath())));
- shareIntent.setType("audio/mp4");
- mContext.startActivity(Intent.createChooser(shareIntent, mContext.getText(R.string.send_to)));
+ public void shareFileDialog(int position) throws FileNotFoundException{
+ File file = new File(getItem(position).getFilePath());
+
+ if(file.exists()){
+ Intent shareIntent = new Intent();
+ shareIntent.setAction(Intent.ACTION_SEND);
+ shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(getItem(position).getFilePath())));
+ shareIntent.setType("audio/wav");
+ mContext.startActivity(Intent.createChooser(shareIntent, mContext.getText(R.string.send_to)));
+ }
+ else{
+ throw new FileNotFoundException();
+ }
}
- public void renameFileDialog (final int position) {
- // File rename dialog
- AlertDialog.Builder renameFileBuilder = new AlertDialog.Builder(mContext);
+ public void renameFileDialog (final int position) throws FileNotFoundException{
+ File file = new File(getItem(position).getFilePath());
- LayoutInflater inflater = LayoutInflater.from(mContext);
- View view = inflater.inflate(R.layout.dialog_rename_file, null);
+ if (file.exists()){
+ // File rename dialog
+ AlertDialog.Builder renameFileBuilder = new AlertDialog.Builder(mContext);
- final EditText input = (EditText) view.findViewById(R.id.new_name);
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ View view = inflater.inflate(R.layout.dialog_rename_file, null);
- renameFileBuilder.setTitle(mContext.getString(R.string.dialog_title_rename));
- renameFileBuilder.setCancelable(true);
- renameFileBuilder.setPositiveButton(mContext.getString(R.string.dialog_action_ok),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- try {
- String value = input.getText().toString().trim() + ".mp4";
- rename(position, value);
+ final EditText input = (EditText) view.findViewById(R.id.new_name);
+ input.setText(file.getName().replace(".wav", ""));
- } catch (Exception e) {
- Log.e(LOG_TAG, "exception", e);
- }
+ renameFileBuilder.setTitle(mContext.getString(R.string.dialog_title_rename));
+ renameFileBuilder.setCancelable(true);
+ renameFileBuilder.setPositiveButton(mContext.getString(R.string.dialog_action_ok),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ try {
+ String value = input.getText().toString().trim() + ".wav";
+ rename(position, value);
- dialog.cancel();
- }
- });
- renameFileBuilder.setNegativeButton(mContext.getString(R.string.dialog_action_cancel),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "exception", e);
+ }
- renameFileBuilder.setView(view);
- AlertDialog alert = renameFileBuilder.create();
- alert.show();
+ dialog.cancel();
+ }
+ });
+ renameFileBuilder.setNegativeButton(mContext.getString(R.string.dialog_action_cancel),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+
+ renameFileBuilder.setView(view);
+ AlertDialog alert = renameFileBuilder.create();
+ alert.show();
+ }
+ else throw new FileNotFoundException();
}
public void deleteFileDialog (final int position) {
@@ -283,6 +370,7 @@ public void deleteFileDialog (final int position) {
confirmDelete.setCancelable(true);
confirmDelete.setPositiveButton(mContext.getString(R.string.dialog_action_yes),
new DialogInterface.OnClickListener() {
+ @Override
public void onClick(DialogInterface dialog, int id) {
try {
//remove item from database, recyclerview, and storage
@@ -297,6 +385,7 @@ public void onClick(DialogInterface dialog, int id) {
});
confirmDelete.setNegativeButton(mContext.getString(R.string.dialog_action_no),
new DialogInterface.OnClickListener() {
+ @Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
@@ -305,4 +394,150 @@ public void onClick(DialogInterface dialog, int id) {
AlertDialog alert = confirmDelete.create();
alert.show();
}
+
+ private boolean isDeviceConnected(){
+ boolean isConnected = false;
+
+ ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo ni = cm.getActiveNetworkInfo();
+
+ if(ni != null) isConnected = ni.isConnected();
+
+ return isConnected;
+ }
+
+ class AsyncronusRefreshing extends AsyncTask{
+ private boolean isLoadingEnded;
+ private CustomAlertDialogForExtractedText customAlertDialogForExtractedText;
+
+ public AsyncronusRefreshing(CustomAlertDialogForExtractedText customAlertDialogForExtractedText){
+ this.isLoadingEnded = false;
+ this.customAlertDialogForExtractedText = customAlertDialogForExtractedText;
+ }
+
+ @Override
+ protected Object doInBackground(Object[] objects) {
+ final String baseText = mContext.getResources().getString(R.string.textExtractionInProgress);
+ String loadingText = baseText;
+
+ while (!this.isLoadingEnded){
+ try {
+ loadingText = loadingText + ".";
+ publishProgress(loadingText);
+
+ if (loadingText.equals(baseText + "...")) loadingText = baseText;
+
+ Thread.sleep(500);
+
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Object[] values) {
+ String loadingText = (String) values[0];
+ this.customAlertDialogForExtractedText.setText(loadingText);
+ }
+
+ public void endTask(){
+ this.isLoadingEnded = true;
+ }
+ }
+
+ class AsyncronusTranscription extends AsyncTask{
+ private final String apiKey = "ifXU_ZXG_ySVNViaU19SiUnILr5BkhmZJtMIcN-AL6Qc";
+ private final String url = "https://api.eu-gb.speech-to-text.watson.cloud.ibm.com/instances/b6c2ed98-71bf-4ebf-a156-af97be159062";
+ private CustomAlertDialogForExtractedText customAlertDialogForExtractedText;
+ private FileInputStream audioInputStream;
+ private AsyncronusRefreshing asyncronusRefreshing;
+
+ public AsyncronusTranscription(CustomAlertDialogForExtractedText customAlertDialogForExtractedText, FileInputStream audioInputStream, AsyncronusRefreshing asyncronusRefreshing){
+ this.customAlertDialogForExtractedText = customAlertDialogForExtractedText;
+ this.audioInputStream = audioInputStream;
+ this.asyncronusRefreshing = asyncronusRefreshing;
+ }
+
+ @Override
+ protected Object doInBackground(Object[] objects) {
+ //Layout building test string
+ //String extractedText = (String) mContext.getResources().getString(R.string.speech_to_text_example);
+
+ String extractedText = contactServiceAndGetTranscript(this.audioInputStream);
+ this.asyncronusRefreshing.endTask();
+ return extractedText;
+ }
+
+ @Override
+ protected void onPostExecute(Object result) {
+ String extractedText = (String) result;
+
+ if (!extractedText.equals("")) this.customAlertDialogForExtractedText.setText(extractedText);
+ else {
+ this.customAlertDialogForExtractedText.setButtonCopyEnabled(false);
+ this.customAlertDialogForExtractedText.setText(mContext.getResources().getString(R.string.toast_unable_to_extract_text));
+ }
+ }
+
+ private String contactServiceAndGetTranscript(FileInputStream audioInputStream){
+ IamAuthenticator authenticator = new IamAuthenticator(this.apiKey);
+ SpeechToText speechToText = new SpeechToText(authenticator);
+ speechToText.setServiceUrl(this.url);
+
+ final String[] transcript = new String[1];
+ transcript[0] = "";
+
+ final Boolean[] transcriptionEnded = new Boolean[1];
+ transcriptionEnded[0] = false;
+
+ RecognizeOptions recognizeOptions = new RecognizeOptions.Builder()
+ .audio(audioInputStream)
+ .contentType("audio/wav")
+ .model("en-US_BroadbandModel")
+ .maxAlternatives(5)
+ .build();
+
+ BaseRecognizeCallback baseRecognizeCallback = new BaseRecognizeCallback() {
+
+ @Override
+ public void onTranscription (SpeechRecognitionResults speechRecognitionResults) {
+ List results = speechRecognitionResults.getResults();
+
+ for (int resultsIndex = 0; resultsIndex < results.size(); resultsIndex++){
+ List alternatives = results.get(resultsIndex).getAlternatives();
+
+ int biggerConfidenceIndex = 0;
+ double maxConfidence = 0;
+ for (int alternativeIndex = 0; alternativeIndex < alternatives.size(); alternativeIndex++){
+ double currentConfidence;
+
+ if (alternatives.get(alternativeIndex).getConfidence() != null) currentConfidence = alternatives.get(alternativeIndex).getConfidence();
+ else currentConfidence = 0;
+
+ if(currentConfidence > maxConfidence){
+ maxConfidence = currentConfidence;
+ biggerConfidenceIndex = alternativeIndex;
+ }
+ }
+
+ transcript[0] += alternatives.get(biggerConfidenceIndex).getTranscript() + " ";
+ }
+ }
+
+ @Override
+ public void onDisconnected() {
+ transcriptionEnded[0] = true;
+ }
+ };
+
+ speechToText.recognizeUsingWebSocket(recognizeOptions, baseRecognizeCallback);
+
+ while (!transcriptionEnded[0]);
+
+ String firstChar = transcript[0].substring(0, 1);
+ return transcript[0].replace(firstChar, firstChar.toUpperCase());
+ }
+ }
}
diff --git a/app/src/main/java/com/danielkim/soundrecorder/fragments/FileViewerFragment.java b/app/src/main/java/com/danielkim/soundrecorder/fragments/FileViewerFragment.java
index bf29e7f0..abbbde9a 100644
--- a/app/src/main/java/com/danielkim/soundrecorder/fragments/FileViewerFragment.java
+++ b/app/src/main/java/com/danielkim/soundrecorder/fragments/FileViewerFragment.java
@@ -20,12 +20,12 @@
public class FileViewerFragment extends Fragment{
private static final String ARG_POSITION = "position";
private static final String LOG_TAG = "FileViewerFragment";
-
private int position;
private FileViewerAdapter mFileViewerAdapter;
public static FileViewerFragment newInstance(int position) {
FileViewerFragment f = new FileViewerFragment();
+
Bundle b = new Bundle();
b.putInt(ARG_POSITION, position);
f.setArguments(b);
@@ -63,20 +63,20 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
}
FileObserver observer =
- new FileObserver(android.os.Environment.getExternalStorageDirectory().toString()
- + "/SoundRecorder") {
+ new FileObserver(android.os.Environment.getExternalStorageDirectory().toString() +
+ "/SoundRecorder") {
// set up a file observer to watch this directory on sd card
@Override
public void onEvent(int event, String file) {
if(event == FileObserver.DELETE){
// user deletes a recording file out of the app
- String filePath = android.os.Environment.getExternalStorageDirectory().toString()
- + "/SoundRecorder" + file + "]";
+ String filePath = android.os.Environment.getExternalStorageDirectory().toString() +
+ "/SoundRecorder" + file + "]";
- Log.d(LOG_TAG, "File deleted ["
- + android.os.Environment.getExternalStorageDirectory().toString()
- + "/SoundRecorder" + file + "]");
+ Log.d(LOG_TAG, "File deleted [" +
+ android.os.Environment.getExternalStorageDirectory().toString() +
+ "/SoundRecorder" + file + "]");
// remove file from database and recyclerview
mFileViewerAdapter.removeOutOfApp(filePath);
diff --git a/app/src/main/java/com/danielkim/soundrecorder/fragments/PlaybackFragment.java b/app/src/main/java/com/danielkim/soundrecorder/fragments/PlaybackFragment.java
index 09f12135..25e20f0b 100644
--- a/app/src/main/java/com/danielkim/soundrecorder/fragments/PlaybackFragment.java
+++ b/app/src/main/java/com/danielkim/soundrecorder/fragments/PlaybackFragment.java
@@ -66,8 +66,8 @@ public void onCreate(Bundle savedInstanceState) {
long itemDuration = item.getLength();
minutes = TimeUnit.MILLISECONDS.toMinutes(itemDuration);
- seconds = TimeUnit.MILLISECONDS.toSeconds(itemDuration)
- - TimeUnit.MINUTES.toSeconds(minutes);
+ seconds = TimeUnit.MILLISECONDS.toSeconds(itemDuration) -
+ TimeUnit.MINUTES.toSeconds(minutes);
}
@Override
@@ -102,8 +102,8 @@ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mHandler.removeCallbacks(mRunnable);
long minutes = TimeUnit.MILLISECONDS.toMinutes(mMediaPlayer.getCurrentPosition());
- long seconds = TimeUnit.MILLISECONDS.toSeconds(mMediaPlayer.getCurrentPosition())
- - TimeUnit.MINUTES.toSeconds(minutes);
+ long seconds = TimeUnit.MILLISECONDS.toSeconds(mMediaPlayer.getCurrentPosition()) -
+ TimeUnit.MINUTES.toSeconds(minutes);
mCurrentProgressTextView.setText(String.format("%02d:%02d", minutes,seconds));
updateSeekBar();
@@ -129,8 +129,8 @@ public void onStopTrackingTouch(SeekBar seekBar) {
mMediaPlayer.seekTo(seekBar.getProgress());
long minutes = TimeUnit.MILLISECONDS.toMinutes(mMediaPlayer.getCurrentPosition());
- long seconds = TimeUnit.MILLISECONDS.toSeconds(mMediaPlayer.getCurrentPosition())
- - TimeUnit.MINUTES.toSeconds(minutes);
+ long seconds = TimeUnit.MILLISECONDS.toSeconds(mMediaPlayer.getCurrentPosition()) -
+ TimeUnit.MINUTES.toSeconds(minutes);
mCurrentProgressTextView.setText(String.format("%02d:%02d", minutes,seconds));
updateSeekBar();
}
@@ -305,8 +305,8 @@ public void run() {
mSeekBar.setProgress(mCurrentPosition);
long minutes = TimeUnit.MILLISECONDS.toMinutes(mCurrentPosition);
- long seconds = TimeUnit.MILLISECONDS.toSeconds(mCurrentPosition)
- - TimeUnit.MINUTES.toSeconds(minutes);
+ long seconds = TimeUnit.MILLISECONDS.toSeconds(mCurrentPosition) -
+ TimeUnit.MINUTES.toSeconds(minutes);
mCurrentProgressTextView.setText(String.format("%02d:%02d", minutes, seconds));
updateSeekBar();
diff --git a/app/src/main/java/com/danielkim/soundrecorder/fragments/RecordFragment.java b/app/src/main/java/com/danielkim/soundrecorder/fragments/RecordFragment.java
index 151822c0..7ee52d0a 100644
--- a/app/src/main/java/com/danielkim/soundrecorder/fragments/RecordFragment.java
+++ b/app/src/main/java/com/danielkim/soundrecorder/fragments/RecordFragment.java
@@ -5,6 +5,7 @@
import android.os.Environment;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -30,7 +31,7 @@
public class RecordFragment extends Fragment {
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_POSITION = "position";
- private static final String LOG_TAG = RecordFragment.class.getSimpleName();
+ // private static final String LOG_TAG = RecordFragment.class.getSimpleName();
private int position;
@@ -42,10 +43,10 @@ public class RecordFragment extends Fragment {
private int mRecordPromptCount = 0;
private boolean mStartRecording = true;
- private boolean mPauseRecording = true;
private Chronometer mChronometer = null;
long timeWhenPaused = 0; //stores time when user clicks pause button
+ private boolean inPause = false; //handles when user stops while in pause
/**
* Use this factory method to create a new instance of
@@ -62,8 +63,6 @@ public static RecordFragment newInstance(int position) {
return f;
}
- public RecordFragment() {
- }
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -77,6 +76,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
View recordView = inflater.inflate(R.layout.fragment_record, container, false);
mChronometer = (Chronometer) recordView.findViewById(R.id.chronometer);
+
//update recording prompt text
mRecordingPrompt = (TextView) recordView.findViewById(R.id.recording_status_text);
@@ -96,8 +96,8 @@ public void onClick(View v) {
mPauseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- onPauseRecord(mPauseRecording);
- mPauseRecording = !mPauseRecording;
+ inPause = !inPause;
+ onPauseRecord();
}
});
@@ -105,15 +105,14 @@ public void onClick(View v) {
}
// Recording Start/Stop
- //TODO: recording pause
private void onRecord(boolean start){
-
Intent intent = new Intent(getActivity(), RecordingService.class);
-
if (start) {
// start recording
mRecordButton.setImageResource(R.drawable.ic_media_stop);
- //mPauseButton.setVisibility(View.VISIBLE);
+ mPauseButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_media_pause,0,0,0);
+
+ mPauseButton.setVisibility(View.VISIBLE);
Toast.makeText(getActivity(),R.string.toast_recording_start,Toast.LENGTH_SHORT).show();
File folder = new File(Environment.getExternalStorageDirectory() + "/SoundRecorder");
if (!folder.exists()) {
@@ -142,43 +141,54 @@ public void onChronometerTick(Chronometer chronometer) {
//start RecordingService
getActivity().startService(intent);
+
//keep screen on while recording
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-
mRecordingPrompt.setText(getString(R.string.record_in_progress) + ".");
mRecordPromptCount++;
} else {
//stop recording
mRecordButton.setImageResource(R.drawable.ic_mic_white_36dp);
- //mPauseButton.setVisibility(View.GONE);
+ mPauseButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_media_pause,0,0,0);
+ mPauseButton.setVisibility(View.GONE);
+
mChronometer.stop();
mChronometer.setBase(SystemClock.elapsedRealtime());
- timeWhenPaused = 0;
- mRecordingPrompt.setText(getString(R.string.record_prompt));
+ mRecordingPrompt.setText(getString(R.string.record_prompt));
getActivity().stopService(intent);
+ inPause = false;
+
//allow the screen to turn off again once recording is finished
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
- //TODO: implement pause recording
- private void onPauseRecord(boolean pause) {
- if (pause) {
- //pause recording
- mPauseButton.setCompoundDrawablesWithIntrinsicBounds
- (R.drawable.ic_media_play ,0 ,0 ,0);
+ private void onPauseRecord() {
+ if (inPause) {
+ mPauseButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_media_play, 0,0,0);
mRecordingPrompt.setText((String)getString(R.string.resume_recording_button).toUpperCase());
- timeWhenPaused = mChronometer.getBase() - SystemClock.elapsedRealtime();
+ timeWhenPaused = SystemClock.elapsedRealtime() - mChronometer.getBase();
mChronometer.stop();
- } else {
- //resume recording
- mPauseButton.setCompoundDrawablesWithIntrinsicBounds
- (R.drawable.ic_media_pause ,0 ,0 ,0);
+
+ }else {
+ mPauseButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_media_pause,0,0,0);
mRecordingPrompt.setText((String)getString(R.string.pause_recording_button).toUpperCase());
- mChronometer.setBase(SystemClock.elapsedRealtime() + timeWhenPaused);
+ mChronometer.setBase(SystemClock.elapsedRealtime() - timeWhenPaused);
mChronometer.start();
}
+
+ Intent intent = new Intent(getActivity(), RecordingService.class);
+ intent.putExtra("inPause", inPause);
+ getActivity().startService(intent);
}
-}
\ No newline at end of file
+}
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/danielkim/soundrecorder/fragments/SettingsFragment.java b/app/src/main/java/com/danielkim/soundrecorder/fragments/SettingsFragment.java
index fc0d47f0..4814a668 100644
--- a/app/src/main/java/com/danielkim/soundrecorder/fragments/SettingsFragment.java
+++ b/app/src/main/java/com/danielkim/soundrecorder/fragments/SettingsFragment.java
@@ -1,13 +1,14 @@
package com.danielkim.soundrecorder.fragments;
+import android.content.Context;
import android.os.Bundle;
-import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.support.annotation.Nullable;
+import android.widget.Toast;
import com.danielkim.soundrecorder.BuildConfig;
-import com.danielkim.soundrecorder.MySharedPreferences;
+import com.danielkim.soundrecorder.DBHelper;
import com.danielkim.soundrecorder.R;
import com.danielkim.soundrecorder.activities.SettingsActivity;
@@ -21,16 +22,6 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
- CheckBoxPreference highQualityPref = (CheckBoxPreference) findPreference(getResources().getString(R.string.pref_high_quality_key));
- highQualityPref.setChecked(MySharedPreferences.getPrefHighQuality(getActivity()));
- highQualityPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- MySharedPreferences.setPrefHighQuality(getActivity(), (boolean) newValue);
- return true;
- }
- });
-
Preference aboutPref = findPreference(getString(R.string.pref_about_key));
aboutPref.setSummary(getString(R.string.pref_about_desc, BuildConfig.VERSION_NAME));
aboutPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@@ -41,5 +32,21 @@ public boolean onPreferenceClick(Preference preference) {
return true;
}
});
+
+ Preference resyncPref = findPreference(getString(R.string.pref_resyncDB_key));
+ resyncPref.setSummary(getString(R.string.pref_resyncDB_desc));
+ resyncPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ Context context = getActivity();
+ DBHelper dbHelper= DBHelper.getInstance(context);
+ dbHelper.checkConsistencyWithFileSystem();
+
+ Toast.makeText(context, context.getResources().getString(R.string.toast_sync_with_db), Toast.LENGTH_LONG).show();
+
+ return true;
+ }
+ });
+
}
}
diff --git a/app/src/main/res/layout/custom_alert_dialog_for_extracted_text.xml b/app/src/main/res/layout/custom_alert_dialog_for_extracted_text.xml
new file mode 100644
index 00000000..121310c8
--- /dev/null
+++ b/app/src/main/res/layout/custom_alert_dialog_for_extracted_text.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_rename_file.xml b/app/src/main/res/layout/dialog_rename_file.xml
index d92ac782..eef28cc1 100644
--- a/app/src/main/res/layout/dialog_rename_file.xml
+++ b/app/src/main/res/layout/dialog_rename_file.xml
@@ -12,9 +12,9 @@
android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:text=".wav" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_media_playback.xml b/app/src/main/res/layout/fragment_media_playback.xml
index f1a82d7e..0ed8d92e 100644
--- a/app/src/main/res/layout/fragment_media_playback.xml
+++ b/app/src/main/res/layout/fragment_media_playback.xml
@@ -7,12 +7,11 @@
android:layout_height="wrap_content">
@@ -30,9 +29,9 @@
android:layout_marginLeft="10dp"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp"
- android:text="file_name.mp4"
- android:textSize="18sp"
- android:fontFamily="sans-serif-condensed"/>
+ android:fontFamily="sans-serif-condensed"
+ android:text="file_name.wav"
+ android:textSize="18sp" />
+ android:elevation="4dp"
+ app:popupTheme="@style/Base.Theme.AppCompat.Light"
+ app:theme="@style/ToolbarStyle">
+
+
+
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 15fafc5b..4d274106 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -1,41 +1,75 @@
+
+ Sito Web: github.com/dkim0419/SoundRecorder
- Registratore suoni
- Licenze
+ Sound Recorder
+ Licenza
Impostazioni
Registra
- Registrazioni salvate
+ Registrazioni Salvate
- Inizio registrazione
- Registazione salvata in
- %1$s eliminato con successo
- Il file %1$s già esiste. Scegliere un nome del file differente.
+ Registrazione Iniziata
+ Registrazione salvata in
+ %1$s eliminata con successo
+ Il file %1$s esiste già: scegli un nome differente per questo file
+ Il file selezionato non esiste.
+ Impossibile estrarre del testo da questo file
+ Sincronizzazione tra database e file system effettuata con successo
- Registrazione...
+ Registrazione in corso...
- Conferma cancellazione
- Sei sicuro di voler cancellare questo file?
- Licenze open source
- Rinomina file
+ Conferma eliminazione
+ Sei sicuro di voler eliminare questo file?
+ Licenza Open Source
+ Condividi File
+ Rinomina File
Opzioni
- Rinomina file
- Elimina file
- Elimina
- OK
- Sì
- No
-
- Nessuna registrazione salvata
- Pausa
- Riprendi
- Le mie registrazioni
- Premi il bottone per iniziare a registrare
- Registrazione in corso
+ Dispositivo non connesso
+ Il dispositivo non è connesso alla rete. \nPer continuare, devi prima stabilire una connessione dati o Wi-Fi
+ Estrai testo da audio
+ Condividi file
+ Rinomina file
+ Elimina file
+ Annulla
+ OK
+ Sì
+ No
+ Estrazione testo
+ Ok
+ Copia
+ Testo copiato negli appunti
+ Da audio a testo
+ Il nome inserito esiste già nel database dell\'app
+ Estrazione in corso, attendere prego
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Nulla ut eros nibh. Nulla facilisi. Sed iaculis velit nulla. Donec pharetra arcu augue,
+ id ultrices erat porta id. Mecenate libero ipsum, ullamcorper ac sem eu, tincidunt molestie massa.
+ conseguat sem et enim efficitur, sit amet sollicitudin massa fermentum. Vestibolo placerat metus
+ sed mattis iaculis. Nam id efficitur ex. Nullam dictum rutrum mi. Quisque maximus tincidunt sapien
+ sit amet tristique.
+
+ Nessuna registrazione salvata
+ Pausa
+ Riprendi
+ Le mie registrazioni
+ Tocca il pulsante per avviare la registrazione
+ Registrazione in corso
+
+ Invia a
+
+
+ pref_about
+ Informazioni
+ v%s
+
+ pref_Sync_Data
+ Sincronizza dati
+ Sincronizza i dati con il file system
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
index 07b371ca..b985b5a2 100644
--- a/app/src/main/res/values-v21/styles.xml
+++ b/app/src/main/res/values-v21/styles.xml
@@ -5,6 +5,8 @@
- false
- true
+ - @color/white
+
- @color/primary
@@ -39,4 +41,10 @@
- @android:transition/explode
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5061b9dc..faf07b93 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -14,19 +14,25 @@
Recording started
Recording saved to
%1$s successfully deleted
- The file %1$s already exists. Please choose a different file name.
+ The file %1$s already exists: please choose a different file name
+ The selected file does not exist
+ Unable to extract text from this file
+ Synchronization between database and file system performed
Recording...
- Confirm Delete...
+ Confirm Delete
Are you sure you would like to delete this file?
Open Source Licenses
Share File
Rename File
Options
+ Device not connected
+ The device is not connected to the network.\nTo continue, you must first establish a connection with Wi-Fi or data connection
+ Extract Text From Audio
Share File
Rename File
Delete File
@@ -34,6 +40,19 @@
OK
Yes
No
+ Speech-To-Text
+ Ok
+ Copy
+ Text Copied To Clipboard
+ Speech-To-Text
+ The entered name already exists in the app database
+ Extraction in progress, please wait
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Nulla ut eros nibh. Nulla facilisi. Sed iaculis velit nulla. Donec pharetra arcu augue,
+ id ultrices erat porta id. Maecenas libero ipsum, ullamcorper ac sem eu, tincidunt molestie massa.
+ consequat sem et enim efficitur, sit amet sollicitudin massa fermentum. Vestibulum placerat metus
+ sed mattis iaculis. Nam id efficitur ex. Nullam dictum rutrum mi. Quisque maximus tincidunt sapien
+ sit amet tristique.
No saved recordings
Pause
@@ -45,11 +64,12 @@
Send to
- pref_high_quality
- Enable High Quality Recording
- Record in CD Quality
pref_about
About
v%s
+ pref_Sync_Data
+ Sync Data
+ Synchronize data with file system
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index bb36f9ca..72b8ab30 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -4,9 +4,9 @@
-
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 6b806acf..c5d84d3a 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -1,11 +1,11 @@
-
+
\ No newline at end of file
diff --git a/app/src/test/java/com/assuntaDC/soundrecorder/Test.java b/app/src/test/java/com/assuntaDC/soundrecorder/Test.java
new file mode 100644
index 00000000..29820e54
--- /dev/null
+++ b/app/src/test/java/com/assuntaDC/soundrecorder/Test.java
@@ -0,0 +1,9 @@
+package com.assuntadc.soundrecorder;
+
+public class Test {
+
+ @org.junit.Test
+ public void testTheTest() {
+
+ }
+}
diff --git a/build.gradle b/build.gradle
index ea98e44f..b0ae6ac4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,12 +3,16 @@
buildscript {
repositories {
jcenter()
+ google()
+ maven {
+ url "https://plugins.gradle.org/m2/"
+ }
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.3.2'
-
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
+ classpath 'com.android.tools.build:gradle:4.0.1'
+ classpath "com.github.roroche:plantuml-gradle-plugin:1.0.2"
+// NOTE: Do not place your application dependencies here; they belong
+// in the individual module build.gradle files
}
}
@@ -16,4 +20,4 @@ allprojects {
repositories {
jcenter()
}
-}
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 1d3591c8..c04c048e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,4 +15,5 @@
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file
+# org.gradle.parallel=true
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index b111db67..10c24322 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon May 22 14:33:42 EDT 2017
+#Mon Nov 16 11:48:12 CET 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip