8

I made an OCR application that makes a screenshot using Android mediaprojection and processes the text in this image. This is working fine, except on Android 9+. When mediaprojeciton is starting there is always a window popping up warning about sensitive data that could be recorded, and a button to cancel or start recording. How can I achieve that this window will only be showed once?

I tried preventing it from popping up by creating two extra private static variables to store intent and resultdata of mediaprojection, and reusing it if its not null. But it did not work (read about this method in another post).

popup window

// initializing MP

  mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);

// Starting MediaProjection

 private void startProjection() {
     startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
 }


// OnActivityResult
 protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {

    if (requestCode == 100) {
        if(mProjectionManager == null) {
            cancelEverything();
            return;
        }

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

                if(mProjectionManager != null)
                sMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
                else
                    cancelEverything();
                if (sMediaProjection != null) {
                    File externalFilesDir = getExternalFilesDir(null);
                    if (externalFilesDir != null) {
                        STORE_DIRECTORY = externalFilesDir.getAbsolutePath() + "/screenshots/";

                        File storeDirectory = new File(STORE_DIRECTORY);
                        if (!storeDirectory.exists()) {
                            boolean success = storeDirectory.mkdirs();
                            if (!success) {
                                Log.e(TAG, "failed to create file storage directory.");
                                return;
                            }
                        }
                    } else {
                        Log.e(TAG, "failed to create file storage directory, getExternalFilesDir is null.");
                        return;
                    }

                    // display metrics
                    DisplayMetrics metrics = getResources().getDisplayMetrics();
                    mDensity = metrics.densityDpi;
                    mDisplay = getWindowManager().getDefaultDisplay();

                    // create virtual display depending on device width / height
                    createVirtualDisplay();

                    // register orientation change callback
                    mOrientationChangeCallback = new OrientationChangeCallback(getApplicationContext());
                    if (mOrientationChangeCallback.canDetectOrientation()) {
                        mOrientationChangeCallback.enable();
                    }

                    // register media projection stop callback
                    sMediaProjection.registerCallback(new MediaProjectionStopCallback(), mHandler);
                }



            }
        }, 2000);


        }

}

My code is working fine on Android versions below Android 9. On older android versions I can choose to keep that decision to grant recording permission, and it will never show up again. So what can I do in Android 9?

Thanks in advance, I'm happy for every idea you have :)

greywolf82
  • 21,813
  • 18
  • 54
  • 108
Mori Ruec
  • 305
  • 2
  • 10
  • I have never seen that dialog. What device are you testing on? – CommonsWare Jul 09 '19 at 11:03
  • I'm testing on an Android emulator with Api 29. Even if I type this dialogs text in google I get no results :( – Mori Ruec Jul 09 '19 at 13:11
  • At what point does that dialog appear? Is it from your `startProjection()` method or from where you call `getMediaProjection()`? – CommonsWare Jul 09 '19 at 13:18
  • This makes the dialog appear: startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE); – Mori Ruec Jul 09 '19 at 18:21
  • `public Intent createScreenCaptureIntent() { Intent i = new Intent(); final ComponentName mediaProjectionPermissionDialogComponent = ComponentName.unflattenFromString(mContext.getResources().getString( com.android.internal.R.string .config_mediaProjectionPermissionDialogComponent)); i.setComponent(mediaProjectionPermissionDialogComponent); return i; }` This is the code in MediaProjectionManager that is called, whats missing is the keep decision checkbox in android 9. I need a workaround – Mori Ruec Jul 09 '19 at 18:30
  • 2
    You only need to call that once per process invocation. – CommonsWare Jul 09 '19 at 20:18
  • Yes, you are right :) I'll post an answer to make it clear for others, I already was on the right track, but I guess I did not fully understand what I was doing. – Mori Ruec Jul 10 '19 at 00:34

1 Answers1

9

Well the problem was that I was calling startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE); every time, which is not necessary (createScreenCaptureIntent() leads to the dialog window which requests user interaction) My solution makes the dialog appear only once (if application was closed it will ask for permission one time again). All I had to do was making addiotional private static variables of type Intent and int.

private static Intent staticIntentData; private static int staticResultCode;

On Activity result I assign those variables with the passed result code and intent:

if(staticResultCode == 0 && staticIntentData == null) {
    sMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
    staticIntentData = data;
    staticResultCode = resultCode;
} else {
    sMediaProjection = mProjectionManager.getMediaProjection(staticResultCode, staticIntentData)};
}

Every time I call my startprojection method, I will check if they are null:

if(staticIntentData == null) startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE); else captureScreen();

If null it will request permission, if not it will start the projection with the static intent data and static int resultcode, so it is not needed to ask for that permission again, just reuse what you get in activity result.

sMediaProjection = mProjectionManager.getMediaProjection(staticResultCode, staticIntentData);

Simple as that! Now it will only showing one single time each time you use the app. I guess thats what Google wants, because theres no keep decision checkbox in that dialog like in previous android versions.

greywolf82
  • 21,813
  • 18
  • 54
  • 108
Mori Ruec
  • 305
  • 2
  • 10
  • 1
    After restarting the device or application kill from the system stack then it will again be asking so is any solution to do not ask. – Suhas Bachewar Nov 09 '20 at 12:18