I am in the process of developping an Android app handling audio data, now seeing how to have the audio keep playing when the app is in the background using a service.
At this point I can set a service playing audio, but the problem is that once in the background, it will stop after exactly one minute. I have tried a few things I found on the net and nothing works. I put my code hereafter, that would be great if someone could let me know what I need to change.
Here is the MainActivity.kt file:
package me.soft.myapp
import android.content.Intent
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
class MainActivity : AppCompatActivity() {
private var toggleFlag = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun startHandler(view: View) {
val serviceIntent = Intent(this, TheService::class.java)
startService(serviceIntent)
}
fun stopHandler(view: View) {
val serviceIntent = Intent(this, TheService::class.java)
stopService(serviceIntent)
}
fun toggleHandler(view: View) {
toggleFlag = !toggleFlag
when(toggleFlag) {
true -> view.setBackgroundColor(Color.rgb(0xFF,0x00,0x00))
false -> view.setBackgroundColor(Color.rgb(0x00,0x00,0xFF))
}
}
}
Here is the TheService.kt file:
package me.soft.myapp
import android.R
import android.app.Notification
import android.app.Service
import android.content.Intent
import android.media.MediaPlayer
import android.os.IBinder
import android.provider.Settings
import android.widget.Toast
import androidx.core.app.NotificationCompat
class TheService: Service() {
private lateinit var audioPlayer:MediaPlayer
override fun onCreate() {
super.onCreate()
}
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val runnable = Runnable {
audioPlayer = MediaPlayer.create(this, Settings.System.DEFAULT_RINGTONE_URI)
audioPlayer?.setLooping(true)
audioPlayer.start()
}
val thread = Thread(runnable)
thread.start() // Stops after one minute when in the background.
return START_NOT_STICKY
}
override fun onDestroy() {
super.onDestroy()
audioPlayer.stop()
}
}
And just in case this is useful, here is the acticity_main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/ res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp">
<Button
android:id="@ id/strtBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start"
android:onClick="startHandler"
android:textAllCaps="false" />
<Button
android:id="@ id/stpBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop"
android:onClick="stopHandler"
android:textAllCaps="false" />
<Button
android:id="@ id/bgctgBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="BCG Toggle"
android:onClick="toggleHandler"
android:textAllCaps="false" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
And also in case this is useful, here is the AndroidManifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="me.soft.myapp">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="myapp"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ServiceTry"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".TheService" />
</application>
</manifest>
CodePudding user response:
You need to use a foreground service. Background services are killed after 2 minutes if the foreground application isn't using the service.Foreground service can last for a long time unless the phone goes very low on resources. to do that use startForegroundService to launch the service, and have the service's onStartCommand call startForeground as well.