App crash in Android 14
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?
call this method Helper.requestCapturePermission() before navigator.mediaDevices.getDisplayMedia
Thank you @Diya-Yi
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.
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.
@Diya-Yi can you please help here?
Also now it shows me 2 popups to start recording after adding await Helper.requestCapturePermission()
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;
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.
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
@lambiengcode Not working first time only.
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
yes, i have stared foreground service using flutter_background
Is the sequence matters? My sequence is
Start foreground servicewhile app init.[One time]- Helper.requestCapturePermission() [while start broadcasting everytime]
- navigator.mediaDevices.getDisplayMedia [Everytime]
I changed the sequence but still same result. Not working for first time.
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" />
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.
Anyone who has found the solution?
Hi there,
I just solved a similar issue and stumbled over this issue
Is the sequence matters? My sequence is 1.
Start foreground servicewhile 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.
For any viewers, this is what you must do to share your screen on Android 14+.
- Add package
flutter_background - 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"/>
- Add this to your AndroidManifest
<service android:name="de.julianassmann.flutter_background.IsolateHolderService" android:foregroundServiceType="mediaProjection" android:enabled="true" android:exported="false"/> - 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;
}
- 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!);
}
For any viewers, this is what you must do to share your screen on Android 14+.
- Add package
flutter_background- 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"/>
- Add this to your AndroidManifest
<service android:name="de.julianassmann.flutter_background.IsolateHolderService" android:foregroundServiceType="mediaProjection" android:enabled="true" android:exported="false"/>- 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; }
- 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 .