From e6252cd7ca4dc7157e0c2179cc596f9394e0f190 Mon Sep 17 00:00:00 2001 From: Ritik Khatri Date: Sat, 22 Nov 2025 18:54:07 +0530 Subject: [PATCH 1/2] fix: request record permission on 14+ android versions --- app/app/hooks/useAudioStreamer.ts | 38 +++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/app/app/hooks/useAudioStreamer.ts b/app/app/hooks/useAudioStreamer.ts index 51e9c8ce..2a2a096c 100644 --- a/app/app/hooks/useAudioStreamer.ts +++ b/app/app/hooks/useAudioStreamer.ts @@ -1,6 +1,6 @@ // useAudioStreamer.ts import { useState, useRef, useCallback, useEffect } from 'react'; -import { PermissionsAndroid, Platform } from 'react-native'; +import { Alert, PermissionsAndroid, Platform } from 'react-native'; import notifee, { AndroidImportance } from '@notifee/react-native'; import NetInfo from '@react-native-community/netinfo'; @@ -53,10 +53,44 @@ async function ensureNotificationPermission() { } } +// On Android 14+ (API 34+), FOREGROUND_SERVICE_MICROPHONE requires RECORD_AUDIO +// FOREGROUND_SERVICE_MICROPHONE is automatically granted when RECORD_AUDIO is granted +// We must ensure RECORD_AUDIO is granted BEFORE starting the foreground service +async function ensureForegroundServiceMicPermission() { + if (Platform.OS !== 'android' || Platform.Version < 34) { + return true; + } + try { + const audioGranted = await PermissionsAndroid.check( + PermissionsAndroid.PERMISSIONS.RECORD_AUDIO + ); + + if (!audioGranted) { + console.log('[AudioStreamer] Requesting RECORD_AUDIO permission...'); + const audioResult = await PermissionsAndroid.request( + PermissionsAndroid.PERMISSIONS.RECORD_AUDIO + ); + if (audioResult !== PermissionsAndroid.RESULTS.GRANTED) { + Alert.alert('RECORD_AUDIO permission is required for microphone foreground service. Please grant microphone permission in app settings.'); + return false; + } + } + + console.log('[AudioStreamer] RECORD_AUDIO permission granted. FOREGROUND_SERVICE_MICROPHONE should be automatically available.'); + return true; + } catch (error) { + console.error('[AudioStreamer] Error ensuring foreground service mic permission:', error); + return false; + } +} + async function startForegroundServiceNotification(title: string, body: string) { ensureFgsRegistered(); await ensureNotificationPermission(); - + const success = await ensureForegroundServiceMicPermission(); + if (!success) { + return; + } // Create channel if needed await notifee.createChannel({ id: FGS_CHANNEL_ID, From b59be5725436aaa18aeaeb8065473b76e5d13020 Mon Sep 17 00:00:00 2001 From: Ritik Khatri Date: Sat, 22 Nov 2025 22:10:24 +0530 Subject: [PATCH 2/2] chore: update comment --- app/app/hooks/useAudioStreamer.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/app/hooks/useAudioStreamer.ts b/app/app/hooks/useAudioStreamer.ts index 2a2a096c..916b9bb9 100644 --- a/app/app/hooks/useAudioStreamer.ts +++ b/app/app/hooks/useAudioStreamer.ts @@ -53,9 +53,11 @@ async function ensureNotificationPermission() { } } -// On Android 14+ (API 34+), FOREGROUND_SERVICE_MICROPHONE requires RECORD_AUDIO -// FOREGROUND_SERVICE_MICROPHONE is automatically granted when RECORD_AUDIO is granted -// We must ensure RECORD_AUDIO is granted BEFORE starting the foreground service +// On Android 14+ (API 34+), FOREGROUND_SERVICE_MICROPHONE is a separate manifest permission +// with normal protection level (auto-granted at install time), but it does NOT replace RECORD_AUDIO. +// The manifest must declare FOREGROUND_SERVICE_MICROPHONE, and the app must request/obtain +// RECORD_AUDIO as a runtime permission BEFORE starting the foreground service. +// RECORD_AUDIO remains a dangerous permission that must be requested at runtime. async function ensureForegroundServiceMicPermission() { if (Platform.OS !== 'android' || Platform.Version < 34) { return true; @@ -76,7 +78,7 @@ async function ensureForegroundServiceMicPermission() { } } - console.log('[AudioStreamer] RECORD_AUDIO permission granted. FOREGROUND_SERVICE_MICROPHONE should be automatically available.'); + console.log('[AudioStreamer] RECORD_AUDIO permission granted. FOREGROUND_SERVICE_MICROPHONE must be declared in manifest.'); return true; } catch (error) { console.error('[AudioStreamer] Error ensuring foreground service mic permission:', error);