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 @@ - - - + \ 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 @@ + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ 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 @@ + + + + + + + + + + + + + + + +