升级到 Android 10 后,自从 Android 5 或 6 停止提供对相机的访问以来,我一直在混合 Android Web View 应用程序中使用 onShowFileChooser 代码。用户仍然可以访问存储的照片,但不再向用户提供相机选项。
我一直使用的代码如下所示
//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;
}
}
我已经从 this link 找到了如何访问相机并将 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 为 null,并且没有任何内容传递到 Web View 。
请问有人可以告诉我我错过了什么吗?
最佳答案
如果您的目标是 Android 10 - 此版本引入了一种新的、更安全/私密的存储访问方式,名为“作用域存储”。查看THIS文章了解如何实现的更多信息
对于更复杂的解决方案,您应该显示 createImageUri
中发生的情况和createImageFile
方法
HERE我们有很好的文档如何处理新旧方式
您可以选择禁用新的访问方式,但仅适用于 Android 10,从 11 开始将需要此支持。添加android:requestLegacyExternalStorage="true"
对于 <application>
list 中的标签
关于android - 无法从 Android 10 Web View 访问相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61590038/