diff --git a/app/build.gradle b/app/build.gradle index 60dcd41..5bbd5d0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,21 +1,9 @@ -buildscript { - repositories { - maven { url 'https://maven.fabric.io/public' } - maven { url 'https://raw.github.com/xujiaao/mvn-repository/master/releases' } - } - - dependencies { - classpath 'com.github.xujiaao:aarLinkSources:1.0.0' - } -} - int MAJOR_VERSION = 1 int MINOR_VERSION = 1 int VERSION_PATCH = 1 int BUILD_NUMBER = 1 apply plugin: 'com.android.application' -apply plugin: 'aar-link-sources' def buildNumber = BUILD_NUMBER // any build number for local build def code = MAJOR_VERSION * 10000 + MINOR_VERSION * 1000 + VERSION_PATCH * 100 + buildNumber @@ -26,8 +14,8 @@ android { buildToolsVersion rootProject.buildToolsVersion defaultConfig { - minSdkVersion 16 - targetSdkVersion 22 + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion versionCode code versionName "${MAJOR_VERSION}.${MINOR_VERSION}.${VERSION_PATCH}" @@ -86,37 +74,33 @@ android { } } -repositories { - jcenter() - mavenCentral() - maven { url 'https://maven.fabric.io/public' } - maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } - flatDir { - dirs 'repo' - } -} - dependencies { compile 'com.yandex.android:speechkit:2.5.0' compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.1.1' - compile 'com.android.support:support-v4:23.1.1' - compile 'com.android.support:recyclerview-v7:23.1.1' - compile 'com.android.support:design:23.1.1' + compile "com.android.support:appcompat-v7:${rootProject.ext.supportVersion}" + compile "com.android.support:support-v4:${rootProject.ext.supportVersion}" + compile "com.android.support:recyclerview-v7:${rootProject.ext.supportVersion}" + compile "com.android.support:design:${rootProject.ext.supportVersion}" compile 'com.squareup.retrofit:retrofit:1.9.0' compile 'com.github.castorflex.smoothprogressbar:library-circular:1.0.1' compile 'org.solovyev.android.views:linear-layout-manager:0.5@aar' - compile ('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.8.3@aar') { - transitive=true + compile('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.8.3@aar') { + transitive = true } - aarLinkSources 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.8.3:sources@jar' compile 'com.yandex.android:mobmetricalib:2.21@aar' compile('com.crashlytics.sdk.android:crashlytics:2.5.2@aar') { transitive = true; } + + compile "io.reactivex.rxjava2:rxjava:2.1.4" + compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar' + + testCompile "org.robolectric:robolectric:3.4.2" + testCompile "junit:junit:4.12" + testCompile "org.mockito:mockito-core:2.10.0" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 471a74e..188fc78 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + * Licensed under the Apache License, Version 2.0 (the "License"); @@ -78,6 +78,7 @@ public void start(final boolean resumedAfterPlaying) { RecognitionBroadcastReceiver.onRecognitionStarted(mContext, mThreadId, resumedAfterPlaying); } + @SuppressWarnings("MissingPermission") // checking in ConversationActivity private void startRecognizer() { final Recognizer recognizer = createRecognizer(mLocale, this); mRecognizers.add(recognizer); diff --git a/app/src/main/java/ru/yandex/subtitles/ui/activity/ConversationActivity.java b/app/src/main/java/ru/yandex/subtitles/ui/activity/ConversationActivity.java index 02b62e1..17cb437 100644 --- a/app/src/main/java/ru/yandex/subtitles/ui/activity/ConversationActivity.java +++ b/app/src/main/java/ru/yandex/subtitles/ui/activity/ConversationActivity.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2015 YA LLC *

* Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,6 +15,7 @@ */ package ru.yandex.subtitles.ui.activity; +import android.Manifest; import android.annotation.TargetApi; import android.content.Context; import android.content.Intent; @@ -25,10 +26,17 @@ import android.support.annotation.Nullable; import android.support.v4.app.FragmentManager; import android.support.v7.app.ActionBar; +import android.util.Log; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; +import android.widget.Toast; +import com.tbruyelle.rxpermissions2.RxPermissions; + +import java.lang.ref.WeakReference; + +import io.reactivex.functions.Consumer; import ru.yandex.speechkit.Error; import ru.yandex.subtitles.R; import ru.yandex.subtitles.analytics.ConversationMetadata; @@ -67,6 +75,7 @@ public class ConversationActivity extends AbstractActivity private static final String EXTRA_THREAD = "thread_id"; private static final String EXTRA_FROM_WIDGET = "from_widget"; + private static final String LOG_TAG = ConversationActivity.class.getSimpleName(); public static void startConversation(final Context context) { startConversation(context, null); @@ -285,9 +294,30 @@ public boolean onOptionsItemSelected(final MenuItem item) { private void autoStartRecognition() { if (mSpeechKitInitialized && mRecognitionStarted && isActivityResumed()) { - mRecognitionStarted = true; - mMicrophoneBarView.setState(MicrophoneBarController.STATE_IN_PROGRESS); - MessagingService.startRecognition(this, mThreadId); + final WeakReference activityRef = new WeakReference<>(this); + new RxPermissions(this) + .request(Manifest.permission.RECORD_AUDIO) + .subscribe(new Consumer() { + @Override + public void accept(Boolean granted) throws Exception { + ConversationActivity activity = activityRef.get(); + if (activity != null) { + if (granted) { + mRecognitionStarted = true; + mMicrophoneBarView.setState(MicrophoneBarController.STATE_IN_PROGRESS); + MessagingService.startRecognition(activity, mThreadId); + } else { + Toast.makeText(activity, activity.getString(R.string.err_record_permission_denied), + Toast.LENGTH_LONG).show(); + } + } + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + Log.e(LOG_TAG, throwable.getMessage()); + } + }); } } @@ -315,6 +345,9 @@ public void onMicrophoneClicked(final MicrophoneBarController controller, mMicrophoneBarView.setState(MicrophoneBarController.STATE_STOPPING); MessagingService.stopRecognition(this); break; + case MicrophoneBarController.STATE_DISABLED: + // nothing + break; } } diff --git a/app/src/main/java/ru/yandex/subtitles/utils/ShareUtils.java b/app/src/main/java/ru/yandex/subtitles/utils/ShareUtils.java index e8f625c..ed2cfa5 100644 --- a/app/src/main/java/ru/yandex/subtitles/utils/ShareUtils.java +++ b/app/src/main/java/ru/yandex/subtitles/utils/ShareUtils.java @@ -1,4 +1,4 @@ -/** +/* * Copyright 2015 YA LLC *

* Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,7 +35,7 @@ public final class ShareUtils { private static final String LOG_TAG = "ShareUtils"; - public static final String MIMETYPE_TEXT_PLAIN = "text/plain"; + private static final String MIMETYPE_TEXT_PLAIN = "text/plain"; private static final String MAIL_TO_FORMAT = "mailto:%1$s?subject=%2$s&body=%3$s"; @@ -49,7 +49,7 @@ public static Intent prepareMailToIntent(@NonNull final String[] addresses, // It's better to use Uri.Builder instead of building strings // but Mail.ru app does not work correctly with default 'mailto:' scheme. final String mailToScheme = String.format(MAIL_TO_FORMAT, - TextUtilsExt.join(",", (String[]) addresses), + TextUtilsExt.join(",", (Object[]) addresses), Uri.encode(subject), Uri.encode(body)); final Uri uri = Uri.parse(mailToScheme); diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 5d0f679..1713cea 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -181,5 +181,6 @@ До налаштувань Зрозуміло + На жаль, без цього дозволу ми не можемо використовувати розпізнавання мови diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5867884..7b95839 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -219,5 +219,6 @@ К настройкам Понятно + К сожалению, без данного разрешения мы не можем использовать распознавание речи diff --git a/app/src/test/java/ru/yandex/subtitles/utils/ShareUtilsTest.java b/app/src/test/java/ru/yandex/subtitles/utils/ShareUtilsTest.java new file mode 100644 index 0000000..07165b1 --- /dev/null +++ b/app/src/test/java/ru/yandex/subtitles/utils/ShareUtilsTest.java @@ -0,0 +1,38 @@ +package ru.yandex.subtitles.utils; + +import android.content.Intent; +import android.net.Uri; + +import junit.framework.TestCase; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertThat; + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class ShareUtilsTest extends TestCase { + + @Test + public void testPrepareMailToIntent() throws Exception { + final String[] addresses = {"test1@ya.ru", "test2@ya.ru", "test3@ya.ru"}; + final String subject = "test subject"; + final String body = "test message"; + + Intent intent = ShareUtils.prepareMailToIntent(addresses, subject, body); + + assertThat(intent.getStringExtra(Intent.EXTRA_SUBJECT), equalTo(subject)); + assertThat(intent.getStringExtra(Intent.EXTRA_TEXT), equalTo(body)); + + Uri data = intent.getData(); + assertThat(data.getScheme(), equalTo("mailto")); + assertThat(data.getEncodedSchemeSpecificPart(), equalTo("test1@ya.ru,test2@ya.ru,test3@ya.ru?subject=test%20subject&body=test%20message")); + + assertArrayEquals(intent.getStringArrayExtra(Intent.EXTRA_EMAIL), addresses); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index bcdabf7..89dd0a7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,23 +1,30 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. ext { - compileSdkVersion = 23 - buildToolsVersion = '21.1.2' + minSdkVersion = 15 + targetSdkVersion = 25 + compileSdkVersion = 25 + buildToolsVersion = '26.0.1' applicationId = "ru.yandex.subtitles" + supportVersion = '25.4.0' } buildscript { - repositories { - mavenCentral() + jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.3.0' + classpath 'com.android.tools.build:gradle:2.3.3' } - } allprojects { repositories { - mavenCentral() + jcenter() + maven { url "https://maven.google.com" } + maven { url 'https://maven.fabric.io/public' } + maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } + flatDir { + dirs '../repo' + } } } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1b216b3..c7547b8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Sep 16 15:48:37 FET 2015 +#Sat Oct 21 14:30:01 YEKT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip