diff --git a/android/app/src/main/java/io/github/transui/android/AppConfig.java b/android/app/src/main/java/io/github/transui/android/AppConfig.java index 0eeabd0..0adbfa0 100644 --- a/android/app/src/main/java/io/github/transui/android/AppConfig.java +++ b/android/app/src/main/java/io/github/transui/android/AppConfig.java @@ -1,36 +1,23 @@ package io.github.transui.android; final class AppConfig { - final String remoteEndpoint; - final String remoteModel; - final String remoteKey; - final String localEndpoint; - final String localModel; - final String localKey; + final String endpoint; + final String model; + final String apiKey; final String prompt; - final boolean remoteFirst; AppConfig( - String remoteEndpoint, - String remoteModel, - String remoteKey, - String localEndpoint, - String localModel, - String localKey, - String prompt, - boolean remoteFirst) { - this.remoteEndpoint = remoteEndpoint; - this.remoteModel = remoteModel; - this.remoteKey = remoteKey; - this.localEndpoint = localEndpoint; - this.localModel = localModel; - this.localKey = localKey; + String endpoint, + String model, + String apiKey, + String prompt) { + this.endpoint = endpoint; + this.model = model; + this.apiKey = apiKey; this.prompt = prompt; - this.remoteFirst = remoteFirst; } boolean hasUsableEndpoint() { - if (remoteFirst && !remoteEndpoint.isEmpty()) return true; - return !localEndpoint.isEmpty(); + return !endpoint.isEmpty(); } } diff --git a/android/app/src/main/java/io/github/transui/android/ConfigRepository.java b/android/app/src/main/java/io/github/transui/android/ConfigRepository.java index 427e91f..b25a465 100644 --- a/android/app/src/main/java/io/github/transui/android/ConfigRepository.java +++ b/android/app/src/main/java/io/github/transui/android/ConfigRepository.java @@ -12,34 +12,38 @@ final class ConfigRepository { ConfigRepository(Context context) { preferences = context.getApplicationContext().getSharedPreferences(PREFS, Context.MODE_PRIVATE); + removeObsoleteLocalSettings(); } AppConfig load() { - String remoteKey = decryptOrEmpty(preferences.getString("remote_key", "")); - String localKey = decryptOrEmpty(preferences.getString("local_key", "")); return new AppConfig( preferences.getString("remote_endpoint", ""), preferences.getString("remote_model", ""), - remoteKey, - preferences.getString("local_endpoint", "http://localhost:8080"), - preferences.getString("local_model", ""), - localKey, - preferences.getString("prompt", ""), - preferences.getBoolean("remote_first", true)); + decryptOrEmpty(preferences.getString("remote_key", "")), + preferences.getString("prompt", "")); } void save(AppConfig config) throws GeneralSecurityException, IOException { - String remoteKey = SecretStore.encrypt(config.remoteKey); - String localKey = SecretStore.encrypt(config.localKey); preferences.edit() - .putString("remote_endpoint", config.remoteEndpoint) - .putString("remote_model", config.remoteModel) - .putString("remote_key", remoteKey) - .putString("local_endpoint", config.localEndpoint) - .putString("local_model", config.localModel) - .putString("local_key", localKey) + .putString("remote_endpoint", config.endpoint) + .putString("remote_model", config.model) + .putString("remote_key", SecretStore.encrypt(config.apiKey)) .putString("prompt", config.prompt) - .putBoolean("remote_first", config.remoteFirst) + .apply(); + } + + private void removeObsoleteLocalSettings() { + if (!preferences.contains("local_endpoint") + && !preferences.contains("local_model") + && !preferences.contains("local_key") + && !preferences.contains("remote_first")) { + return; + } + preferences.edit() + .remove("local_endpoint") + .remove("local_model") + .remove("local_key") + .remove("remote_first") .apply(); } diff --git a/android/app/src/main/java/io/github/transui/android/MainActivity.java b/android/app/src/main/java/io/github/transui/android/MainActivity.java index 78d1629..7f7b86e 100644 --- a/android/app/src/main/java/io/github/transui/android/MainActivity.java +++ b/android/app/src/main/java/io/github/transui/android/MainActivity.java @@ -10,7 +10,6 @@ import android.os.Bundle; import android.provider.Settings; import android.widget.Button; import android.widget.EditText; -import android.widget.Switch; import android.widget.TextView; import android.widget.Toast; @@ -20,14 +19,12 @@ import java.security.GeneralSecurityException; public final class MainActivity extends Activity { private static final int MICROPHONE_REQUEST = 1; - private EditText remoteEndpoint; - private EditText remoteModel; - private EditText remoteKey; - private EditText localEndpoint; - private EditText localModel; - private EditText localKey; + private static final String ACTION_LANGUAGE_SETTINGS = "android.settings.LANGUAGE_SETTINGS"; + + private EditText endpoint; + private EditText model; + private EditText apiKey; private EditText prompt; - private Switch remoteFirst; private TextView providerStatus; private Button microphone; private ConfigRepository repository; @@ -42,9 +39,7 @@ public final class MainActivity extends Activity { findViewById(R.id.save).setOnClickListener(view -> saveConfig()); microphone.setOnClickListener(view -> requestMicrophone()); - findViewById(R.id.choose_provider).setOnClickListener(view -> { - if (saveConfig()) openVoiceInputSettings(); - }); + findViewById(R.id.language_settings).setOnClickListener(view -> openLanguageSettings()); } @Override @@ -60,39 +55,27 @@ public final class MainActivity extends Activity { } private void bindViews() { - remoteEndpoint = findViewById(R.id.remote_endpoint); - remoteModel = findViewById(R.id.remote_model); - remoteKey = findViewById(R.id.remote_key); - localEndpoint = findViewById(R.id.local_endpoint); - localModel = findViewById(R.id.local_model); - localKey = findViewById(R.id.local_key); + endpoint = findViewById(R.id.endpoint); + model = findViewById(R.id.model); + apiKey = findViewById(R.id.api_key); prompt = findViewById(R.id.prompt); - remoteFirst = findViewById(R.id.remote_first); providerStatus = findViewById(R.id.provider_status); microphone = findViewById(R.id.microphone); } private void showConfig(AppConfig config) { - remoteEndpoint.setText(config.remoteEndpoint); - remoteModel.setText(config.remoteModel); - remoteKey.setText(config.remoteKey); - localEndpoint.setText(config.localEndpoint); - localModel.setText(config.localModel); - localKey.setText(config.localKey); + endpoint.setText(config.endpoint); + model.setText(config.model); + apiKey.setText(config.apiKey); prompt.setText(config.prompt); - remoteFirst.setChecked(config.remoteFirst); } private boolean saveConfig() { AppConfig config = new AppConfig( - value(remoteEndpoint).trim(), - value(remoteModel).trim(), - value(remoteKey).trim(), - value(localEndpoint).trim(), - value(localModel).trim(), - value(localKey).trim(), - value(prompt), - remoteFirst.isChecked()); + value(endpoint).trim(), + value(model).trim(), + value(apiKey).trim(), + value(prompt)); try { repository.save(config); Toast.makeText(this, R.string.settings_saved, Toast.LENGTH_SHORT).show(); @@ -109,11 +92,17 @@ public final class MainActivity extends Activity { } } - private void openVoiceInputSettings() { + private void openLanguageSettings() { try { - startActivity(new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS)); - } catch (ActivityNotFoundException error) { - Toast.makeText(this, R.string.voice_settings_unavailable, Toast.LENGTH_LONG).show(); + startActivity(new Intent(ACTION_LANGUAGE_SETTINGS)); + return; + } catch (ActivityNotFoundException ignored) { + // Older Android builds expose the combined Languages and input page here. + } + try { + startActivity(new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS)); + } catch (ActivityNotFoundException ignored) { + Toast.makeText(this, R.string.language_settings_unavailable, Toast.LENGTH_LONG).show(); } } diff --git a/android/app/src/main/java/io/github/transui/android/TranscriptionClient.java b/android/app/src/main/java/io/github/transui/android/TranscriptionClient.java index 9a02ac3..5436d6b 100644 --- a/android/app/src/main/java/io/github/transui/android/TranscriptionClient.java +++ b/android/app/src/main/java/io/github/transui/android/TranscriptionClient.java @@ -20,25 +20,10 @@ final class TranscriptionClient { private volatile HttpURLConnection activeConnection; Result transcribe(AppConfig config, byte[] wav) { - Result remoteResult = null; - if (config.remoteFirst && !config.remoteEndpoint.isEmpty()) { - remoteResult = request( - config.remoteEndpoint, config.remoteModel, config.remoteKey, config.prompt, wav); - if (remoteResult.text != null) return remoteResult; + if (config.endpoint.isEmpty()) { + return Result.error("No transcription endpoint is configured", SpeechRecognizer.ERROR_CLIENT); } - - if (!config.localEndpoint.isEmpty()) { - Result localResult = request( - config.localEndpoint, config.localModel, config.localKey, config.prompt, wav); - if (localResult.text != null || remoteResult == null) return localResult; - return Result.error( - remoteResult.error + "; local: " + localResult.error, - localResult.errorCode); - } - - return remoteResult != null - ? remoteResult - : Result.error("No transcription endpoint is configured", SpeechRecognizer.ERROR_CLIENT); + return request(config.endpoint, config.model, config.apiKey, config.prompt, wav); } void cancel() { diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml index a8397c4..b2524eb 100644 --- a/android/app/src/main/res/layout/activity_main.xml +++ b/android/app/src/main/res/layout/activity_main.xml @@ -48,51 +48,26 @@ + android:text="@string/server" /> - - - - - - - - @@ -109,15 +84,6 @@ android:maxLines="3" android:singleLine="false" /> - -