Невозможно получить доступ к камере из Android 10 веб-просмотра - PullRequest
0 голосов
/ 04 мая 2020

При обновлении до Android 10 код onShowFileChooser, который я использовал в своем приложении Hybrid Android Web View, так как Android 5 или 6 прекратил предоставлять доступ к камере. Пользователь все еще может получить доступ к сохраненным фотографиям, но опция камеры больше не предлагается пользователю.

Код, который я использовал, показан ниже

      //For Android 5.0+
    public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
        {
        if(mUMA != null)
            {
            mUMA.onReceiveValue (null);
            }
        mUMA = filePathCallback;
        Intent takePictureIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity (MainActivity.this.getPackageManager()) != null)
            {
            File photoFile = null;
            try
                {
                photoFile = createImageFile();
                takePictureIntent.putExtra("PhotoPath", mCM);
                }
            catch(IOException ex)
                {
                Log.e(TAG, "Image file creation failed", ex);
                }
            if (photoFile != null)
                {
                mCM = "file:" + photoFile.getAbsolutePath();
                takePictureIntent.putExtra (MediaStore.EXTRA_OUTPUT, Uri.fromFile (photoFile));
                }
            else
                {
                takePictureIntent = null;
                }
            }
        Intent contentSelectionIntent = new Intent (Intent.ACTION_GET_CONTENT);
        contentSelectionIntent.addCategory (Intent.CATEGORY_OPENABLE);
        contentSelectionIntent.setType ("image/*");
        Intent[] intentArray;
        if (takePictureIntent != null)
            {
            intentArray = new Intent[] {takePictureIntent};
            }
        else
            {
            intentArray = new Intent[0];
            }

        Intent chooserIntent = new Intent (Intent.ACTION_CHOOSER);
        chooserIntent.putExtra (Intent.EXTRA_INTENT, contentSelectionIntent);
        chooserIntent.putExtra (Intent.EXTRA_TITLE, "Image Chooser");
        chooserIntent.putExtra (Intent.EXTRA_INITIAL_INTENTS, intentArray);
        startActivityForResult (chooserIntent, FileChooserActivityCode);
        return true;
        }

вместе со следующим кодом для обработать результат

protected void onActivityResult (int requestCode, int resultCode, Intent intent)
    {
    super.onActivityResult(requestCode, resultCode, intent);

    if (requestCode == FileChooserActivityCode)
        {
        Uri[] results = null;
        //Check if response is positive
        if (resultCode == Activity.RESULT_OK)
            {
            if (null == mUMA)
                {
                return;
                }
            if (intent == null || intent.getData() == null)
                {
                //Capture Photo if no image available
                if (mCM != null)
                    {
                    results = new Uri[]{Uri.parse(mCM)};
                    }
                }
            else
                {
                String dataString = intent.getDataString();
                if(dataString != null)
                    {
                    results = new Uri[]{Uri.parse(dataString)};
                    }
                }
            }
        mUMA.onReceiveValue(results);
        mUMA = null;
        }
    }

Я узнал, как получить доступ к камере из этой ссылки и изменил код takePictureIntent следующим образом:

    if(takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {

    File photoFile = null;
    Uri photoUri = null;

    if (isAndroidQ) {
        // Android Q compatibility
        photoUri = createImageUri();
        mCameraUri = photoUri;
        if (photoUri != null) {
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
        }
    } else {
        try {
            photoFile = createImageFile();
            takePictureIntent.putExtra("PhotoPath", mCM);
        } catch (IOException ex) {
            Log.e(LOG_TAG, "Image file creation failed", ex);
        }
        if (photoFile != null) {
            mCM = "file:" + photoFile.getAbsolutePath();
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
        } else {
            takePictureIntent = null;
        }
    }
}

private Uri createImageUri()
        {
        String status = Environment.getExternalStorageState();
        if (status.equals(Environment.MEDIA_MOUNTED))
            {
            return MainActivity.this.getApplicationContext().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
            }
        else
            {
            return MainActivity.this.getApplicationContext().getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, new ContentValues());
            }
        }

Но сейчас после съемки фотографии в коде onActivityResult переменная mCM равна нулю, и в веб-представление ничего не передается.

Пожалуйста, кто-нибудь может сказать мне, что я пропустил?

Ответы [ 2 ]

0 голосов
/ 05 мая 2020

Все, что нужно было добавить, было

else if (mCameraUri != null)
                    {
                    results = new Uri[]{mCameraUri};
                    }
0 голосов
/ 04 мая 2020

Если вы нацелены на Android 10 - эта версия представляет новый, более безопасный / приватный способ доступа к хранилищу с именем Scoped Storage. проверьте ЭТУ статью для получения дополнительной информации о том, как реализовать

для более сложного решения, вы должны показать, что происходит в createImageUri и createImageFile методах

ЗДЕСЬ у нас хорошо получается c как обращаться со старым и новым способом

опционально вы можете отключить новый способ доступа, но только для Android 10, начиная с 11 эта поддержка потребуется. Добавьте android:requestLegacyExternalStorage="true" для <application> тег в манифест

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...