Skip to content
This repository has been archived by the owner on Jun 28, 2024. It is now read-only.

Commit

Permalink
Add foreground service in android example
Browse files Browse the repository at this point in the history
  • Loading branch information
graszka22 committed Jun 14, 2024
1 parent 811262e commit d1a968c
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 7 deletions.
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ plugins {

android {
namespace 'com.example.fishjamandroidexample'
compileSdk 33
compileSdk 34

defaultConfig {
applicationId "com.example.fishjamandroidexample"
minSdk 24
targetSdk 33
targetSdk 34
versionCode 1
versionName "1.0"

Expand Down Expand Up @@ -57,7 +57,7 @@ android {

dependencies {

implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.core:core-ktx:1.13.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
implementation 'androidx.activity:activity-compose:1.7.1'
implementation platform('androidx.compose:compose-bom:2022.10.00')
Expand Down
24 changes: 21 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools" >

<uses-feature
android:name="android.hardware.camera"
android:required="true" />

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

<application
android:allowBackup="true"
Expand All @@ -12,7 +23,14 @@
android:supportsRtl="true"
android:theme="@style/Theme.FishjamAndroidExample"
android:usesCleartextTraffic="true"
tools:targetApi="31">
tools:targetApi="31" >
<service
android:name=".CameraService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="camera|microphone|mediaProjection">
</service>

<activity
android:name=".RoomActivity"
android:exported="false"
Expand All @@ -22,7 +40,7 @@
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.FishjamAndroidExample">
android:theme="@style/Theme.FishjamAndroidExample" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.example.fishjamandroidexample

import android.app.ForegroundServiceStartNotAllowedException
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ServiceInfo
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.core.app.ServiceCompat
import androidx.core.content.ContextCompat

class CameraService : Service() {
private fun startForeground() {
// Before starting the service as foreground check that the app has the
// appropriate runtime permissions. In this case, verify that the user has
// granted the CAMERA permission.
val cameraPermission =
ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)
if (cameraPermission == PackageManager.PERMISSION_DENIED) {
// Without camera permissions the service cannot run in the foreground
// Consider informing user or updating your app UI if visible.
stopSelf()
return
}

try {
val channelID = "FISHJAM_NOTIFICATION_CHANNEL"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create the NotificationChannel.
val name = "Fishjam notification channel"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val mChannel = NotificationChannel(channelID, name, importance)
// Register the channel with the system. You can't change the importance
// or other notification behaviors after this.
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(mChannel)
}
val notification = NotificationCompat.Builder(this, channelID)
// Create the notification to display while the service is running
.setContentTitle("Fishjam is running")
.build()
ServiceCompat.startForeground(
/* service = */ this,
/* id = */ 100, // Cannot be 0
/* notification = */ notification,
/* foregroundServiceType = */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
} else {
0
},
)
} catch (e: Exception) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
&& e is ForegroundServiceStartNotAllowedException
) {
// App not in a valid state to start foreground service
// (e.g. started from bg)
}
// ...
}
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
startForeground()
return START_STICKY
}
override fun onBind(intent: Intent): IBinder? {
return null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class MainActivity : ComponentActivity() {
rememberMultiplePermissionsState(
listOf(
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA
Manifest.permission.CAMERA,
Manifest.permission.POST_NOTIFICATIONS
)
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.example.fishjamandroidexample

import android.app.Application
import android.content.Intent
import android.os.Build
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.fishjamdev.client.Config
Expand Down Expand Up @@ -40,6 +42,15 @@ class RoomViewModel(application: Application) :
setupTracks()
}

override fun onCleared() {
super.onCleared()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val intent =
Intent(getApplication<Application>().applicationContext, CameraService::class.java)
getApplication<Application>().applicationContext.stopService(intent)
}
}

fun disconnect() {
localVideoTrack?.stop()
localVideoTrack = null
Expand Down Expand Up @@ -75,6 +86,10 @@ class RoomViewModel(application: Application) :
)
}
emitParticipants()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val intent = Intent(getApplication<Application>().applicationContext, CameraService::class.java)
getApplication<Application>().applicationContext.startForegroundService(intent)
}
}

override fun onJoinError(metadata: Any) {
Expand Down

0 comments on commit d1a968c

Please sign in to comment.