Проблемы медиапроекции на Android 9+ - PullRequest
1 голос
/ 09 июля 2019

Я сделал приложение для оптического распознавания текста, которое делает скриншот с помощью медиапроекции Android и обрабатывает текст на этом изображении. Это работает нормально, за исключением Android 9+. Когда запускается медиапроект, всегда появляется окно с предупреждением о конфиденциальных данных, которые могут быть записаны, и кнопка для отмены или начала записи. Как я могу добиться, чтобы это окно отображалось только один раз?

Я попытался предотвратить его появление, создав две дополнительные частные статические переменные для хранения намерения и результирующих данных медиапроекции, и повторно использовав их, если они не равны NULL. Но это не сработало (об этом методе читайте в другом посте)

popup window

// инициализация MP

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

// Запуск MediaProjection

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

// OnActivityResult protected void onActivityResult (окончательный int requestCode, окончательный int resultCode, окончательные данные Intent) {

    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);


        }

}

Мой код работает нормально на версиях Android ниже Android 9. На старых версиях Android я могу оставить это решение, чтобы предоставить разрешение на запись, и оно никогда не появится снова. Так что я могу сделать в Android 9?

Заранее спасибо, я рад за каждую вашу идею :) 1021 *

1 Ответ

2 голосов
/ 10 июля 2019

Ну, проблема была в том, что я звонил startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE); каждый раз, что не нужно (createScreenCaptureIntent() приводит к диалоговому окну, которое запрашивает взаимодействие с пользователем). Мое решение заставляет диалоговое окно появляться только один раз (если приложение было закрыто, оно будетпопросить разрешения еще раз).Все, что мне нужно было сделать, это создать дополнительные частные статические переменные типа Intent и int.

private static Intent staticIntentData; private static int staticResultCode;

В результате действия Activity я присваиваю эти переменные с переданным кодом результата и намерением:

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

Каждый раз, когда я вызываю метод startprojection, я проверяю, равны ли они нулю:

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

Если значение равно нулю, он запросит разрешение, если нет, то запустит проекцию со статическими данными намерений и статическим кодом результата int, поэтому нет необходимости запрашивать это разрешение снова,просто используйте то, что вы получаете в результате действия.

sMediaProjection = mProjectionManager.getMediaProjection(staticResultCode, staticIntentData);

Просто!Теперь он будет отображаться только один раз каждый раз, когда вы используете приложение.Я думаю, это то, чего хочет Google, потому что в этом диалоговом окне нет флажка держать решение, как в предыдущих версиях Android.

...