2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-22 09:58:08 +00:00

Add support for Bigscreen STT using android's inbuilt speech engine

This commit is contained in:
Aditya Mehra 2020-06-06 21:39:41 +00:00 committed by Philip Cohn-Cort
parent d5946faf3d
commit ee5c75e10a
6 changed files with 102 additions and 3 deletions

View File

@ -37,6 +37,7 @@
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M 16.766667,8.7612589 v 2.5197071 c 0,2.182796 -2.138935,3.959544 -4.766667,3.959544 -2.6277329,0 -4.7666673,-1.776748 -4.7666673,-3.959544 V 8.7612589 H 5.4999999 v 2.5197071 c 0,2.732804 2.4587328,4.991913 5.6333321,5.345392 v 2.933663 H 8.0999999 v 1.439831 H 15.9 V 19.560021 H 12.866667 V 16.626358 C 16.041267,16.272879 18.5,14.01377 18.5,11.280966 V 8.7612589 Z M 12,13.800679 A 3.0333332,2.5197106 0 0 1 8.9666671,11.280966 V 5.5216304 a 3.0333332,2.5197106 0 1 1 6.0666649,0 V 11.280966 A 3.0333332,2.5197106 0 0 1 12,13.800679 Z"/>
</vector>

View File

@ -25,6 +25,16 @@
android:src="@drawable/ic_arrow_upward_black_24dp"
android:theme="@style/DisableableButton" />
<ImageButton
android:id="@+id/mic_button"
grid:layout_column="2"
grid:layout_columnWeight="1"
grid:layout_row="0"
grid:layout_rowWeight="1"
android:contentDescription="@string/bigscreen_mic"
android:src="@drawable/ic_mic_black"
android:theme="@style/DisableableButton" />
<ImageButton
android:id="@+id/left_button"
grid:layout_column="0"

View File

@ -366,8 +366,11 @@
<string name="bigscreen_select">Select</string>
<string name="bigscreen_right">Right</string>
<string name="bigscreen_down">Down</string>
<string name="bigscreen_mic">Mic</string>
<string name="pref_plugin_bigscreen">Bigscreen remote</string>
<string name="pref_plugin_bigscreen_desc">Use your device as a remote for Plasma Bigscreen</string>
<string name="bigscreen_optional_permission_explanation">To share microphone input from your phone you need to give access to the phone\'s audio input</string>
<string name="bigscreen_speech_extra_prompt">Speech</string>
<string name="theme_dialog_title">Choose theme</string>
<string-array name="theme_list">
@ -381,4 +384,5 @@
<item>light</item>
<item>dark</item>
</string-array>
</resources>

View File

@ -21,16 +21,29 @@
package org.kde.kdeconnect.Plugins.BigscreenPlugin;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
import android.view.View;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.UserInterface.MainActivity;
import org.kde.kdeconnect.UserInterface.PermissionsAlertDialogFragment;
import org.kde.kdeconnect.UserInterface.ThemeUtil;
import org.kde.kdeconnect_tp.R;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class BigscreenActivity extends AppCompatActivity {
private static final int REQUEST_SPEECH = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -39,14 +52,57 @@ public class BigscreenActivity extends AppCompatActivity {
final String deviceId = getIntent().getStringExtra("deviceId");
BackgroundService.RunWithPlugin(this, deviceId, org.kde.kdeconnect.Plugins.BigscreenPlugin.BigscreenPlugin.class, plugin -> runOnUiThread(() -> {
if (!SpeechRecognizer.isRecognitionAvailable(this)) {
findViewById(R.id.mic_button).setEnabled(false);
findViewById(R.id.mic_button).setVisibility(View.INVISIBLE);
}
BackgroundService.RunWithPlugin(this, deviceId, BigscreenPlugin.class, plugin -> runOnUiThread(() -> {
findViewById(R.id.left_button).setOnClickListener(v -> plugin.sendLeft());
findViewById(R.id.right_button).setOnClickListener(v -> plugin.sendRight());
findViewById(R.id.up_button).setOnClickListener(v -> plugin.sendUp());
findViewById(R.id.down_button).setOnClickListener(v -> plugin.sendDown());
findViewById(R.id.select_button).setOnClickListener(v -> plugin.sendSelect());
findViewById(R.id.home_button).setOnClickListener(v -> plugin.sendHome());
findViewById(R.id.mic_button).setOnClickListener(v -> {
if (plugin.hasMicPermission()) {
activateSTT();
} else {
new PermissionsAlertDialogFragment.Builder()
.setTitle(plugin.getDisplayName())
.setMessage(R.string.bigscreen_optional_permission_explanation)
.setPositiveButton(R.string.ok)
.setNegativeButton(R.string.cancel)
.setPermissions(new String[]{Manifest.permission.RECORD_AUDIO})
.setRequestCode(MainActivity.RESULT_NEEDS_RELOAD)
.create().show(getSupportFragmentManager(), null);
}
});
}));
}
public void activateSTT() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, R.string.bigscreen_speech_extra_prompt);
startActivityForResult(intent, REQUEST_SPEECH);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_SPEECH) {
if (resultCode == Activity.RESULT_OK && data != null) {
ArrayList<String> result = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
if (result.get(0) != null) {
final String deviceId = getIntent().getStringExtra("deviceId");
BackgroundService.RunWithPlugin(this, deviceId, BigscreenPlugin.class, plugin -> runOnUiThread(() -> {
plugin.sendSTT(result.get(0));
}));
}
}
}
}
}

View File

@ -22,6 +22,7 @@
package org.kde.kdeconnect.Plugins.BigscreenPlugin;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
@ -41,9 +42,11 @@ import static org.kde.kdeconnect.Plugins.MousePadPlugin.KeyListenerView.SpecialK
public class BigscreenPlugin extends Plugin {
private final static String PACKET_TYPE_MOUSEPAD_REQUEST = "kdeconnect.mousepad.request";
private final static String PACKET_TYPE_BIGSCREEN_STT = "kdeconnect.bigscreen.stt";
@Override
public boolean onCreate() {
optionalPermissionExplanation = R.string.bigscreen_optional_permission_explanation;
return device.getDeviceType().equals(Device.DeviceType.Tv);
}
@ -85,11 +88,11 @@ public class BigscreenPlugin extends Plugin {
}
@Override
public String[] getSupportedPacketTypes() { return new String[0]; }
public String[] getSupportedPacketTypes() { return new String[]{PACKET_TYPE_BIGSCREEN_STT}; }
@Override
public String[] getOutgoingPacketTypes() {
return new String[]{PACKET_TYPE_MOUSEPAD_REQUEST};
return new String[]{PACKET_TYPE_MOUSEPAD_REQUEST, PACKET_TYPE_BIGSCREEN_STT};
}
@Override
@ -97,6 +100,15 @@ public class BigscreenPlugin extends Plugin {
return context.getString(R.string.pref_plugin_bigscreen);
}
public String[] getOptionalPermissions() {
return new String[]{Manifest.permission.RECORD_AUDIO};
}
public Boolean hasMicPermission() {
return isPermissionGranted(Manifest.permission.RECORD_AUDIO);
}
public void sendLeft() {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_MOUSEPAD_REQUEST);
np.set("specialKey", SpecialKeysMap.get(KeyEvent.KEYCODE_DPAD_LEFT));
@ -133,4 +145,11 @@ public class BigscreenPlugin extends Plugin {
np.set("specialKey", SpecialKeysMap.get(KeyEvent.KEYCODE_F4));
device.sendPacket(np);
}
public void sendSTT(String content) {
NetworkPacket np = new NetworkPacket(PACKET_TYPE_BIGSCREEN_STT);
np.set("type", "stt");
np.set("content", content);
device.sendPacket(np);
}
}