Avec les nouveaux changements de confidentialité en vigueur avec Android Q, il est désormais obligatoire pour toute application utilisant MediaProjection
api de spécifier Android: foregroundServiceType dans l'attribut étiquette de service sous manifeste.
Mais récemment, j'ai remarqué que même si je définissais le Android:foregroundServiceType="mediaprojection"
une exception de sécurité est levée. Quelqu'un a-t-il une idée de ce que je fais mal?
Manifeste:
<service
Android:name=".services.MediaProjectionService"
Android:enabled="true"
Android:exported="false"
Android:foregroundServiceType="mediaProjection" />
Exception levée:
Java.lang.RuntimeException: Unable to start service com.package.app.services.MediaProjectionService@6d0fed2 with Intent { act=com.package.app.services.action.startrecording cmp=com.package.app/.services.MediaProjectionService(has extras) }: Java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
at Android.app.ActivityThread.handleServiceArgs(ActivityThread.Java:4103)
at Android.app.ActivityThread.access$1800(ActivityThread.Java:219)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1891)
at Android.os.Handler.dispatchMessage(Handler.Java:107)
at Android.os.Looper.loop(Looper.Java:214)
at Android.app.ActivityThread.main(ActivityThread.Java:7343)
at Java.lang.reflect.Method.invoke(Native Method)
at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.Java:492)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:933)
Caused by: Java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
at Android.os.Parcel.createException(Parcel.Java:2071)
at Android.os.Parcel.readException(Parcel.Java:2039)
at Android.os.Parcel.readException(Parcel.Java:1987)
at Android.media.projection.IMediaProjection$Stub$Proxy.start(IMediaProjection.Java:231)
at Android.media.projection.MediaProjection.<init>(MediaProjection.Java:58)
at Android.media.projection.MediaProjectionManager.getMediaProjection(MediaProjectionManager.Java:104)
at com.package.app.services.MediaProjectionService.startRecording(MediaProjectionService.Java:190)
at com.package.app.services.MediaProjectionService.onStartCommand(MediaProjectionService.Java:142)
at Android.app.ActivityThread.handleServiceArgs(ActivityThread.Java:4085)
at Android.app.ActivityThread.access$1800(ActivityThread.Java:219)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1891)
at Android.os.Handler.dispatchMessage(Handler.Java:107)
at Android.os.Looper.loop(Looper.Java:214)
at Android.app.ActivityThread.main(ActivityThread.Java:7343)
at Java.lang.reflect.Method.invoke(Native Method)
at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.Java:492)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:933)
Caused by: Android.os.RemoteException: Remote stack trace:
at com.Android.server.media.projection.MediaProjectionManagerService$MediaProjection.start(MediaProjectionManagerService.Java:476)
at Android.media.projection.IMediaProjection$Stub.onTransact(IMediaProjection.Java:135)
at Android.os.Binder.execTransactInternal(Binder.Java:1021)
at Android.os.Binder.execTransact(Binder.Java:994)
P.S: Cela se produit sur Android Q DP5 GSI avec le SDK cible 29. L'application fonctionne correctement avec le SDK cible 28 sans aucun changement.
N'oubliez pas d'ajouter la permission <uses-permission Android:name="Android.permission.FOREGROUND_SERVICE" />
Dans AndroidManifest.xml
?
MISE À JOUR
Assurez-vous d'appeler startForeground()
avantgetMediaProjection()
!
La meilleure solution consiste à appeler startForeground()
à partir de onCreate()
sans aucune condition, affichant une sorte de messages par défaut dans la notification. Ensuite, vous pouvez exécuter votre logique et appeler à tout moment NotificationManager.notify()
avec une notification mise à jour.
Modification des attributs suivants
Android:foregroundServiceType="mediaProjection"
tools:targetApi="q"
dans AndroidManifest.xml a fonctionné pour moi.
< service
Android:name="SERVICE_NAME"
Android:foregroundServiceType="mediaProjection"
tools:targetApi="q"
Android:enabled="true"
Android:exported="false" />