Extract constants

This commit is contained in:
2020-05-10 16:10:31 +02:00
parent 50c49eeb8f
commit 222fc3b882
5 changed files with 55 additions and 27 deletions

View File

@@ -27,7 +27,9 @@ class MainActivity : AppCompatActivity() {
override fun onReceive(context: Context?, intent: Intent?) { override fun onReceive(context: Context?, intent: Intent?) {
intent?.let { intent?.let {
updateViewAccordingToServiceState( updateViewAccordingToServiceState(
ServiceState.valueOf(it.getStringExtra("STATE") ?: "STOPPED") ServiceState.valueOf(
it.getStringExtra(ForegroundService.STATE) ?: ServiceState.STOPPED.name
)
) )
} }
} }
@@ -39,7 +41,7 @@ class MainActivity : AppCompatActivity() {
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId) { when (item.itemId) {
R.id.open_preferences -> startActivity(Intent(this, PreferencesActivity::class.java)) R.id.open_preferences -> startActivity(Intent(this, PreferencesActivity::class.java))
R.id.open_help -> startActivity(Intent(this, HelpActivity::class.java)) R.id.open_help -> startActivity(Intent(this, HelpActivity::class.java))
} }
@@ -72,7 +74,7 @@ class MainActivity : AppCompatActivity() {
super.onResume() super.onResume()
LocalBroadcastManager LocalBroadcastManager
.getInstance(this) .getInstance(this)
.registerReceiver(receiver, IntentFilter("io.bartek.web.server.CHANGE_STATE")) .registerReceiver(receiver, IntentFilter(ForegroundService.CHANGE_STATE))
updateViewAccordingToServiceState(ForegroundService.state) updateViewAccordingToServiceState(ForegroundService.state)
} }

View File

@@ -0,0 +1,9 @@
package io.bartek.preference
object PreferenceKey {
const val PORT = "preference_port"
const val ENABLE_SAY_ENDPOINT = "preference_enable_say_endpoint"
const val ENABLE_WAVE_ENDPOINT = "preference_enable_wave_endpoint"
const val TTS = "preference_tts"
}

View File

@@ -24,7 +24,9 @@ class PreferencesFragment : PreferenceFragmentCompat() {
override fun onReceive(context: Context?, intent: Intent?) { override fun onReceive(context: Context?, intent: Intent?) {
intent?.let { intent?.let {
updateViewAccordingToServiceState( updateViewAccordingToServiceState(
ServiceState.valueOf(it.getStringExtra("STATE") ?: "STOPPED") ServiceState.valueOf(
it.getStringExtra(ForegroundService.STATE) ?: ServiceState.STOPPED.name
)
) )
} }
} }
@@ -38,7 +40,7 @@ class PreferencesFragment : PreferenceFragmentCompat() {
super.onResume() super.onResume()
LocalBroadcastManager LocalBroadcastManager
.getInstance(context!!) .getInstance(context!!)
.registerReceiver(receiver, IntentFilter("io.bartek.web.server.CHANGE_STATE")) .registerReceiver(receiver, IntentFilter(ForegroundService.CHANGE_STATE))
updateViewAccordingToServiceState(ForegroundService.state) updateViewAccordingToServiceState(ForegroundService.state)
} }
@@ -51,15 +53,19 @@ class PreferencesFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences, rootKey) setPreferencesFromResource(R.xml.preferences, rootKey)
portPreference = findPreference("preference_port")!! portPreference = findPreference(PreferenceKey.PORT)!!
portPreference.setOnBindEditTextListener { it.inputType = InputType.TYPE_CLASS_NUMBER } portPreference.setOnBindEditTextListener { it.inputType = InputType.TYPE_CLASS_NUMBER }
sayEndpointPreference = findPreference("preference_enable_say_endpoint")!! sayEndpointPreference = findPreference(PreferenceKey.ENABLE_SAY_ENDPOINT)!!
waveEndpointPreference = findPreference("preference_enable_wave_endpoint")!! waveEndpointPreference = findPreference(PreferenceKey.ENABLE_WAVE_ENDPOINT)!!
ttsEnginePreference = findPreference("preference_tts")!! ttsEnginePreference = findPreference(PreferenceKey.TTS)!!
ttsEnginePreference.setOnPreferenceClickListener { ttsEnginePreference.setOnPreferenceClickListener {
startActivity(Intent("com.android.settings.TTS_SETTINGS")) startActivity(Intent(ANDROID_TTS_SETTINGS))
true true
} }
updateViewAccordingToServiceState(ForegroundService.state) updateViewAccordingToServiceState(ForegroundService.state)
} }
companion object {
private const val ANDROID_TTS_SETTINGS = "com.android.settings.TTS_SETTINGS"
}
} }

View File

@@ -5,15 +5,13 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Color import android.graphics.Color
import android.os.Binder
import android.os.Build import android.os.Build
import android.os.IBinder
import android.os.PowerManager import android.os.PowerManager
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import io.bartek.MainActivity import io.bartek.MainActivity
import io.bartek.R import io.bartek.R
import io.bartek.preference.PreferenceKey
import io.bartek.web.TTSServer import io.bartek.web.TTSServer
import java.lang.Integer.parseInt
class ForegroundService : Service() { class ForegroundService : Service() {
@@ -22,7 +20,7 @@ class ForegroundService : Service() {
private var isServiceStarted = false private var isServiceStarted = false
private var ttsServer: TTSServer? = null private var ttsServer: TTSServer? = null
private val port: Int private val port: Int
get() = preferences.getInt("preference_port", 8080) get() = preferences.getInt(PreferenceKey.PORT, 8080)
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
@@ -91,7 +89,7 @@ class ForegroundService : Service() {
isServiceStarted = true isServiceStarted = true
wakeLock = wakeLock =
(getSystemService(Context.POWER_SERVICE) as PowerManager).run { (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WebService::lock").apply { newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG).apply {
acquire() acquire()
} }
} }
@@ -119,7 +117,9 @@ class ForegroundService : Service() {
// than to place it as a static field // than to place it as a static field
var state = ServiceState.STOPPED var state = ServiceState.STOPPED
private const val NOTIFICATION_CHANNEL_ID = "TTSService.NOTIFICATION_CHANNEL" private const val NOTIFICATION_CHANNEL_ID = "TTSService.NOTIFICATION_CHANNEL"
const val PORT = "TTSService.PORT" private const val WAKELOCK_TAG = "ForegroundService::lock"
const val CHANGE_STATE = "io.bartek.service.CHANGE_STATE"
const val STATE = "STATE"
const val START = "START" const val START = "START"
const val STOP = "STOP" const val STOP = "STOP"
} }

View File

@@ -7,6 +7,8 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import fi.iki.elonen.NanoHTTPD import fi.iki.elonen.NanoHTTPD
import fi.iki.elonen.NanoHTTPD.Response.Status.* import fi.iki.elonen.NanoHTTPD.Response.Status.*
import io.bartek.preference.PreferenceKey
import io.bartek.service.ForegroundService
import io.bartek.service.ServiceState import io.bartek.service.ServiceState
import io.bartek.tts.TTS import io.bartek.tts.TTS
import org.json.JSONObject import org.json.JSONObject
@@ -23,7 +25,7 @@ class TTSServer(port: Int, private val context: Context) : NanoHTTPD(port),
override fun serve(session: IHTTPSession?): Response { override fun serve(session: IHTTPSession?): Response {
try { try {
session?.let { session?.let {
return when(it.uri) { return when (it.uri) {
"/wave" -> wave(it) "/wave" -> wave(it)
"/say" -> say(it) "/say" -> say(it)
else -> throw ResponseException(NOT_FOUND, "") else -> throw ResponseException(NOT_FOUND, "")
@@ -39,7 +41,7 @@ class TTSServer(port: Int, private val context: Context) : NanoHTTPD(port),
} }
private fun wave(session: IHTTPSession): Response { private fun wave(session: IHTTPSession): Response {
if(!preferences.getBoolean("preference_enable_wave_endpoint", true)) { if (!preferences.getBoolean(PreferenceKey.ENABLE_WAVE_ENDPOINT, true)) {
throw ResponseException(NOT_FOUND, "") throw ResponseException(NOT_FOUND, "")
} }
@@ -47,17 +49,17 @@ class TTSServer(port: Int, private val context: Context) : NanoHTTPD(port),
throw ResponseException(METHOD_NOT_ALLOWED, "") throw ResponseException(METHOD_NOT_ALLOWED, "")
} }
if (session.headers["content-type"]?.let { it != "application/json" } != false) { if (session.headers[CONTENT_TYPE]?.let { it != MIME_JSON } != false) {
throw ResponseException(BAD_REQUEST, "") throw ResponseException(BAD_REQUEST, "")
} }
val (text, language) = getRequestData(session) val (text, language) = getRequestData(session)
val (stream, size) = tts.fetchTTSStream(text, language) val (stream, size) = tts.fetchTTSStream(text, language)
return newFixedLengthResponse(OK, "audio/x-wav", stream, size) return newFixedLengthResponse(OK, MIME_WAVE, stream, size)
} }
private fun say(session: IHTTPSession): Response { private fun say(session: IHTTPSession): Response {
if(!preferences.getBoolean("preference_enable_say_endpoint", true)) { if (!preferences.getBoolean(PreferenceKey.ENABLE_SAY_ENDPOINT, true)) {
throw ResponseException(NOT_FOUND, "") throw ResponseException(NOT_FOUND, "")
} }
@@ -65,7 +67,7 @@ class TTSServer(port: Int, private val context: Context) : NanoHTTPD(port),
throw ResponseException(METHOD_NOT_ALLOWED, "") throw ResponseException(METHOD_NOT_ALLOWED, "")
} }
if (session.headers["content-type"]?.let { it != "application/json" } != false) { if (session.headers[CONTENT_TYPE]?.let { it != MIME_JSON } != false) {
throw ResponseException(BAD_REQUEST, "") throw ResponseException(BAD_REQUEST, "")
} }
@@ -78,7 +80,10 @@ class TTSServer(port: Int, private val context: Context) : NanoHTTPD(port),
val map = mutableMapOf<String, String>() val map = mutableMapOf<String, String>()
session.parseBody(map) session.parseBody(map)
val json = JSONObject(map["postData"] ?: "{}") val json = JSONObject(map["postData"] ?: "{}")
val language = Locale(json.optString("language", "en_US")) val language = json.optString("language")
.takeIf { it.isNotBlank() }
?.let { Locale(it) }
?: Locale.US
val text = json.optString("text") ?: throw ResponseException(BAD_REQUEST, "") val text = json.optString("text") ?: throw ResponseException(BAD_REQUEST, "")
return TTSRequestData(text, language) return TTSRequestData(text, language)
} }
@@ -89,8 +94,8 @@ class TTSServer(port: Int, private val context: Context) : NanoHTTPD(port),
super.start() super.start()
LocalBroadcastManager LocalBroadcastManager
.getInstance(context) .getInstance(context)
.sendBroadcast(Intent("io.bartek.web.server.CHANGE_STATE").also { .sendBroadcast(Intent(ForegroundService.CHANGE_STATE).also {
it.putExtra("STATE", ServiceState.RUNNING.name) it.putExtra(ForegroundService.STATE, ServiceState.RUNNING.name)
}) })
} }
@@ -98,8 +103,14 @@ class TTSServer(port: Int, private val context: Context) : NanoHTTPD(port),
super.stop() super.stop()
LocalBroadcastManager LocalBroadcastManager
.getInstance(context) .getInstance(context)
.sendBroadcast(Intent("io.bartek.web.server.CHANGE_STATE").also { .sendBroadcast(Intent(ForegroundService.CHANGE_STATE).also {
it.putExtra("STATE", ServiceState.STOPPED.name) it.putExtra(ForegroundService.STATE, ServiceState.STOPPED.name)
}) })
} }
companion object {
private const val MIME_JSON = "application/json"
private const val MIME_WAVE = "audio/x-wav"
private const val CONTENT_TYPE = "content-type"
}
} }