Error getMediaProjection when targetSdkVersion 29

Viewed 1980

I am building a screen recording application. But it only works on targetSdkVersion 28, when passing targetSdkVersion 29 requested by google, the error

Code

    @SuppressLint("MissingSuperCall")
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode != REQUEST_CODE) {
            Toast.makeText(this, "Error!", Toast.LENGTH_SHORT).show();
            return;
        }
        if (resultCode != RESULT_OK) {
            Toast.makeText(this,
                    "Screen Cast Permission Denied", Toast.LENGTH_SHORT).show();
            return;
        }
        mMediaProjectionCallback = new MediaProjectionCallback();

        mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
        mMediaProjection.registerCallback(mMediaProjectionCallback, null);
        mVirtualDisplay = createVirtualDisplay();
        mMediaRecorder.start();
    }

Error was thrown

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.megamestudio.screen_record_and_booster, PID: 21862
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1000, result=-1, data=Intent { (has extras) }} to activity {com.megamestudio.screen_record_and_booster/com.megamestudio.screen_record_and_booster.MainActivity}: java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4927)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4968)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7548)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
     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:2074)
        at android.os.Parcel.readException(Parcel.java:2042)
        at android.os.Parcel.readException(Parcel.java:1990)
        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.megamestudio.screen_record_and_booster.MainActivity.onActivityResult(MainActivity.java:426)

Please help me, thanks

2 Answers

This is the solution after some time of research. First of all, follow the other answers.

  1. manifest permission
  2. start service on the foreground

this is the answer that I had

  1. On the service, onStartCommand(), I implemented this method for the android Q. (less than Q, it works without this codes): startForeground(id, notification, serviceType)
public int onStartCommand(Intent intent, int flags, int startId) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            Notification notification = ScreenRecorderHelper.GetMediaProjectionNotification(AppShared.gContext);
            startForeground(startId,
                    notification,
                    ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION);
        }



        handleCommand(intent);
        // We want this service to continue running until it is explicitly
        // stopped, so return sticky.
        return START_STICKY;
    }

I hope this helps many others like me...

Add android:foregroundServiceType="mediaProjection" to the element in the manifest for your service and this issue will be gone.

Related