Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microphone Not Working in Background on Android Device #254

Open
vishalyad16 opened this issue Jan 27, 2025 · 19 comments
Open

Microphone Not Working in Background on Android Device #254

vishalyad16 opened this issue Jan 27, 2025 · 19 comments

Comments

@vishalyad16
Copy link

vishalyad16 commented Jan 27, 2025

Hi

While the app is in the background, the microphone isn't working. However, it functions properly when the app is in the foreground, where both camera and microphone permissions are granted.

how can i solve this ?

I’m facing an issue where the microphone stops working when the app is in the background, even though the camera and microphone permissions are correctly granted when the app is in the background and it functions properly when the app is in foreground.

Can you please assist in resolving this? It would be greatly appreciated if someone could help or provide any guidance on how to fix this behavior.

Thanks in advance!

Image
Image

@KartikLakhani009
Copy link

I have similar issue
after 2 second the voice permission icon disappear that's the make as microphone off and voice saved as blank
i am still finding solution or work around

@vishalyad16
Copy link
Author

vishalyad16 commented Jan 27, 2025

@KartikLakhani009, if you find a solution, please share it. I’ve been searching for a solution for the past week.

@Rapsssito, could you please help with the solution?

@IIvexII
Copy link

IIvexII commented Feb 4, 2025

@KartikLakhani009 @vishalyad16 Did you find any fix for this?

@vishalyad16
Copy link
Author

@IIvexII I’m still figuring out the solution.

@IIvexII
Copy link

IIvexII commented Feb 5, 2025

@vishalyad16 After days of struggle, I have resolved this issue by only running a background service.

npm i react-native-background-actions

After the installation, I converted my expo to bare react native project:

npx expo prebuild

In android>app>src>main>AndroidManifest.xml I added the following permissions and services:

  <uses-permission android:name="android.permission.WAKE_LOCK"/>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

and between application tag I added this

 <application>
       ...............other things
        <service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" android:foregroundServiceType="shortService|microphone|mediaPlayback|mediaProjection"/>
       ...............other things or at the end
</application>

Here is the basic code to start and stop the background service, feel free to change the parameters

import BackgroundService from "react-native-background-actions";

// this start a background service that will keep the microphone access alive
    await BackgroundService.start(taskToMakeMicAlive, {
      taskName: "MicrophoneIndicator",
      taskTitle: "[NOTICE] Mic is being used",
      taskDesc: "",
      taskIcon: {
        name: "ic_launcher_foreground", // you should be very carefull when mentioningthe name of icon its in android>app>src>main>res><inside every folder starting with mipmap> this icon can make or break this functionality of background service so be carefull, I have waste immense amount of time on this :P 
        type: "mipmap",
      },
      color: "#010816",
      linkingURI: "JoinScreen",
      parameters: {
        delay: 2000,
      },
    });

// this will stop the background service
await BackgroundService.stop();

Here is the actual function that will run in the background:

async function taskToMakeMicAlive(taskDataArguments: { delay: number } | undefined) {
    if (!taskDataArguments) return;

    const { delay } = taskDataArguments;
    console.log(BackgroundService.isRunning());
    while (BackgroundService.isRunning()) {
      // wait for the delay time
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }

@vishalyad16
Copy link
Author

@IIvexII Please send me the code snippet from node_modules/react-native-background-actions/android/src/main/AndroidManifest.xml.

@IIvexII
Copy link

IIvexII commented Feb 5, 2025

do you have android folder in your project?

@vishalyad16
Copy link
Author

Yes I am using CLI

@IIvexII
Copy link

IIvexII commented Feb 5, 2025

I didn't edited the node_modules/react-native-background-actions/android/src/main/AndroidManifest.xml, so it will be same as yours. Please change the android>app>src>main>AndroidManifest.xml :
Here is mine if it can help:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  <uses-permission android:name="android.permission.BLUETOOTH"/>
  <uses-permission android:name="android.permission.CAMERA"/>
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.VIBRATE"/>
  <uses-permission android:name="android.permission.WAKE_LOCK"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

  <queries>
    <intent>
      <action android:name="android.intent.action.VIEW"/>
      <category android:name="android.intent.category.BROWSABLE"/>
      <data android:scheme="https"/>
    </intent>
  </queries>
  <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true">
    <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="default"/>
    <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/notification_icon_color"/>
    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon"/>
    <meta-data android:name="expo.modules.notifications.default_notification_color" android:resource="@color/notification_icon_color"/>
    <meta-data android:name="expo.modules.notifications.default_notification_icon" android:resource="@drawable/notification_icon"/>
    <meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
    
    <service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" android:foregroundServiceType="shortService|microphone|mediaPlayback|mediaProjection"/>


    <activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="com.zafeerhafeez.AudioMeet"/>
        <data android:scheme="exp+audio-meet"/>
      </intent-filter>
    </activity>
  </application>
</manifest>

@vishalyad16
Copy link
Author

vishalyad16 commented Feb 5, 2025

@IIvexII I'm facing a build issue while adding it.

<service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" android:foregroundServiceType="shortService|microphone|mediaPlayback|mediaProjection"/>

android\app\src\debug\AndroidManifest.xml:33:85-156 Error:
Attribute service#com.asterinet.react.bgactions.RNBackgroundActionsTask@foregroundServiceType value=(shortService|microphone|mediaProjection) from AndroidManifest.xml:33:85-156
is also present at [:react-native-background-actions] AndroidManifest.xml:10:13-53 value=(dataSync).
Suggestion: add 'tools:replace="android:foregroundServiceType"' to element at AndroidManifest.xml to override.

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':app:processDebugMainManifest'.

Manifest merger failed with multiple errors, see logs

@IIvexII
Copy link

IIvexII commented Feb 5, 2025

It seems like there 2 services defined with the same name but different value. Remove the one that have value of value=(dataSync) and make sure that you have not edited the AndroidManifest of the package. You should only modify the one present in your project's android folder.

If the problem persist then re-install the package react-native-background-actions.

@vishalyad16
Copy link
Author

vishalyad16 commented Feb 7, 2025

It seems like there 2 services defined with the same name but different value. Remove the one that have value of value=(dataSync) and make sure that you have not edited the AndroidManifest of the package. You should only modify the one present in your project's android folder.

If the problem persist then re-install the package react-native-background-actions.

@IIvexII I tried the solution above, but the app now crashes when it goes into the background.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.asterinet.react.bgactions"> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <application> <service android:name=".RNBackgroundActionsTask"/> </application> </manifest>

@IIvexII
Copy link

IIvexII commented Feb 7, 2025

@vishalyad16 I am facing the same issue in android 14 and above version. This is working fine in 13 and less. The problem is with shortService. I will try to fix mine then I'll share the solution if successful.

@vishalyad16
Copy link
Author

Okay @IIvexII

@IIvexII
Copy link

IIvexII commented Feb 12, 2025

@vishalyad16 Sorry for the late reply, I was busy in some other things. By the way, I have found and fixed the root causes that was making the app crash.

  • shortService - I have removed it and added new foreground service type i.e. dataSync
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
    
    ... under application
    <service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" android:foregroundServiceType="dataSync|microphone|mediaPlayback"/>
    ...
    
  • removed the unused permission and forground type i.e. mediaProjection. Because I don't need the permission to record the screen, but if you want to record then you have to explicitly ask the permission from the user.

@vishalyad16
Copy link
Author

vishalyad16 commented Feb 12, 2025

@IIvexII , thanks for the reply. Can you please send me the code for android/app/src/main/AndroidManifest.xml?

@IIvexII
Copy link

IIvexII commented Feb 12, 2025

Sure!! Here is the code:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  <uses-permission android:name="android.permission.BLUETOOTH"/>
  <uses-permission android:name="android.permission.CAMERA"/>
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.VIBRATE"/>
  <uses-permission android:name="android.permission.WAKE_LOCK"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />

  <queries>
    <intent>
      <action android:name="android.intent.action.VIEW"/>
      <category android:name="android.intent.category.BROWSABLE"/>
      <data android:scheme="https"/>
    </intent>
  </queries>
  <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true">
    <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="default"/>
    <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/notification_icon_color"/>
    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon"/>
    <meta-data android:name="expo.modules.notifications.default_notification_color" android:resource="@color/notification_icon_color"/>
    <meta-data android:name="expo.modules.notifications.default_notification_icon" android:resource="@drawable/notification_icon"/>
    <meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
    
    <service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" android:foregroundServiceType="dataSync|microphone|mediaPlayback"/>


    <activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="dummy scheme"/>
        <data android:scheme="exp+audio-meet"/>
      </intent-filter>
    </activity>
  </application>
</manifest>

@vishalyad16
Copy link
Author

@IIvexII it is still crashing on samsung device

@shehharyar
Copy link

shehharyar commented Feb 23, 2025

FOREGROUND_SERVICE_MICROPHONE and other permissions are introduced in ANDROID > 13 , which might be not included in react native permissions, that's why the app is being crashed in android 14 or above while we are defining these permissions in AndroidManifest.xml. In my case, i did all the above stuff and I added manually this permission (FOREGROUND_SERVICE_MICROPHONE) in my code , which works for me. Here's my code :

const PERMISSIONS = {
FOREGROUND_SERVICE_MICROPHONE: "android.permission.FOREGROUND_SERVICE_MICROPHONE",
};
const requestForegroundPermissions = async () => {
if (Platform.OS === 'android' && Platform.Version >= 34) {
try {
const granted = await PermissionsAndroid.request(
PERMISSIONS.FOREGROUND_SERVICE_MICROPHONE,
{
title: "Background Microphone Permission",
message: "This app requires access to microphone to record in background.",
buttonPositive: "OK",
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Foreground Service permissions granted');
return true;
} else {
console.log('Foreground Service permissions denied');
return false;
}
} catch (err) {
console.warn(err);
}

  } 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants