diff --git a/.idea/misc.xml b/.idea/misc.xml
index 85fda62..5197594 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -42,6 +42,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
index 72cbc1f..ce3ae8a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,6 +4,8 @@ plugins {
}
android {
+
+
compileSdk 31
defaultConfig {
@@ -56,6 +58,10 @@ android {
kotlinCompilerVersion '1.5.21'
}
packagingOptions {
+ exclude 'META-INF/*'
+ // Due to https://github.com/Kotlin/kotlinx.coroutines/issues/2023
+ exclude 'META-INF/licenses/*'
+ exclude '**/attach_hotspot_windows.dll'
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
@@ -82,6 +88,10 @@ dependencies {
implementation 'com.github.yausername.youtubedl-android:library:0.13.+'
implementation 'com.github.yausername.youtubedl-android:ffmpeg:0.13.+'
implementation "androidx.media:media:1.4.3"
+
+ implementation 'io.ktor:ktor-server-core:1.6.2'
+ implementation 'io.ktor:ktor-server-jetty:1.6.2'
+ implementation 'io.ktor:ktor-websockets:1.6.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7b87462..95a1393 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -27,6 +27,16 @@
+
+
+
+
+
+
+
+
+
+
+ interf.inetAddresses.toList().forEach { inetAddress ->
+ if (!inetAddress.isLoopbackAddress && inetAddress.hostAddress.indexOf(':') < 0) {
+ return inetAddress
+ }
+ }
+ }
+ return null
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/eu/toldi/balazs/caster/ChromecastManagerActivity.kt b/app/src/main/java/eu/toldi/balazs/caster/ChromecastManagerActivity.kt
index 03fe86b..2299682 100644
--- a/app/src/main/java/eu/toldi/balazs/caster/ChromecastManagerActivity.kt
+++ b/app/src/main/java/eu/toldi/balazs/caster/ChromecastManagerActivity.kt
@@ -1,12 +1,19 @@
package eu.toldi.balazs.caster
+import android.annotation.SuppressLint
import android.content.Intent
+import android.database.Cursor
+import android.net.Uri
import android.os.Build
import android.os.Bundle
+import android.provider.OpenableColumns
import android.util.Log
import android.view.KeyEvent
+import android.webkit.MimeTypeMap
import androidx.activity.ComponentActivity
+import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
@@ -25,12 +32,16 @@ import coil.compose.rememberImagePainter
import com.yausername.ffmpeg.FFmpeg
import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLException
+import eu.toldi.balazs.caster.helpers.FileCacheHelper
import eu.toldi.balazs.caster.model.ChromecastManageViewmodel
import eu.toldi.balazs.caster.services.ChromecastManagerService
import eu.toldi.balazs.caster.ui.theme.CasterTheme
import su.litvak.chromecast.api.v2.ChromeCast
import su.litvak.chromecast.api.v2.Media
import su.litvak.chromecast.api.v2.MediaStatus
+import java.io.BufferedInputStream
+import java.io.BufferedOutputStream
+import java.io.FileOutputStream
class ChromecastManagerActivity : ComponentActivity() {
@@ -152,37 +163,50 @@ class ChromecastManagerActivity : ComponentActivity() {
modifier = Modifier.fillMaxWidth()
)
}
- Row(
- Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween
- ) {
- Text(
- text = String.format(
- "%02d:%02d",
- ((mediaStatus.currentTime % 3600) / 60).toInt(),
- (mediaStatus.currentTime % 60).toInt()
+ if(mediaStatus.media.contentType.startsWith("video/")) {
+ Row(
+ Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
+ Text(
+ text = String.format(
+ "%02d:%02d",
+ ((mediaStatus.currentTime % 3600) / 60).toInt(),
+ (mediaStatus.currentTime % 60).toInt()
+ )
)
- )
- Text(
- text = String.format(
- "%02d:%02d",
- ((mediaStatus.media.duration % 3600) / 60).toInt(),
- (mediaStatus.media.duration % 60).toInt()
+ Text(
+ text = String.format(
+ "%02d:%02d",
+ ((mediaStatus.media.duration % 3600) / 60).toInt(),
+ (mediaStatus.media.duration % 60).toInt()
+ )
)
- )
+ }
+ Slider(value = sliderPosition, onValueChange = {
+ sliderPosition = it
+ sliderMoving = true
+ }, onValueChangeFinished = {
+ viewModel.seek(sliderPosition.toDouble())
+ sliderMoving = false
+ })
}
- Slider(value = sliderPosition, onValueChange = {
- sliderPosition = it
- sliderMoving = true
- }, onValueChangeFinished = {
- viewModel.seek(sliderPosition.toDouble())
- sliderMoving = false
- })
}
}
+
@Composable
fun MenuBar() {
+ val pickPictureLauncher = rememberLauncherForActivityResult(
+ ActivityResultContracts.OpenDocument()
+ ) { fileUri ->
+ if (fileUri != null) {
+ val cacheHelper = FileCacheHelper(applicationContext)
+ cacheHelper.cacheThis(listOf(fileUri))
+ viewModel.castFromCache(cacheHelper.tryFileName(fileUri))
+
+ }
+ }
TopAppBar(
title = {
Text("Caster")
@@ -197,7 +221,14 @@ class ChromecastManagerActivity : ComponentActivity() {
},
actions = {
Row {
-
+ IconButton(onClick = {
+ pickPictureLauncher.launch(arrayOf("image/*", "video/*"))
+ }) {
+ Icon(
+ Icons.Filled.Folder,
+ contentDescription = stringResource(id = R.string.back)
+ )
+ }
}
}
)
diff --git a/app/src/main/java/eu/toldi/balazs/caster/MainActivity.kt b/app/src/main/java/eu/toldi/balazs/caster/MainActivity.kt
index 812cdc4..0f072f8 100644
--- a/app/src/main/java/eu/toldi/balazs/caster/MainActivity.kt
+++ b/app/src/main/java/eu/toldi/balazs/caster/MainActivity.kt
@@ -32,11 +32,13 @@ import eu.toldi.balazs.caster.ui.theme.CasterTheme
import su.litvak.chromecast.api.v2.ChromeCast
-class MainActivity : ComponentActivity() {
+open class MainActivity : ComponentActivity() {
- lateinit var viewModel: ChromeCastViewModel
- private var multicastLock: MulticastLock? = null
+ protected lateinit var viewModel: ChromeCastViewModel
+ protected var multicastLock: MulticastLock? = null
+
+ protected fun isViewModelInitialised() = ::viewModel.isInitialized
override fun onStart() {
super.onStart()
val wifi = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
@@ -184,7 +186,11 @@ class MainActivity : ComponentActivity() {
@Composable
- fun showChromeCastButton(chromeCast: ChromeCast) {
+ fun showChromeCastButton(chromeCast: ChromeCast,buttonCallBack: () -> Unit = {
+ ChromecastManagerActivity.chromeCast_ = chromeCast
+ val intent = Intent(applicationContext, ChromecastManagerActivity::class.java)
+ startActivity(intent)
+ }) {
Column(
Modifier
.fillMaxWidth()
@@ -193,11 +199,9 @@ class MainActivity : ComponentActivity() {
Card(modifier = Modifier
.fillMaxWidth()
.clickable {
- ChromecastManagerActivity.chromeCast_ = chromeCast
- val intent = Intent(applicationContext, ChromecastManagerActivity::class.java)
- startActivity(intent)
+ buttonCallBack()
}) {
- Row() {
+ Row {
val image_id = when (chromeCast.model) {
"Chromecast Ultra" -> R.drawable.chromecastultra
else -> R.drawable.chromecastv1
@@ -217,7 +221,8 @@ class MainActivity : ComponentActivity() {
)
}
- Column() {
+ Column(modifier = Modifier.fillMaxWidth().height(80.dp),
+ verticalArrangement = Arrangement.Center) {
Text(
text = "Name: " + when {
chromeCast.title != null -> chromeCast.title
@@ -267,7 +272,7 @@ class MainActivity : ComponentActivity() {
@Preview(showBackground = true)
@Composable
- fun DefaultPreview() {
+ open fun DefaultPreview() {
CasterTheme {
Column {
MenuBar({}, {})
diff --git a/app/src/main/java/eu/toldi/balazs/caster/ShareRecieverActivity.kt b/app/src/main/java/eu/toldi/balazs/caster/ShareRecieverActivity.kt
index b12a767..dcac3d6 100644
--- a/app/src/main/java/eu/toldi/balazs/caster/ShareRecieverActivity.kt
+++ b/app/src/main/java/eu/toldi/balazs/caster/ShareRecieverActivity.kt
@@ -2,8 +2,10 @@ package eu.toldi.balazs.caster
import android.annotation.SuppressLint
import android.content.Intent
+import android.net.Uri
import android.net.wifi.WifiManager
import android.os.Bundle
+import android.os.Parcelable
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@@ -19,49 +21,47 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLException
+import eu.toldi.balazs.caster.helpers.FileCacheHelper
import eu.toldi.balazs.caster.model.ChromeCastViewModel
+import eu.toldi.balazs.caster.services.ChromecastManagerService
import eu.toldi.balazs.caster.ui.theme.CasterTheme
import kotlinx.coroutines.launch
import su.litvak.chromecast.api.v2.ChromeCast
-class ShareRecieverActivity : ComponentActivity() {
-
- lateinit var viewModel: ChromeCastViewModel
- private var multicastLock: WifiManager.MulticastLock? = null
-
- override fun onStart() {
- super.onStart()
- val wifi = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
- // get the device ip address
- multicastLock = wifi.createMulticastLock(javaClass.name)
- multicastLock!!.setReferenceCounted(true)
- multicastLock!!.acquire()
- if (!this::viewModel.isInitialized)
- viewModel = ViewModelProvider(this).get(ChromeCastViewModel::class.java)
- viewModel.startScanning()
- }
-
- override fun onStop() {
- super.onStop()
- if (multicastLock != null) {
- Log.i("Caster", "Releasing Mutlicast Lock...")
- multicastLock!!.release()
- multicastLock = null
- }
- viewModel.startScanning()
- }
+class ShareRecieverActivity : MainActivity() {
@SuppressLint("CoroutineCreationDuringComposition")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- if (intent?.action != Intent.ACTION_SEND || intent.type != "text/plain") {
+ if (intent?.action != Intent.ACTION_SEND ) {
finish()
}
- val link = intent.getStringExtra(Intent.EXTRA_TEXT) as String
+ Log.d(null, intent.type.toString())
+ val link = when {
+ intent.type == "text/plain" -> intent.getStringExtra(Intent.EXTRA_TEXT) as String
+ intent.type?.startsWith("video/") == true ||
+ intent.type?.startsWith("image/") == true -> {
+ val uri = (intent.getParcelableExtra(Intent.EXTRA_STREAM) as? Uri)
+ if(uri is Uri) {
+ val fileCache = FileCacheHelper(applicationContext)
+ fileCache.cacheThis(listOf(uri))
+ "http://" + ChromeCastHelper.getIPv4Address()?.hostAddress + ":" + ChromecastManagerService.PORT + "/assets/" + fileCache.tryFileName(
+ uri
+ )
+ }else ""
+
+
+ }
+ else -> {
+ ""
+ }
+ }
+ if (link == "") finish()
try {
YoutubeDL.getInstance().init(application)
} catch (e: YoutubeDLException) {
@@ -69,7 +69,7 @@ class ShareRecieverActivity : ComponentActivity() {
}
setContent {
CasterTheme {
- if (!this::viewModel.isInitialized)
+ if (!isViewModelInitialised())
viewModel = ViewModelProvider(this).get(ChromeCastViewModel::class.java)
viewModel.startScanning()
val chromeCastState = viewModel.chromeCasts.observeAsState(emptyList())
@@ -110,8 +110,8 @@ class ShareRecieverActivity : ComponentActivity() {
link = link
)
}
- item{
- if(enabled.not()){
+ item {
+ if (enabled.not()) {
CircularProgressIndicator()
}
}
@@ -130,25 +130,23 @@ class ShareRecieverActivity : ComponentActivity() {
chromeCast: ChromeCast,
link: String
) {
- Button(
- onClick = {
+ showChromeCastButton(chromeCast = chromeCast, buttonCallBack = {
+ if (enabled) {
onEnableChanged(false)
+ Intent(this, ChromecastManagerService::class.java).also {
+ it.action = ChromecastManagerService.ACTION_INIT
+ it.putExtra("CHROMECAST_ADDRESS", chromeCast.address)
+ it.putExtra("CHROMECAST_NAME", chromeCast.title)
+ ContextCompat.startForegroundService(this, it)
+ }
lifecycleScope.launch {
ChromeCastHelper.chromeCast = chromeCast
ChromeCastHelper.castLink(link) {
- finish()
+ //finish()
}
}
- },
- modifier = Modifier.padding(5.dp),
- enabled = enabled
- ) {
- when {
- chromeCast.title != null -> Text(text = chromeCast.title)
- chromeCast.name != null -> Text(text = chromeCast.name)
- else -> Text(text = chromeCast.address)
}
- }
+ })
}
@Composable
@@ -173,7 +171,7 @@ class ShareRecieverActivity : ComponentActivity() {
@Preview(showBackground = true)
@Composable
- fun DefaultPreview() {
+ override fun DefaultPreview() {
CasterTheme {
MenuBar {}
}
diff --git a/app/src/main/java/eu/toldi/balazs/caster/helpers/FileCacheHelper.kt b/app/src/main/java/eu/toldi/balazs/caster/helpers/FileCacheHelper.kt
new file mode 100644
index 0000000..ebacf70
--- /dev/null
+++ b/app/src/main/java/eu/toldi/balazs/caster/helpers/FileCacheHelper.kt
@@ -0,0 +1,129 @@
+package eu.toldi.balazs.caster.helpers
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.database.Cursor
+import android.net.Uri
+import android.provider.OpenableColumns
+import android.util.Log
+import android.webkit.MimeTypeMap
+import java.io.BufferedInputStream
+import java.io.BufferedOutputStream
+import java.io.File
+import java.io.FileOutputStream
+import java.util.concurrent.Executors
+
+class FileCacheHelper(
+private val mContext: Context
+) {
+
+ // content resolver
+ private val contentResolver = mContext.contentResolver
+
+ // to get the type of file
+ private val mimeTypeMap = MimeTypeMap.getSingleton()
+
+ private val mCacheLocation = mContext.cacheDir
+
+ fun cacheThis(uris: List) {
+ executor.submit {
+ uris.forEach { uri -> copyFromSource(uri) }
+ }
+ }
+
+ fun tryFileName(uri: Uri): String{
+ val fileExtension: String = getFileExtension(uri) ?: kotlin.run {
+ throw RuntimeException("Extension is null for $uri")
+ }
+ return queryName(uri) ?: getFileName(fileExtension)
+ }
+
+ /**
+ * Copies the actual data from provided content provider.
+ */
+ private fun copyFromSource(uri: Uri) {
+
+ val fileExtension: String = getFileExtension(uri) ?: kotlin.run {
+ throw RuntimeException("Extension is null for $uri")
+ }
+ val fileName = queryName(uri) ?: getFileName(fileExtension)
+
+ val inputStream = contentResolver.openInputStream(uri) ?: kotlin.run {
+ throw RuntimeException("Cannot open for reading $uri")
+ }
+ val bufferedInputStream = BufferedInputStream(inputStream)
+
+ // the file which will be the new cached file
+ val outputFile = File(mCacheLocation, fileName)
+ val bufferedOutputStream = BufferedOutputStream(FileOutputStream(outputFile))
+
+ // this will hold the content for each iteration
+ val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
+
+ var readBytes = 0 // will be -1 if reached the end of file
+
+ while (true) {
+ readBytes = bufferedInputStream.read(buffer)
+
+ // check if the read was failure
+ if (readBytes == -1) {
+ bufferedOutputStream.flush()
+ break
+ }
+
+ bufferedOutputStream.write(buffer)
+ bufferedOutputStream.flush()
+ }
+ Log.i("FileCache",outputFile.absoluteFile.toString())
+ // close everything
+ inputStream.close()
+ bufferedInputStream.close()
+ bufferedOutputStream.close()
+
+ }
+
+ private fun getFileExtension(uri: Uri): String? {
+ return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(uri))
+ }
+
+ /**
+ * Tries to get actual name of the file being copied.
+ * This might be required in some of the cases where you might want to know the file name too.
+ *
+ * @param uri
+ *
+ */
+ @SuppressLint("Recycle")
+ private fun queryName(uri: Uri): String? {
+ val returnCursor: Cursor = contentResolver.query(uri, null, null, null, null) ?: return null
+ val nameIndex: Int = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
+ returnCursor.moveToFirst()
+ val name: String = returnCursor.getString(nameIndex)
+ returnCursor.close()
+ return name
+ }
+
+ private fun getFileName(fileExtension: String): String {
+ return "${System.currentTimeMillis().toString()}.$fileExtension"
+ }
+
+ /**
+ * Remove everything that we have cached.
+ * You might want to invoke this method before quiting the application.
+ */
+ fun removeAll() {
+ mContext.cacheDir.deleteRecursively()
+ }
+
+ companion object {
+
+ // base buffer size
+ private const val BASE_BUFFER_SIZE = 1024
+
+ // if you want to modify size use binary multiplier 2, 4, 6, 8
+ private const val DEFAULT_BUFFER_SIZE = BASE_BUFFER_SIZE * 4
+
+ private val executor = Executors.newSingleThreadExecutor()
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/eu/toldi/balazs/caster/model/ChromecastManageViewmodel.kt b/app/src/main/java/eu/toldi/balazs/caster/model/ChromecastManageViewmodel.kt
index 469ad9a..2850bb1 100644
--- a/app/src/main/java/eu/toldi/balazs/caster/model/ChromecastManageViewmodel.kt
+++ b/app/src/main/java/eu/toldi/balazs/caster/model/ChromecastManageViewmodel.kt
@@ -1,15 +1,19 @@
package eu.toldi.balazs.caster.model
+import android.net.Uri
import android.util.Log
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import eu.toldi.balazs.caster.ChromeCastHelper
+import eu.toldi.balazs.caster.services.ChromecastManagerService
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import su.litvak.chromecast.api.v2.ChromeCast
import su.litvak.chromecast.api.v2.MediaStatus
+import java.net.InetAddress
+import java.net.NetworkInterface
class ChromecastManageViewmodel : ViewModel() {
@@ -60,6 +64,13 @@ class ChromecastManageViewmodel : ViewModel() {
}
}
+ fun castFromCache(fileName: String,callBack: () -> Unit = {}){
+ //Log.i("Caster","http://"+getIPv4Address()?.hostAddress+":"+ChromecastManagerService.PORT+"/assets/"+fileName)
+ viewModelScope.launch(IO) {
+ ChromeCastHelper.castLink("http://"+getIPv4Address()?.hostAddress+":"+ChromecastManagerService.PORT+"/assets/"+fileName,callBack)
+ }
+ }
+
fun stopApp() {
viewModelScope.launch(IO) {
ChromeCastHelper.stopApp()
@@ -95,4 +106,15 @@ class ChromecastManageViewmodel : ViewModel() {
setVolume(chromeCast.status.volume.level - 0.05f)
}
}
+
+ fun getIPv4Address(): InetAddress? {
+ NetworkInterface.getNetworkInterfaces().toList().forEach { interf ->
+ interf.inetAddresses.toList().forEach { inetAddress ->
+ if (!inetAddress.isLoopbackAddress && inetAddress.hostAddress.indexOf(':') < 0) {
+ return inetAddress
+ }
+ }
+ }
+ return null
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/eu/toldi/balazs/caster/services/ChromecastManagerService.kt b/app/src/main/java/eu/toldi/balazs/caster/services/ChromecastManagerService.kt
index ba69fcf..90db981 100644
--- a/app/src/main/java/eu/toldi/balazs/caster/services/ChromecastManagerService.kt
+++ b/app/src/main/java/eu/toldi/balazs/caster/services/ChromecastManagerService.kt
@@ -16,14 +16,21 @@ import androidx.core.app.NotificationCompat
import eu.toldi.balazs.caster.App.Companion.CHANNEL_ID
import eu.toldi.balazs.caster.ChromeCastHelper
import eu.toldi.balazs.caster.R
-import kotlinx.coroutines.Dispatchers
+import io.ktor.application.*
+import io.ktor.features.*
+import io.ktor.http.*
+import io.ktor.http.content.*
+import io.ktor.response.*
+import io.ktor.routing.*
+import io.ktor.server.engine.*
+import io.ktor.server.jetty.*
+import io.ktor.websocket.*
+import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
import su.litvak.chromecast.api.v2.ChromeCast
import su.litvak.chromecast.api.v2.Media
import su.litvak.chromecast.api.v2.MediaStatus
+import java.io.File
class ChromecastManagerService : Service() {
@@ -36,6 +43,9 @@ class ChromecastManagerService : Service() {
const val ACTION_NEXT = "action_next"
const val ACTION_PREVIOUS = "action_previous"
const val ACTION_STOP = "action_stop"
+ const val ACTION_SETFILE = "action_file"
+
+ const val PORT = 3080
}
private val mMediaPlayer = MediaPlayer()
@@ -43,10 +53,33 @@ class ChromecastManagerService : Service() {
private lateinit var mController: MediaControllerCompat
private lateinit var pendingIntent : PendingIntent
private var mediaStatus: MediaStatus? = null
-
+ private var file : File? = null
override fun onBind(p0: Intent?): IBinder? = null
private lateinit var chromeCast: ChromeCast
+ private val server by lazy {
+ embeddedServer(Jetty, PORT, watchPaths = emptyList()) {
+ install(WebSockets)
+ install(CallLogging)
+ routing {
+ get("/") {
+ if(file == null) {
+ call.respondText(
+ text = "Hello!! You are here in ${Build.MODEL}",
+ contentType = ContentType.Text.Plain
+ )
+ }else{
+
+ call.respondFile(file!!)
+ }
+ }
+ static("assets") {
+ staticRootFolder = applicationContext.cacheDir
+ files(".")
+ }
+ }
+ }
+ }
@RequiresApi(Build.VERSION_CODES.M)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@@ -81,8 +114,11 @@ class ChromecastManagerService : Service() {
.setContentIntent(pendingIntent).build()
startForeground(1, notification)
+ CoroutineScope(IO).launch {
+ server.start(wait = true)
+ }
+ CoroutineScope(IO).launch {
- GlobalScope.launch(IO) {
while (true) {
try {
ChromeCastHelper.chromeCast = chromeCast
@@ -116,6 +152,11 @@ class ChromecastManagerService : Service() {
}
+ override fun onDestroy() {
+ server.stop(1_000, 2_000)
+ super.onDestroy()
+ }
+
private suspend fun buildNotification() {
var status = chromeCast.status
Log.d(null, status.applications.toString())