Add additional info about server address to notification and main activity
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
package io.bartek.ttsserver.core.sonos.queue
|
package io.bartek.ttsserver.core.sonos.queue
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import io.bartek.ttsserver.ui.preference.PreferenceKey
|
|
||||||
import io.bartek.ttsserver.core.sonos.worker.SonosWorker
|
import io.bartek.ttsserver.core.sonos.worker.SonosWorker
|
||||||
import io.bartek.ttsserver.core.tts.engine.TTSEngine
|
import io.bartek.ttsserver.core.tts.engine.TTSEngine
|
||||||
import io.bartek.ttsserver.core.util.NetworkUtil
|
import io.bartek.ttsserver.core.util.NetworkUtil
|
||||||
@@ -9,28 +7,14 @@ import io.bartek.ttsserver.core.web.dto.SonosDTO
|
|||||||
import java.util.concurrent.BlockingQueue
|
import java.util.concurrent.BlockingQueue
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
|
|
||||||
class SonosQueue(
|
class SonosQueue(private val tts: TTSEngine, private val networkUtil: NetworkUtil) {
|
||||||
private val tts: TTSEngine,
|
|
||||||
private val networkUtil: NetworkUtil,
|
|
||||||
private val preferences: SharedPreferences
|
|
||||||
) {
|
|
||||||
private val queue: BlockingQueue<SonosDTO> = LinkedBlockingQueue()
|
private val queue: BlockingQueue<SonosDTO> = LinkedBlockingQueue()
|
||||||
private var consumer: Thread? = null
|
private var consumer: Thread? = null
|
||||||
private val host: String
|
|
||||||
get() = networkUtil.getIpAddress()
|
|
||||||
private val port: Int
|
|
||||||
get() = preferences.getInt(PreferenceKey.PORT, 8080)
|
|
||||||
|
|
||||||
fun run() {
|
fun run() {
|
||||||
consumer?.interrupt()
|
consumer?.interrupt()
|
||||||
consumer = Thread(
|
consumer = Thread(SonosWorker(tts, networkUtil.serverAddress, queue))
|
||||||
SonosWorker(
|
.also { it.name = "SonosQueue" }
|
||||||
tts,
|
|
||||||
host,
|
|
||||||
port,
|
|
||||||
queue
|
|
||||||
)
|
|
||||||
).also { it.name = "SonosQueue" }
|
|
||||||
consumer?.start()
|
consumer?.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ import java.util.concurrent.BlockingQueue
|
|||||||
|
|
||||||
class SonosWorker(
|
class SonosWorker(
|
||||||
private val tts: TTSEngine,
|
private val tts: TTSEngine,
|
||||||
private val host: String,
|
private val address: String,
|
||||||
private val port: Int,
|
|
||||||
private val queue: BlockingQueue<SonosDTO>
|
private val queue: BlockingQueue<SonosDTO>
|
||||||
) : Runnable {
|
) : Runnable {
|
||||||
|
|
||||||
@@ -26,7 +25,7 @@ class SonosWorker(
|
|||||||
SonosDiscovery.discover().firstOrNull { it.zoneGroupState.name == data.zone }?.let {
|
SonosDiscovery.discover().firstOrNull { it.zoneGroupState.name == data.zone }?.let {
|
||||||
val file = tts.createTTSFile(data.text, data.language)
|
val file = tts.createTTSFile(data.text, data.language)
|
||||||
val filename = file.name
|
val filename = file.name
|
||||||
val url = "http://$host:$port/sonos/$filename"
|
val url = "$address/sonos/$filename"
|
||||||
it.clip(url, data.volume, "")
|
it.clip(url, data.volume, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,11 +2,16 @@ package io.bartek.ttsserver.core.util
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Context.WIFI_SERVICE
|
import android.content.Context.WIFI_SERVICE
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.net.wifi.WifiManager
|
import android.net.wifi.WifiManager
|
||||||
|
import io.bartek.ttsserver.ui.preference.PreferenceKey
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
|
|
||||||
|
|
||||||
class NetworkUtil(private val context: Context) {
|
class NetworkUtil(private val context: Context, private val preferences: SharedPreferences) {
|
||||||
|
val serverAddress: String
|
||||||
|
get() = "http://${getIpAddress()}:${preferences.getInt(PreferenceKey.PORT, 8000)}"
|
||||||
|
|
||||||
fun getIpAddress(): String {
|
fun getIpAddress(): String {
|
||||||
return (context.getApplicationContext().getSystemService(WIFI_SERVICE) as WifiManager).let {
|
return (context.getApplicationContext().getSystemService(WIFI_SERVICE) as WifiManager).let {
|
||||||
inetAddress(it.dhcpInfo.ipAddress).toString().substring(1)
|
inetAddress(it.dhcpInfo.ipAddress).toString().substring(1)
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import android.speech.tts.TextToSpeech
|
|||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import io.bartek.ttsserver.service.notification.ForegroundNotificationFactory
|
|
||||||
import io.bartek.ttsserver.core.sonos.queue.SonosQueue
|
import io.bartek.ttsserver.core.sonos.queue.SonosQueue
|
||||||
import io.bartek.ttsserver.core.tts.engine.TTSEngine
|
import io.bartek.ttsserver.core.tts.engine.TTSEngine
|
||||||
import io.bartek.ttsserver.core.tts.status.TTSStatusHolder
|
import io.bartek.ttsserver.core.tts.status.TTSStatusHolder
|
||||||
import io.bartek.ttsserver.core.util.NetworkUtil
|
import io.bartek.ttsserver.core.util.NetworkUtil
|
||||||
import io.bartek.ttsserver.core.web.server.WebServerFactory
|
import io.bartek.ttsserver.core.web.server.WebServerFactory
|
||||||
|
import io.bartek.ttsserver.service.notification.ForegroundNotificationFactory
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@@ -38,13 +38,12 @@ class TTSModule {
|
|||||||
context: Context,
|
context: Context,
|
||||||
tts: TTSEngine,
|
tts: TTSEngine,
|
||||||
sonos: SonosQueue
|
sonos: SonosQueue
|
||||||
) =
|
) = WebServerFactory(
|
||||||
WebServerFactory(
|
preferences,
|
||||||
preferences,
|
context,
|
||||||
context,
|
tts,
|
||||||
tts,
|
sonos
|
||||||
sonos
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -52,17 +51,17 @@ class TTSModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun networkUtil(context: Context) = NetworkUtil(context)
|
fun networkUtil(context: Context, preferences: SharedPreferences) =
|
||||||
|
NetworkUtil(context, preferences)
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun sonosQueue(tts: TTSEngine, networkUtil: NetworkUtil, preferences: SharedPreferences) =
|
fun sonosQueue(tts: TTSEngine, networkUtil: NetworkUtil) = SonosQueue(tts, networkUtil)
|
||||||
SonosQueue(tts, networkUtil, preferences)
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun foregroundNotificationFactory(context: Context) =
|
fun foregroundNotificationFactory(
|
||||||
ForegroundNotificationFactory(
|
context: Context,
|
||||||
context
|
networkUtil: NetworkUtil
|
||||||
)
|
) = ForegroundNotificationFactory(context, networkUtil)
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,8 @@ package io.bartek.ttsserver.service.foreground
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import dagger.android.DaggerService
|
import dagger.android.DaggerService
|
||||||
import io.bartek.ttsserver.ui.preference.PreferenceKey
|
|
||||||
import io.bartek.ttsserver.core.web.server.WebServer
|
import io.bartek.ttsserver.core.web.server.WebServer
|
||||||
import io.bartek.ttsserver.core.web.server.WebServerFactory
|
import io.bartek.ttsserver.core.web.server.WebServerFactory
|
||||||
import io.bartek.ttsserver.service.notification.ForegroundNotificationFactory
|
import io.bartek.ttsserver.service.notification.ForegroundNotificationFactory
|
||||||
@@ -18,11 +16,6 @@ class ForegroundService : DaggerService() {
|
|||||||
private var wakeLock: PowerManager.WakeLock? = null
|
private var wakeLock: PowerManager.WakeLock? = null
|
||||||
private var isServiceStarted = false
|
private var isServiceStarted = false
|
||||||
private var webServer: WebServer? = null
|
private var webServer: WebServer? = null
|
||||||
private val port: Int
|
|
||||||
get() = preferences.getInt(PreferenceKey.PORT, 8080)
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var preferences: SharedPreferences
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var webServerFactory: WebServerFactory
|
lateinit var webServerFactory: WebServerFactory
|
||||||
@@ -32,7 +25,7 @@ class ForegroundService : DaggerService() {
|
|||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
startForeground(1, notificationFactory.createForegroundNotification(port))
|
startForeground(1, notificationFactory.createForegroundNotification())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent) = null
|
override fun onBind(intent: Intent) = null
|
||||||
|
|||||||
@@ -9,25 +9,32 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import io.bartek.R
|
import io.bartek.R
|
||||||
|
import io.bartek.ttsserver.core.util.NetworkUtil
|
||||||
import io.bartek.ttsserver.ui.main.MainActivity
|
import io.bartek.ttsserver.ui.main.MainActivity
|
||||||
|
|
||||||
class ForegroundNotificationFactory(private val context: Context) {
|
class ForegroundNotificationFactory(
|
||||||
|
private val context: Context,
|
||||||
|
private val networkUtil: NetworkUtil
|
||||||
|
) {
|
||||||
private val oreo: Boolean
|
private val oreo: Boolean
|
||||||
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||||
|
|
||||||
fun createForegroundNotification(port: Int): Notification {
|
private val notificationContent: String
|
||||||
|
get() = context.getString(R.string.service_notification_text, networkUtil.serverAddress)
|
||||||
|
|
||||||
|
fun createForegroundNotification(): Notification {
|
||||||
createNotificationChannel()
|
createNotificationChannel()
|
||||||
return buildNotification(port, createPendingIntent())
|
return buildNotification(createPendingIntent())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
private fun buildNotification(port: Int, pendingIntent: PendingIntent?) =
|
private fun buildNotification(pendingIntent: PendingIntent?) =
|
||||||
provideNotificationBuilder()
|
provideNotificationBuilder()
|
||||||
.setContentTitle(context.resources.getString(R.string.service_notification_title))
|
.setContentTitle(context.resources.getString(R.string.service_notification_title))
|
||||||
.setContentText(context.resources.getString(R.string.service_notification_text, port))
|
.setContentText(notificationContent)
|
||||||
.setContentIntent(pendingIntent)
|
.setContentIntent(pendingIntent)
|
||||||
.setSmallIcon(R.drawable.ic_foreground_service)
|
.setSmallIcon(R.drawable.ic_foreground_service)
|
||||||
.setTicker(context.getString(R.string.service_notification_text, port))
|
.setTicker(notificationContent)
|
||||||
.setPriority(Notification.PRIORITY_HIGH) // for under android 26 compatibility
|
.setPriority(Notification.PRIORITY_HIGH) // for under android 26 compatibility
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
@@ -57,7 +64,8 @@ class ForegroundNotificationFactory(private val context: Context) {
|
|||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
private fun provideNotificationBuilder() =
|
private fun provideNotificationBuilder() =
|
||||||
if (oreo) Notification.Builder(context,
|
if (oreo) Notification.Builder(
|
||||||
|
context,
|
||||||
NOTIFICATION_CHANNEL_ID
|
NOTIFICATION_CHANNEL_ID
|
||||||
)
|
)
|
||||||
else Notification.Builder(context)
|
else Notification.Builder(context)
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package io.bartek.ttsserver.ui.main
|
package io.bartek.ttsserver.ui.main
|
||||||
|
|
||||||
import android.content.BroadcastReceiver
|
import android.content.*
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.IntentFilter
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
@@ -14,20 +11,28 @@ import androidx.appcompat.widget.AppCompatImageButton
|
|||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
import dagger.android.support.DaggerAppCompatActivity
|
import dagger.android.support.DaggerAppCompatActivity
|
||||||
import io.bartek.R
|
import io.bartek.R
|
||||||
import io.bartek.ttsserver.ui.help.HelpActivity
|
import io.bartek.ttsserver.core.util.NetworkUtil
|
||||||
import io.bartek.ttsserver.ui.preference.PreferencesActivity
|
|
||||||
import io.bartek.ttsserver.service.foreground.ForegroundService
|
import io.bartek.ttsserver.service.foreground.ForegroundService
|
||||||
import io.bartek.ttsserver.service.state.ServiceState
|
import io.bartek.ttsserver.service.state.ServiceState
|
||||||
|
import io.bartek.ttsserver.ui.help.HelpActivity
|
||||||
|
import io.bartek.ttsserver.ui.preference.PreferencesActivity
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : DaggerAppCompatActivity() {
|
class MainActivity : DaggerAppCompatActivity() {
|
||||||
private lateinit var serverControlButton: AppCompatImageButton
|
private lateinit var serverControlButton: AppCompatImageButton
|
||||||
|
private lateinit var serverStatus: TextView
|
||||||
private lateinit var promptText: TextView
|
private lateinit var promptText: TextView
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var context: Context
|
lateinit var context: Context
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var preferences: SharedPreferences
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var networkUtil: NetworkUtil
|
||||||
|
|
||||||
private val receiver = object : BroadcastReceiver() {
|
private val receiver = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
(intent?.getStringExtra(ForegroundService.STATE) ?: ServiceState.STOPPED.name)
|
(intent?.getStringExtra(ForegroundService.STATE) ?: ServiceState.STOPPED.name)
|
||||||
@@ -55,10 +60,13 @@ class MainActivity : DaggerAppCompatActivity() {
|
|||||||
when (newState) {
|
when (newState) {
|
||||||
ServiceState.STOPPED -> {
|
ServiceState.STOPPED -> {
|
||||||
serverControlButton.setImageResource(R.drawable.ic_power_off)
|
serverControlButton.setImageResource(R.drawable.ic_power_off)
|
||||||
|
serverStatus.text = getString(R.string.main_activity_server_status_down)
|
||||||
promptText.text = getString(R.string.main_activity_prompt_to_run)
|
promptText.text = getString(R.string.main_activity_prompt_to_run)
|
||||||
}
|
}
|
||||||
ServiceState.RUNNING -> {
|
ServiceState.RUNNING -> {
|
||||||
serverControlButton.setImageResource(R.drawable.ic_power_on)
|
serverControlButton.setImageResource(R.drawable.ic_power_on)
|
||||||
|
serverStatus.text =
|
||||||
|
getString(R.string.main_activity_server_status_up, networkUtil.serverAddress)
|
||||||
promptText.text = getString(R.string.main_activity_prompt_to_stop)
|
promptText.text = getString(R.string.main_activity_prompt_to_stop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,6 +76,7 @@ class MainActivity : DaggerAppCompatActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
serverControlButton = findViewById(R.id.server_control_button)
|
serverControlButton = findViewById(R.id.server_control_button)
|
||||||
|
serverStatus = findViewById(R.id.server_status)
|
||||||
promptText = findViewById(R.id.prompt_text)
|
promptText = findViewById(R.id.prompt_text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,17 @@
|
|||||||
tools:context=".ttsserver.ui.main.MainActivity">
|
tools:context=".ttsserver.ui.main.MainActivity">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/prompt_text"
|
android:id="@+id/server_status"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="20dp"
|
android:layout_marginTop="20dp"
|
||||||
|
android:text="@string/main_activity_server_status_down"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/prompt_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/main_activity_prompt_to_run"
|
android:text="@string/main_activity_prompt_to_run"
|
||||||
android:textAlignment="center" />
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
<string name="permission_http_server_label">booting up TTS HTTP server</string>
|
<string name="permission_http_server_label">booting up TTS HTTP server</string>
|
||||||
<string name="permission_http_server_description">Allows application to run HTTP server which provides a TTS services.</string>
|
<string name="permission_http_server_description">Allows application to run HTTP server which provides a TTS services.</string>
|
||||||
|
|
||||||
<string name="main_activity_run">Run</string>
|
<string name="main_activity_server_status_down">The server is down</string>
|
||||||
<string name="main_activity_stop">Stop</string>
|
<string name="main_activity_server_status_up">The server is up: %1$s</string>
|
||||||
<string name="main_activity_prompt_to_run">Tap power on button to run the server</string>
|
<string name="main_activity_prompt_to_run">Tap power on button to run the server</string>
|
||||||
<string name="main_activity_prompt_to_stop">Tap power off button to stop the server</string>
|
<string name="main_activity_prompt_to_stop">Tap power off button to stop the server</string>
|
||||||
|
|
||||||
<string name="service_notification_category_name">HTTP Server</string>
|
<string name="service_notification_category_name">HTTP Server</string>
|
||||||
<string name="service_notification_category_description">The fixed notification keeping the HTTP server alive</string>
|
<string name="service_notification_category_description">The fixed notification keeping the HTTP server alive</string>
|
||||||
<string name="service_notification_title">Server is running</string>
|
<string name="service_notification_title">Server is running</string>
|
||||||
<string name="service_notification_text">The HTTP server is listening on port %1$d</string>
|
<string name="service_notification_text">The HTTP server is listening on address %1$s</string>
|
||||||
|
|
||||||
<string name="title_activity_preferences">Settings</string>
|
<string name="title_activity_preferences">Settings</string>
|
||||||
<string name="preference_port_summary">The desired port on which HTTP server is intended to listening</string>
|
<string name="preference_port_summary">The desired port on which HTTP server is intended to listening</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user