12

With the new privacy changes in effect with Android Q, it is now mandatory for any app using MediaProjection api to specify android:foregroundServiceType attribute in the service tag under manifest.

But recently, I noticed that though I set the android:foregroundServiceType="mediaprojection" there is a security exception thrown. Does anybody have any idea what I'm doing wrong?

Manifest:

<service
            android:name=".services.MediaProjectionService"
            android:enabled="true"
            android:exported="false"
            android:foregroundServiceType="mediaProjection" />

Exception thrown:

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: This is experienced on Android Q DP5 GSI with target SDK 29. The app works fine with target sdk 28 without any changes.

Vijai
  • 1,067
  • 2
  • 11
  • 25
  • You need this to be a foreground service (`Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION`). Having `foregroundServiceType` is part of that, but is the service a foreground service at runtime (via `startForeground()`)? – CommonsWare Jul 15 '19 at 10:44
  • 1
    The service is started with `startForeground(ID, Notification)` and I did try the new `startForeground(ID, Notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION)` method. The result is the same no mater if the service type is set in manifest or in `startForeground` method. Everything works fine if I set compileSDK to 28 – Vijai Jul 16 '19 at 14:46
  • 1
    `compileSdkVersion` should not have an impact. `targetSdkVersion` might. – CommonsWare Jul 16 '19 at 14:48
  • my bad, that's what I meant. But anyway `targetSdkVersion` and `compileSdkVersion` both set to 28 works fine – Vijai Jul 16 '19 at 15:06

2 Answers2

9

Don't you forget to add permission <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> into AndroidManifest.xml ?

UPDATE

Make sure you call startForeground() before getMediaProjection()!

The best solution is to call startForeground() from onCreate() without any conditions, displaying some sort of default messages in notification. Then you can execute your logic and call NotificationManager.notify() with updated notification at any time.

Oleksii K.
  • 5,359
  • 6
  • 44
  • 72
  • Ofcourse, it is added. The app works fine when downgrading target sdk to 28 – Vijai Jul 26 '19 at 17:49
  • Take a look on my update, I just checked, the order of invocation is very important. – Oleksii K. Jul 26 '19 at 18:30
  • Can you help me with https://stackoverflow.com/questions/63543414/rename-file-of-the-external-storage-which-is-created-by-app-in-android-10-worki – jazzbpn Aug 24 '20 at 03:47
  • Caused by: java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION..... In my cause app is crashed – Parveen Haade Apr 09 '22 at 06:23
4

Changing the following attributes

android:foregroundServiceType="mediaProjection"

tools:targetApi="q"

in AndroidManifest.xml worked for me.

< service

android:name="SERVICE_NAME"

android:foregroundServiceType="mediaProjection"

tools:targetApi="q"

android:enabled="true"

android:exported="false" />
Vijai
  • 1,067
  • 2
  • 11
  • 25
Divyang M
  • 101
  • 1
  • 5
  • That worked for me also after adding to AndroidManifest and set the service as foreground service before the call to MediaProjection. – svprdga May 11 '20 at 08:02