8000 App crash in Android 14 · Issue #1631 · flutter-webrtc/flutter-webrtc · GitHub
[go: up one dir, main page]

Skip to content
8000

App crash in Android 14 #1631

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

Open
harshmdr opened this issue Jul 17, 2024 · 20 comments
Open

App crash in Android 14 #1631

harshmdr opened this issue Jul 17, 2024 · 20 comments

Comments

@harshmdr
Copy link

E/AndroidRuntime( 7187): java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION

I am using flutter_webrtc: 0.9.27.
var stream = await navigator.mediaDevices.getDisplayMedia({
'video': {'deviceId': 'broadcast'},
'audio': false
});

Any solution?

@Diya-Yi
Copy link
Diya-Yi commented Jul 19, 2024

call this method Helper.requestCapturePermission() before navigator.mediaDevices.getDisplayMedia

@harshmdr
Copy link
Author

Thank you @Diya-Yi

@harshmdr harshmdr reopened this Jul 19, 2024
@harshmdr
Copy link
Author

Not working after set targetSdversion to 34

Failed to handle method call
E/MethodChannel#FlutterWebRTC.Method( 6423): java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Parcel.createExceptionOrNull(Parcel.java:3057)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Parcel.createException(Parcel.java:3041)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Parcel.readException(Parcel.java:3024)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Parcel.readException(Parcel.java:2966)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.media.projection.IMediaProjection$Stub$Proxy.start(IMediaProjection.java:313)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.media.projection.MediaProjection.(MediaProjection.java:84)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.media.projection.MediaProjection.(MediaProjection.java:75)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.media.projection.MediaProjectionManager.getMediaProjection(MediaProjectionManager.java:236)
E/MethodChannel#FlutterWebRTC.Method( 6423): at com.cloudwebrtc.webrtc.OrientationAwareScreenCapturer.startCapture(OrientationAwareScreenCapturer.java:123)
E/MethodChannel#FlutterWebRTC.Method( 6423): at com.cloudwebrtc.webrtc.GetUserMediaImpl.getDisplayMedia(GetUserMediaImpl.java:559)
E/MethodChannel#FlutterWebRTC.Method( 6423): at com.cloudwebrtc.webrtc.GetUserMediaImpl.getDisplayMedia(GetUserMediaImpl.java:511)
E/MethodChannel#FlutterWebRTC.Method( 6423): at com.cloudwebrtc.webrtc.MethodCallHandlerImpl.getDisplayMedia(MethodCallHandlerImpl.java:1404)
E/MethodChannel#FlutterWebRTC.Method( 6423): at com.cloudwebrtc.webrtc.MethodCallHandlerImpl.onMethodCall(MethodCallHandlerImpl.java:634)
E/MethodChannel#FlutterWebRTC.Method( 6423): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:267)
E/MethodChannel#FlutterWebRTC.Method( 6423): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:292)
E/MethodChannel#FlutterWebRTC.Method( 6423): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:319)
E/MethodChannel#FlutterWebRTC.Method( 6423): at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Handler.handleCallback(Handler.java:958)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Looper.loopOnce(Looper.java:205)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Looper.loop(Looper.java:294)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.app.ActivityThread.main(ActivityThread.java:8177)
E/MethodChannel#FlutterWebRTC.Method( 6423): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#FlutterWebRTC.Method( 6423): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
E/MethodChannel#FlutterWebRTC.Method( 6423): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
E/MethodChannel#FlutterWebRTC.Method( 6423): Caused by: android.os.RemoteException: Remote stack trace:
E/MethodChannel#FlutterWebRTC.Method( 6423): at com.android.server.media.projection.MediaProjectionManagerService$MediaProjection.start(MediaProjectionManagerService.java:940)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.media.projection.IMediaProjection$Stub.onTransact(IMediaProjection.java:192)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Binder.execTransactInternal(Binder.java:1339)
E/MethodChannel#FlutterWebRTC.Method( 6423): at android.os.Binder.execTransact(Binder.java:1275)
E/MethodChannel#FlutterWebRTC.Method( 6423):

@harshmdr
Copy link
Author
harshmdr commented Jul 19, 2024

When I do a fresh install and then

await Helper.requestCapturePermission()
var stream = await navigator.mediaDevices.getDisplayMedia({
'video': {'deviceId': 'broadcast'},
'audio': false
});

then gives error but after restart again then it works properly. Looks like android is not listening permission properly without hard reload.

@harshmdr
Copy link
Author

@Diya-Yi can you please help here?

@harshmdr
Copy link
Author
harshmdr commented Jul 19, 2024

Also now it shows me 2 popups to start recording after adding await Helper.requestCapturePermission()

@lambiengcode
Copy link
Contributor

hi @harshmdr-devslane,

Add this in your AndroidManifest.xml

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"/>

Before call getDisplayMedia, add this:

final isGranted = await Helper.requestCapturePermission();

if (!isGranted) return;

@harshmdr
Copy link
Author
harshmdr commented Aug 3, 2024

I am using the same code and I have got isGranted is true after allow but fails java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION at only first time and then after restart, it is working fine.

@harshmdr
Copy link
Author
harshmdr commented Aug 3, 2024

I am using android Emulator so may be the reason of it. I will try in real device and then let you know.
Thanks @lambiengcode

@harshmdr
Copy link
Author
harshmdr commented Aug 5, 2024

@lambiengcode Not working first time only.

@lambiengcode
Copy link
Contributor
final isGranted = await Helper.requestCapturePermission();

if (!isGranted) return;

// start foreground service

var stream = await navigator.mediaDevices.getDisplayMedia({

Have you started the foreground service yet? @harshmdr-devslane

@harshmdr
Copy link
Author
harshmdr commented Aug 5, 2024

yes, i have stared foreground service using flutter_background

@harshmdr
Copy link
Author
harshmdr commented Aug 5, 2024

Is the sequence matters?
My sequence is

  1. Start foreground service while app init.[One time]
  2. Helper.requestCapturePermission() [while start broadcasting everytime]
  3. navigator.mediaDevices.getDisplayMedia [Everytime]

@harshmdr
Copy link
Author
harshmdr commented Aug 5, 2024

I changed the sequence but still same result. Not working for first time.

@victortive
Copy link
victortive commented Aug 6, 2024

This error is because Android 14 requires android:foregroundServiceType to be declared on the service tag in the android manifest file Example

<service
    android:name="de.julianassmann.flutter_background.IsolateHolderService"
    android:enabled="true"
    android:exported="false"
    android:foregroundServiceType="mediaProjection" />

@harshmdr
Copy link
Author
harshmdr commented Aug 7, 2024

Hi @victortive
I am using the same code.
Only first time after install the app and after give permission, it give me the error and then after every time, it is working fine.

@EnterSoftwareSolutions
Copy link

Anyone who has found the solution?

@holzgeist
Copy link
Contributor

Hi there,

I just solved a similar issue and stumbled over this issue

Is the sequence matters? My sequence is
1. Start foreground service while app init.[One time]
2. Helper.requestCapturePermission() [while start broadcasting everytime]
3. navigator.mediaDevices.getDisplayMedia [Everytime]

Yes, ordering matters, you need to first request capture permission, then start the foreground service (and then do whatever you do, getDisplayMedia in this case)

According to the docs, the "standard" permission needs to be granted before attemping to use the foreground permission.

For example, if you try to launch a foreground service of type location, the system checks to make sure your app already has either the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission. If it doesn't, the system throws SecurityException.

@ardeshir-33033
Copy link
ardeshir-33033 commented Jan 20, 2025

For any viewers, this is what you must do to share your screen on Android 14+.

  1. Add package flutter_background
  2. Add this in your AndroidManifest
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION" />

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"/>
  1. Add this to your AndroidManifest
    <service android:name="de.julianassmann.flutter_background.IsolateHolderService" android:foregroundServiceType="mediaProjection" android:enabled="true" android:exported="false"/>
  2. Call this function in main function of your app
 Future<bool> startForegroundService() async {
 const androidConfig = FlutterBackgroundAndroidConfig(
   notificationTitle: 'Title of the notification',
   notificationText: 'Text of the notification',

 );
 await FlutterBackground.initialize(androidConfig: androidConfig);
 return true;
}
  1. Call This function to share the screen
 Future<void> screenSharing() async {
  FlutterBackground.enableBackgroundExecution();
  final isGranted = await Helper.requestCapturePermission();
  if (!isGranted) return;
  _shareStream = await navigator.mediaDevices.getDisplayMedia({
    'audio': true,
    'video': {
      'cursor': 'always',
    },
  });

  await _replaceStream(_shareStream!);
}

@Sam15b
Copy link
Sam15b commented Apr 9, 2025

For any viewers, this is what you must do to share your screen on Android 14+.

  1. Add package flutter_background
  2. Add this in your AndroidManifest
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION" />

  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"/>
  1. Add this to your AndroidManifest
    <service android:name="de.julianassmann.flutter_background.IsolateHolderService" android:foregroundServiceType="mediaProjection" android:enabled="true" android:exported="false"/>
  2. Call this function in main function of your app
 Future<bool> startForegroundService() async {
 const androidConfig = FlutterBackgroundAndroidConfig(
   notificationTitle: 'Title of the notification',
   notificationText: 'Text of the notification',

 );
 await FlutterBackground.initialize(androidConfig: androidConfig);
 return true;
}
  1. Call This function to share the screen
 Future<void> screenSharing() async {
  FlutterBackground.enableBackgroundExecution();
  final isGranted = await Helper.requestCapturePermission();
  if (!isGranted) return;
  _shareStream = await navigator.mediaDevices.getDisplayMedia({
    'audio': true,
    'video': {
      'cursor': 'always',
    },
  });

  await _replaceStream(_shareStream!);
}

But this is not working on Android 14 and 15 . it is Only working when you force your targetsdk to 28 . But this is not good when you publishing your App in google console. Becuz Google play console want taget sdk 33+. And Also what is your requestCapturePermission() , when i added this Permission it throw me error .

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

8 participants
0