Skip to content

Commit 8a86d6e

Browse files
authoredJun 27, 2021
Drag IME to switch between the 3 modes (#91)
Changes: - IME: change UI mode by vertical dragging (instead of pressing the lower-right-corner button) - IME: lower-right-corner button is now only a microphone button (but invisible in the default UI mode) - IME: up/down swipe moves/selects faster - improve UI of combo buttons (underline to indicate selection) - update speechutils (avoids lint error about AUDIO_RECORD permission)
1 parent 8d128b3 commit 8a86d6e

22 files changed

+485
-240
lines changed
 

‎app/build.gradle

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ dependencies {
77
implementation 'com.googlecode.json-simple:json-simple:1.1'
88
implementation 'com.koushikdutta.async:androidasync:3.1.0'
99
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
10-
implementation 'androidx.appcompat:appcompat:1.2.0'
10+
implementation 'androidx.appcompat:appcompat:1.3.0'
1111
implementation 'androidx.preference:preference:1.1.1'
12-
implementation 'androidx.recyclerview:recyclerview:1.2.0'
12+
implementation 'androidx.recyclerview:recyclerview:1.2.1'
1313
// implementation 'androidx.activity:activity:1.3.0-alpha03'
1414
implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
1515
implementation 'com.google.android.material:material:1.3.0'
@@ -27,8 +27,8 @@ android {
2727
applicationId 'ee.ioc.phon.android.speak'
2828
minSdkVersion 21
2929
targetSdkVersion 30
30-
versionCode 1800
31-
versionName '1.8.00'
30+
versionCode 1805
31+
versionName '1.8.05'
3232
vectorDrawables.useSupportLibrary = true
3333
// Keep only en and et resources
3434
resConfigs "en", "et"

‎app/src/main/java/ee/ioc/phon/android/speak/activity/PermissionsRequesterActivity.java

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public void onCreate(Bundle savedInstanceState) {
2727

2828
@Override
2929
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
30+
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
3031
switch (requestCode) {
3132
case PERMISSION_REQUEST_RECORD_AUDIO: {
3233
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

‎app/src/main/java/ee/ioc/phon/android/speak/adapter/ComboButtonsAdapter.kt

+21-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ee.ioc.phon.android.speak.adapter
22

33
import android.content.ComponentName
4+
import android.graphics.Paint
45
import android.os.Build
56
import android.view.LayoutInflater
67
import android.view.View
@@ -11,8 +12,11 @@ import ee.ioc.phon.android.speak.R
1112
import ee.ioc.phon.android.speak.ServiceLanguageChooser
1213
import ee.ioc.phon.android.speak.model.Combo
1314

14-
class ComboButtonsAdapter(private val mListener: ComboButtonsAdapterListener, private val mSlc: ServiceLanguageChooser) : RecyclerView.Adapter<ComboButtonsAdapter.MyViewHolder>() {
15-
private lateinit var mSelectedView: View
15+
class ComboButtonsAdapter(
16+
private val mListener: ComboButtonsAdapterListener,
17+
private val mSlc: ServiceLanguageChooser
18+
) : RecyclerView.Adapter<ComboButtonsAdapter.MyViewHolder>() {
19+
private lateinit var mSelectedView: Button
1620

1721
interface ComboButtonsAdapterListener {
1822
fun onComboChange(language: String, service: ComponentName)
@@ -22,8 +26,10 @@ class ComboButtonsAdapter(private val mListener: ComboButtonsAdapterListener, pr
2226
class MyViewHolder(var mView: Button) : RecyclerView.ViewHolder(mView)
2327

2428
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
25-
return MyViewHolder(LayoutInflater.from(parent.context)
26-
.inflate(R.layout.list_item_combo_button, parent, false) as Button)
29+
return MyViewHolder(
30+
LayoutInflater.from(parent.context)
31+
.inflate(R.layout.list_item_combo_button, parent, false) as Button
32+
)
2733
}
2834

2935
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
@@ -38,9 +44,13 @@ class ComboButtonsAdapter(private val mListener: ComboButtonsAdapterListener, pr
3844
val combo = Combo(context, mSlc[position])
3945
if (mSlc.isSelected(position)) {
4046
mSelectedView = holder.mView
41-
holder.mView.alpha = 1f
47+
mSelectedView.alpha = 1f
48+
mSelectedView.paintFlags = mSelectedView.paintFlags or Paint.UNDERLINE_TEXT_FLAG
49+
mSelectedView.isClickable = false
4250
} else {
4351
holder.mView.alpha = 0.5f
52+
holder.mView.paintFlags = 0
53+
holder.mView.isClickable = true
4454
}
4555
var label = combo.localeAsStr
4656
if (label.isEmpty() || label.equals("und")) {
@@ -50,13 +60,17 @@ class ComboButtonsAdapter(private val mListener: ComboButtonsAdapterListener, pr
5060
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
5161
holder.mView.tooltipText = combo.longLabel
5262
}
53-
// TODO: selected button should not be clickable
63+
5464
holder.mView.setOnClickListener { view: View ->
5565
if (!mSlc.isSelected(position)) {
5666
mSlc.set(position)
5767
mSelectedView.alpha = 0.5f
58-
mSelectedView = view
68+
mSelectedView.paintFlags = 0
69+
mSelectedView.isClickable = true
70+
mSelectedView = view as Button
5971
mSelectedView.alpha = 1f
72+
mSelectedView.paintFlags = holder.mView.paintFlags or Paint.UNDERLINE_TEXT_FLAG
73+
mSelectedView.isClickable = false
6074
mListener.onComboChange(mSlc.language, mSlc.service)
6175
}
6276
}

‎app/src/main/java/ee/ioc/phon/android/speak/service/SpeechInputMethodService.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,9 @@ public void onAction(int editorAction, boolean hide) {
457457
if (hide) {
458458
closeSession();
459459
}
460-
runOp(mCommandEditor.imeAction(editorAction));
460+
if (editorAction > 0) {
461+
runOp(mCommandEditor.imeAction(editorAction));
462+
}
461463
if (hide) {
462464
requestHideSelf(0);
463465
}

‎app/src/main/java/ee/ioc/phon/android/speak/service/WebSocketRecognitionService.java

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import android.speech.SpeechRecognizer;
1212
import android.util.Pair;
1313

14+
import androidx.annotation.RequiresPermission;
15+
1416
import com.koushikdutta.async.http.AsyncHttpClient;
1517
import com.koushikdutta.async.http.WebSocket;
1618

@@ -30,6 +32,8 @@
3032
import ee.ioc.phon.android.speechutils.service.AbstractRecognitionService;
3133
import ee.ioc.phon.android.speechutils.utils.PreferenceUtils;
3234

35+
import static android.Manifest.permission.RECORD_AUDIO;
36+
3337
/**
3438
* Implements RecognitionService, connects to the server via WebSocket.
3539
*/
@@ -67,6 +71,7 @@ public class WebSocketRecognitionService extends AbstractRecognitionService {
6771

6872
private int mNumBytesSent;
6973

74+
@RequiresPermission(RECORD_AUDIO)
7075
@Override
7176
protected void configure(Intent recognizerIntent) throws IOException {
7277
Bundle bundle = getExtras();

‎app/src/main/java/ee/ioc/phon/android/speak/view/ComboSelectorView.kt

+16-7
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import ee.ioc.phon.android.speak.model.CallerInfo
2020
import ee.ioc.phon.android.speak.model.Combo
2121

2222
class ComboSelectorView @JvmOverloads constructor(
23-
context: Context,
24-
attrs: AttributeSet? = null,
25-
defStyleAttr: Int = 0
23+
context: Context,
24+
attrs: AttributeSet? = null,
25+
defStyleAttr: Int = 0
2626
) : LinearLayoutCompat(context, attrs, defStyleAttr) {
2727

2828
private lateinit var mSlc: ServiceLanguageChooser
@@ -35,9 +35,10 @@ class ComboSelectorView @JvmOverloads constructor(
3535

3636
init {
3737
context.theme.obtainStyledAttributes(
38-
attrs,
39-
R.styleable.ComboSelectorView,
40-
0, 0).apply {
38+
attrs,
39+
R.styleable.ComboSelectorView,
40+
0, 0
41+
).apply {
4142

4243
try {
4344
mMinButtons = getInteger(R.styleable.ComboSelectorView_minButtons, 3)
@@ -47,7 +48,15 @@ class ComboSelectorView @JvmOverloads constructor(
4748
}
4849
}
4950

50-
fun init(context: Context, prefs: SharedPreferences?, keys: Int, callerInfo: CallerInfo?, appId: String?, key: Int, listener: ComboSelectorListener) {
51+
fun init(
52+
context: Context,
53+
prefs: SharedPreferences?,
54+
keys: Int,
55+
callerInfo: CallerInfo?,
56+
appId: String?,
57+
key: Int,
58+
listener: ComboSelectorListener
59+
) {
5160
// TODO: check for null? (test by deinstalling a recognizer but not changing K6nele settings)
5261
mSlc = ServiceLanguageChooser(context, prefs, keys, callerInfo, appId)
5362
mListener = listener

‎app/src/main/java/ee/ioc/phon/android/speak/view/OnCursorTouchListener.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ public class OnCursorTouchListener implements View.OnTouchListener {
2424
private final Handler mHandlerPress = new GestureHandler(this);
2525

2626
// TODO: calculate dynamically
27-
private static final float VERTICAL_SPEED = 3.5f;
27+
// TODO: swiping up should be much faster
28+
private static final float VERTICAL_SPEED = 5f;
2829
private static final float DISTANCE_SCALE = 0.04f;
2930

3031
private final int mEdge;
@@ -194,8 +195,8 @@ public boolean onTouch(View v, MotionEvent event) {
194195
}
195196

196197
private void cancelEdge() {
197-
if (mHandler != null) mHandler.removeCallbacks(mTask1);
198-
if (mHandler != null) mHandler.removeCallbacks(mTask2);
198+
mHandler.removeCallbacks(mTask1);
199+
mHandler.removeCallbacks(mTask2);
199200
mIsEdge = false;
200201
}
201202

@@ -224,7 +225,7 @@ private float getDistance(float startX, float startY, MotionEvent ev) {
224225
startY = hy;
225226
}
226227
// add distance from last historical point to event's point
227-
*/
228+
*/
228229
float dx = (ev.getX(0) - startX);
229230
float dy = VERTICAL_SPEED * (ev.getY(0) - startY);
230231
distanceSum += Math.sqrt(dx * dx + dy * dy);

0 commit comments

Comments
 (0)
Failed to load comments.