Skip to content

Commit 0b995da

Browse files
maciejmakowski2003maciejmakowski2003
andauthored
Fix/android foreground service (#644)
* fix: part of fix for FS * fix: final fix for Android 13+ foreground service * fix: renaming * fix: applied requested changes * ci: yarn lint * fix: fixed type and updated notification icon * refactor: small improvements * fix: removed forward declaration --------- Co-authored-by: maciejmakowski2003 <[email protected]>
1 parent b880d55 commit 0b995da

File tree

14 files changed

+255
-152
lines changed

14 files changed

+255
-152
lines changed

apps/common-app/src/examples/AudioFile/AudioFile.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ const AudioFile: FC = () => {
5959
'remotePlay',
6060
() => {
6161
AudioPlayer.play();
62+
setIsPlaying(true);
6263
}
6364
);
6465

6566
const remotePauseSubscription = AudioManager.addSystemEventListener(
6667
'remotePause',
6768
() => {
6869
AudioPlayer.pause();
70+
setIsPlaying(false);
6971
}
7072
);
7173

apps/fabric-example/android/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
66
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
77
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
8-
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
98
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
109

1110
<application
@@ -16,7 +15,7 @@
1615
android:allowBackup="false"
1716
android:theme="@style/AppTheme"
1817
android:supportsRtl="true">
19-
<service android:stopWithTask="true" android:name="com.swmansion.audioapi.system.MediaNotificationManager$NotificationService" android:foregroundServiceType="mediaPlayback|dataSync" />
18+
<service android:stopWithTask="true" android:name="com.swmansion.audioapi.system.MediaNotificationManager$AudioForegroundService" android:foregroundServiceType="mediaPlayback" />
2019
<activity
2120
android:name=".MainActivity"
2221
android:label="@string/app_name"

packages/react-native-audio-api/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ AudioPlayer::AudioPlayer(
1515
sampleRate_(sampleRate),
1616
channelCount_(channelCount) {
1717
isInitialized_ = openAudioStream();
18+
19+
nativeAudioPlayer_ = jni::make_global(NativeAudioPlayer::create());
1820
}
1921

2022
bool AudioPlayer::openAudioStream() {
@@ -47,6 +49,7 @@ bool AudioPlayer::openAudioStream() {
4749

4850
bool AudioPlayer::start() {
4951
if (mStream_) {
52+
nativeAudioPlayer_->start();
5053
auto result = mStream_->requestStart();
5154
return result == oboe::Result::OK;
5255
}
@@ -56,6 +59,7 @@ bool AudioPlayer::start() {
5659

5760
void AudioPlayer::stop() {
5861
if (mStream_) {
62+
nativeAudioPlayer_->stop();
5963
mStream_->requestStop();
6064
}
6165
}

packages/react-native-audio-api/android/src/main/cpp/audioapi/android/core/AudioPlayer.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <functional>
66
#include <memory>
77

8+
#include <audioapi/android/core/NativeAudioPlayer.hpp>
9+
810
namespace audioapi {
911

1012
using namespace oboe;
@@ -19,13 +21,18 @@ class AudioPlayer : public AudioStreamDataCallback, AudioStreamErrorCallback {
1921
float sampleRate,
2022
int channelCount);
2123

24+
~AudioPlayer() override {
25+
nativeAudioPlayer_.release();
26+
cleanup();
27+
}
28+
2229
bool start();
2330
void stop();
2431
bool resume();
2532
void suspend();
2633
void cleanup();
2734

28-
bool isRunning() const;
35+
[[nodiscard]] bool isRunning() const;
2936

3037
DataCallbackResult onAudioReady(
3138
AudioStream *oboeStream,
@@ -44,6 +51,8 @@ class AudioPlayer : public AudioStreamDataCallback, AudioStreamErrorCallback {
4451
int channelCount_;
4552

4653
bool openAudioStream();
54+
55+
facebook::jni::global_ref<NativeAudioPlayer> nativeAudioPlayer_;
4756
};
4857

4958
} // namespace audioapi
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
3+
4+
#include <fbjni/fbjni.h>
5+
#include <react/jni/CxxModuleWrapper.h>
6+
#include <react/jni/JMessageQueueThread.h>
7+
#include <memory>
8+
#include <utility>
9+
#include <unordered_map>
10+
11+
namespace audioapi {
12+
13+
using namespace facebook;
14+
using namespace react;
15+
16+
class NativeAudioPlayer : public jni::JavaClass<NativeAudioPlayer> {
17+
public:
18+
static auto constexpr kJavaDescriptor =
19+
"Lcom/swmansion/audioapi/core/NativeAudioPlayer;";
20+
21+
static jni::local_ref<NativeAudioPlayer> create() {
22+
return newInstance();
23+
}
24+
25+
void start() {
26+
static const auto method = javaClassStatic()->getMethod<void()>("start");
27+
method(self());
28+
}
29+
30+
void stop() {
31+
static const auto method = javaClassStatic()->getMethod<void()>("stop");
32+
method(self());
33+
}
34+
};
35+
36+
} // namespace audioapi
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.swmansion.audioapi.core
2+
3+
import com.facebook.common.internal.DoNotStrip
4+
import com.swmansion.audioapi.system.MediaSessionManager
5+
6+
@DoNotStrip
7+
class NativeAudioPlayer {
8+
private var sourceNodeId: String? = null
9+
10+
@DoNotStrip
11+
fun start() {
12+
this.sourceNodeId = MediaSessionManager.attachAudioPlayer(this)
13+
MediaSessionManager.startForegroundServiceIfNecessary()
14+
}
15+
16+
@DoNotStrip
17+
fun stop() {
18+
this.sourceNodeId?.let {
19+
MediaSessionManager.detachAudioPlayer(it)
20+
this.sourceNodeId = null
21+
}
22+
MediaSessionManager.stopForegroundServiceIfNecessary()
23+
}
24+
}

packages/react-native-audio-api/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class LockScreenManager(
122122
)
123123

124124
nb.setLargeIcon(bitmap)
125-
mediaNotificationManager.get()?.show(nb, isPlaying)
125+
mediaNotificationManager.get()?.updateNotification(nb, isPlaying)
126126

127127
artworkThread = null
128128
} catch (ex: Exception) {
@@ -167,14 +167,14 @@ class LockScreenManager(
167167

168168
mediaSession.get()?.setMetadata(md.build())
169169
mediaSession.get()?.setActive(true)
170-
mediaNotificationManager.get()?.show(nb, isPlaying)
170+
mediaNotificationManager.get()?.updateNotification(nb, isPlaying)
171171
}
172172

173173
fun resetLockScreenInfo() {
174174
if (artworkThread != null && artworkThread!!.isAlive) artworkThread!!.interrupt()
175175
artworkThread = null
176176

177-
mediaNotificationManager.get()?.hide()
177+
mediaNotificationManager.get()?.cancelNotification()
178178
mediaSession.get()?.setActive(false)
179179
}
180180

@@ -235,7 +235,7 @@ class LockScreenManager(
235235
updateNotificationMediaStyle()
236236

237237
if (mediaSession.get()?.isActive == true) {
238-
mediaNotificationManager.get()?.show(nb, isPlaying)
238+
mediaNotificationManager.get()?.updateNotification(nb, isPlaying)
239239
}
240240
}
241241

0 commit comments

Comments
 (0)