mirror of
https://github.com/screentinker/screentinker.git
synced 2026-06-14 18:22:46 -06:00
ScreenTinker - open source digital signage management software. MIT License, all features included, no license gates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
165 lines
5.8 KiB
Kotlin
165 lines
5.8 KiB
Kotlin
package com.remotedisplay.player
|
|
|
|
import android.Manifest
|
|
import android.content.ComponentName
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.content.ServiceConnection
|
|
import android.content.pm.PackageManager
|
|
import android.os.Build
|
|
import android.os.Bundle
|
|
import android.os.IBinder
|
|
import android.util.Log
|
|
import android.view.View
|
|
import android.view.WindowManager
|
|
import android.widget.Button
|
|
import android.widget.EditText
|
|
import android.widget.ProgressBar
|
|
import android.widget.TextView
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import androidx.core.app.ActivityCompat
|
|
import androidx.core.content.ContextCompat
|
|
import com.remotedisplay.player.data.ServerConfig
|
|
import com.remotedisplay.player.service.WebSocketService
|
|
|
|
class ProvisioningActivity : AppCompatActivity() {
|
|
|
|
private lateinit var config: ServerConfig
|
|
private var wsService: WebSocketService? = null
|
|
private var bound = false
|
|
|
|
private lateinit var serverUrlInput: EditText
|
|
private lateinit var connectBtn: Button
|
|
private lateinit var pairingCodeText: TextView
|
|
private lateinit var statusText: TextView
|
|
private lateinit var progressBar: ProgressBar
|
|
private lateinit var pairingSection: View
|
|
|
|
private val connection = object : ServiceConnection {
|
|
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
|
val binder = service as WebSocketService.LocalBinder
|
|
wsService = binder.getService()
|
|
bound = true
|
|
setupServiceCallbacks()
|
|
}
|
|
|
|
override fun onServiceDisconnected(name: ComponentName?) {
|
|
wsService = null
|
|
bound = false
|
|
}
|
|
}
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
setContentView(R.layout.activity_provisioning)
|
|
|
|
// Fullscreen immersive
|
|
@Suppress("DEPRECATION")
|
|
window.decorView.systemUiVisibility = (
|
|
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
|
|
View.SYSTEM_UI_FLAG_FULLSCREEN or
|
|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
|
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
|
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
|
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
|
)
|
|
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
|
|
|
config = ServerConfig(this)
|
|
|
|
serverUrlInput = findViewById(R.id.serverUrlInput)
|
|
connectBtn = findViewById(R.id.connectBtn)
|
|
pairingCodeText = findViewById(R.id.pairingCodeText)
|
|
statusText = findViewById(R.id.statusText)
|
|
progressBar = findViewById(R.id.progressBar)
|
|
pairingSection = findViewById(R.id.pairingSection)
|
|
|
|
// Pre-fill if previously entered
|
|
if (config.serverUrl.isNotEmpty()) {
|
|
serverUrlInput.setText(config.serverUrl)
|
|
}
|
|
|
|
connectBtn.setOnClickListener {
|
|
val url = serverUrlInput.text.toString().trim().trimEnd('/')
|
|
if (url.isEmpty()) {
|
|
statusText.text = "Please enter the server URL"
|
|
return@setOnClickListener
|
|
}
|
|
config.serverUrl = url
|
|
connectToServer(url)
|
|
}
|
|
|
|
// Request notification permission on Android 13+
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
|
|
!= PackageManager.PERMISSION_GRANTED) {
|
|
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 100)
|
|
} else {
|
|
startWebSocketService()
|
|
}
|
|
} else {
|
|
startWebSocketService()
|
|
}
|
|
}
|
|
|
|
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
|
// Start service regardless of permission result - it just won't show notification on 13+
|
|
startWebSocketService()
|
|
}
|
|
|
|
private fun startWebSocketService() {
|
|
try {
|
|
val serviceIntent = Intent(this, WebSocketService::class.java)
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
startForegroundService(serviceIntent)
|
|
} else {
|
|
startService(serviceIntent)
|
|
}
|
|
bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)
|
|
} catch (e: Exception) {
|
|
Log.e("ProvisioningActivity", "Failed to start service: ${e.message}")
|
|
statusText.text = "Service error: ${e.message}"
|
|
}
|
|
}
|
|
|
|
private fun connectToServer(url: String) {
|
|
connectBtn.isEnabled = false
|
|
progressBar.visibility = View.VISIBLE
|
|
statusText.text = "Connecting to server..."
|
|
|
|
wsService?.connect(url)
|
|
}
|
|
|
|
private fun setupServiceCallbacks() {
|
|
wsService?.onRegistered = { deviceId ->
|
|
runOnUiThread {
|
|
progressBar.visibility = View.GONE
|
|
pairingSection.visibility = View.VISIBLE
|
|
pairingCodeText.text = wsService?.getPairingCode() ?: "------"
|
|
statusText.text = "Enter this code in the dashboard to pair this display"
|
|
connectBtn.isEnabled = false
|
|
}
|
|
}
|
|
|
|
wsService?.onPaired = { deviceId, name ->
|
|
runOnUiThread {
|
|
statusText.text = "Paired as: $name"
|
|
// Transition to main activity
|
|
val intent = Intent(this, MainActivity::class.java)
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
startActivity(intent)
|
|
finish()
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
if (bound) {
|
|
unbindService(connection)
|
|
bound = false
|
|
}
|
|
super.onDestroy()
|
|
}
|
|
}
|