Android Kotlin Programmierung.
Radioplayer
Livestream mit Metadaten.
Native App.
- MainActivity.kt (online)
- MediaPlayerService.kt (demnächst online)
- MyAnalyticsListener.kt (demnächst online)
- NotificationHelper.kt (demnächst online)
- Interface.kt (demnächst online)
- HeadsetConnectionReceiver.kt (demnächst online)
- BluetoothReceiver.kt (demnächst online)
- AndroidManifest.xml (demnächst online)
- activity_main.xml (demnächst online)
- build.gradle.kts (demnächst online)
package com.example.sesin24_v3
// Sebastiano Sindona * SESIN24 * 01.2020 *
// MainActivity.kt
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.ServiceConnection
import android.content.pm.ActivityInfo
import android.graphics.Bitmap
import android.media.AudioManager
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.util.DisplayMetrics
import android.util.Log
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.ImageButton
import android.widget.ProgressBar
import android.widget.SeekBar
import android.widget.TextView
import android.widget.Toast
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.traceEventEnd
import androidx.lifecycle.ViewModel
class MainActivity : AppCompatActivity(), OnPlayStatusChangedListener {
private lateinit var webView: WebView
private lateinit var metadataReceiver: BroadcastReceiver
private lateinit var titelTextView: TextView
private lateinit var volumeSlider: SeekBar
private lateinit var volumeLevel: ProgressBar
private lateinit var audioManager: AudioManager
// -------------------------------------------------------------------
// ViewModel-Instanz erstellen.
private val webViewModel: WebViewModel by viewModels()
class WebViewModel : ViewModel() {
var currentUrl: String? = null
}
// -------------------------------------------------------------------
// Status "player" MediaPlayerService ****************
private var isPlaying = false
private var mediaPlayerService: MediaPlayerService? = null
private var serviceBound = false
private val serviceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val binder = service as MediaPlayerService.LocalBinder
mediaPlayerService = binder.getService()
serviceBound = true
// Registriere Listener
mediaPlayerService?.setOnPlayStatusChangedListener(this@MainActivity)
}
override fun onServiceDisconnected(name: ComponentName?) {
serviceBound = false
}
}
// -------------------------------------------------------------------
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ActionBar
supportActionBar?.hide() // Entferne Titelleiste (ActionBar)
// Gerätetyp
requestedOrientation = if (isPhone()) {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
} else {
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
}
// -------------------------------------------------------------------
// Status "player" MediaPlayerService *
val intent = Intent(this, MediaPlayerService::class.java)
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
// -------------------------------------------------------------------
// VOL. Initialisiere SeekBar und ProgressBar > Layout ******
volumeSlider = findViewById(R.id.volumeSlider)
volumeLevel = findViewById(R.id.volumeLevel)
// Initialisiere AudioManager, um die Lautstärke des Geräts zu steuern
audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
// Hole die maximale und aktuelle Lautstärke
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
// Setze die maximale Lautstärke für den Lautstärkeregler und die ProgressBar
volumeSlider.max = maxVolume
volumeLevel.max = maxVolume
// Setze den aktuellen Lautstärkewert in der SeekBar und ProgressBar
volumeSlider.progress = currentVolume
volumeLevel.progress = currentVolume
// Listener für den Lautstärkeregler (SeekBar)
volumeSlider.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
// Aktualisiere die Systemlautstärke
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0)
// Aktualisiere den ProgressBar-Pegel
volumeLevel.progress = progress
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
// Nichts zu tun, wenn der Benutzer beginnt zu ziehen
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
// Nichts zu tun, wenn der Benutzer aufhört zu ziehen
}
})
// -------------------------------------------------------------------
// METADATEN - initialisieren BroadcastReceiver ********************
metadataReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// metadaten von MediaPlayerService
val titel = intent?.getStringExtra("titel")
val artist = intent?.getStringExtra("artist")
val sendername = intent?.getStringExtra("sendername")
// METADATEN View
titelTextView.text = titel ?: "Unknown Titel" // Einzel nur Titel
var artistvar = artist ?: "Unknown Artist" // Einzel nur Artist
val titelartsong = "$artistvar, $titel" // Artist und Titel
titelTextView.text = titelartsong
}
}
// -------------------------------------------------------------------
titelTextView = findViewById(R.id.textViewTitel)
titelTextView.isSelected = true
// -------------------------------------------------------------------
// Player Button ****************************************************
val playButton: ImageButton = findViewById(R.id.buttonPlayStop)
playButton.setOnClickListener {
isPlaying = !isPlaying // Toggle Play/Stop
if (isPlaying) {
val intent = Intent(this, MediaPlayerService::class.java)
intent.action = "ACTION_PLAY"
startService(intent)
} else {
val intent = Intent(this, MediaPlayerService::class.java)
intent.action = "ACTION_STOP"
startService(intent)
}
}
// -------------------------------------------------------------------
// Metadaten - Registriere BroadcastReceiver ****************
val intentFilter = IntentFilter("com.example.ACTION_METADATA_UPDATED")
registerReceiver(metadataReceiver, intentFilter, RECEIVER_EXPORTED)
// -------------------------------------------------------------------
// URL Mobilseite
webView = findViewById(R.id.webView)
if (webViewModel.currentUrl == null) {
// Lade Startseite
webView.loadUrl("file:///android_asset/deine_startseite")
} else {
// Code hinzufügen oder leer lassen
}
} //
// -----------------------------------------------------------------
// Bildschirm
private fun isPhone(): Boolean {
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
val screenWidthDp = metrics.widthPixels / metrics.density
val screenHeightDp = metrics.heightPixels / metrics.density
return screenWidthDp < 600 || screenHeightDp < 600
}
// -------------------------------------------------------------------
// Beenden ***********************************************************
override fun onDestroy() {
super.onDestroy()
try {
unregisterReceiver(metadataReceiver)
} catch (e: IllegalArgumentException) {
Log.e("MainActivity", "Receiver not registered: ${e.message}")
}
}
// -------------------------------------------------------------------
// Button-Status "player" MediaPlayerService
override fun onIsPlayingChanged(isPlaying: Boolean) {
// Button
val playButton: ImageButton = findViewById(R.id.buttonPlayStop)
this.isPlaying = isPlaying
if (isPlaying) {
// Stop-Icon.
playButton.setImageResource(R.drawable.ic_pause)
} else {
// Play-Icon.
titelTextView.text = "SESIN24" // Dein Radioname
playButton.setImageResource(R.drawable.ic_play)
}
}
}