【发布时间】:2022-03-01 00:29:57
【问题描述】:
我遇到的问题是我无法从 webview 打开相机,因为我有 php 页面,所以我必须从那里打开画廊和相机,但我无法从这个链接“@987654321 @"。 我可以打开图库但不能打开相机请给我任何解决方案。
【问题讨论】:
我遇到的问题是我无法从 webview 打开相机,因为我有 php 页面,所以我必须从那里打开画廊和相机,但我无法从这个链接“@987654321 @"。 我可以打开图库但不能打开相机请给我任何解决方案。
【问题讨论】:
Android 7+ 的 Kotlin 工作示例
添加相机权限
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAMERA2" />
配置您的WebView
private fun configureWebViewSettings() {
binding.webView.settings.javaScriptEnabled = true
binding.webView.settings.domStorageEnabled = true
binding.webView.settings.setSupportZoom(false)
binding.webView.settings.allowFileAccess = true
binding.webView.settings.allowContentAccess = true
binding.webView.webChromeClient = getCustomWebChromeClient()
}
将下面的行添加到您的Activity
private var imagePathCallback: ValueCallback<Array<Uri>>? = null
private var cameraImagePath: String? = null
实现WebChromeClient 并将其添加到您的WebView
private fun getCustomWebChromeClient() = object : WebChromeClient() {
override fun onShowFileChooser(
view: WebView?,
filePath: ValueCallback<Array<Uri>>?,
fileChooserParams: FileChooserParams?
): Boolean {
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
requestPermissions(arrayOf(Manifest.permission.CAMERA), CAMERA_REQUEST_CODE)
imagePathCallback?.onReceiveValue(null)
imagePathCallback = null
imagePathCallback = filePath
val takePictureIntent = createImageCaptureIntent()
val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT)
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE)
contentSelectionIntent.type = INTENT_FILE_TYPE
val intentArray: Array<Intent?>
intentArray = takePictureIntent?.let { arrayOf(it) } ?: arrayOfNulls(0)
val chooserIntent = Intent(Intent.ACTION_CHOOSER)
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
chooserIntent.putExtra(Intent.EXTRA_TITLE, getString(R.string.file_chooser_title))
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray)
try {
startActivityForResult(chooserIntent, REQUEST_SELECT_FILE)
} catch (e: ActivityNotFoundException) {
imagePathCallback = null
cameraImagePath = null
Toast.makeText(
this@MainActivity,
getString(R.string.cannot_open_file_chooser_txt),
Toast.LENGTH_LONG
).show()
return false
}
return true
}
private fun createImageCaptureIntent(): Intent? {
var captureImageIntent: Intent? = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (captureImageIntent?.resolveActivity(packageManager) != null) {
var imageFile: File? = null
try {
imageFile = createImageFile()
captureImageIntent.putExtra("CameraImagePath", cameraImagePath)
} catch (ex: IOException) {
ex.printStackTrace()
}
if (imageFile != null) {
cameraImagePath = CAMERA_PHOTO_PATH_POSTFIX + imageFile.absolutePath
captureImageIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile))
} else {
captureImageIntent = null
}
}
return captureImageIntent
}
private fun createImageFile(): File? {
val timeStamp = SimpleDateFormat.getDateInstance().format(Date())
val imageFileName = PHOTO_NAME_POSTFIX + timeStamp + "_"
val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(imageFileName, PHOTO_FORMAT, storageDir)
}
在您的Activity 中实现onRequestPermissionsResult
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == CAMERA_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(
this,
getString(R.string.amera_permission_granted_txt),
Toast.LENGTH_LONG
).show()
} else {
Toast.makeText(
this,
getString(R.string.camera_permission_denied_txt),
Toast.LENGTH_LONG
).show()
}
}
}
在您的Activity 中实现onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode != REQUEST_SELECT_FILE || imagePathCallback == null) return
var results: Array<Uri>? = null
if (resultCode == RESULT_OK) {
if (data == null) {
if (cameraImagePath != null) results = arrayOf(Uri.parse(cameraImagePath))
} else {
val dataString = data.dataString
if (dataString != null) results = arrayOf(Uri.parse(dataString))
}
}
imagePathCallback?.onReceiveValue(results)
imagePathCallback = null
}
常量
companion object {
private const val CAMERA_REQUEST_CODE = 113
private const val REQUEST_SELECT_FILE = 13
private const val INTENT_FILE_TYPE = "image/*"
private const val CAMERA_PHOTO_PATH_POSTFIX = "file:"
private const val PHOTO_NAME_POSTFIX = "JPEG_"
private const val PHOTO_FORMAT = ".jpg"
}
试试看,应该可以的。
【讨论】:
您是否向 WebView 的 WebChromeClient 授予相机权限?
请在您的 AndroidManifest.xml 中添加相机权限。
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAMERA2" />
将 WebChromeClient 设置到您的 WebView 中。
webView.setWebChromeClient(new ChromeClient())
定义您的 ChromeClient 类。
public class ChromeClient extends WebChromeClient {
@Override
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
if (!hasPermissions(MainActivity.this, PERMISSIONS)) {
checkStoragePermission();
return false;
}
// Double check that we don't have any existing callbacks
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "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, "Select Photo");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, Constant.INPUT_FILE_REQUEST_CODE);
return true;
}
}
这里是变量。
String[] PERMISSIONS = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
检查存储和相机权限。
private void checkStoragePermission() {
String permission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, Constant.REQUEST_STORAGE_PERMISSION);
} else {
checkCameraPermission();
}
}
private void checkCameraPermission() {
String permission = Manifest.permission.CAMERA;
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, Constant.REQUEST_CAMERA_PERMISSION);
} else {
onPermissionGranted();
}
}
之后,我可以访问相机和图库。
希望对您有所帮助。
【讨论】:
对于 Android 10,SDK 30
在 manifest 的 application 标签中添加 android:requestLegacyExternalStorage="true"
https://stackoverflow.com/a/65415381/7775500
这可能会对你有所帮助..
【讨论】:
你肯定需要权限才能在安卓上打开相机。
像这样编辑清单:
<uses-permission android:name="android.permission.CAMERA" />
您可能还需要一个不包括在内的库
【讨论】:
我也有这个问题。我会分享给以后可能遇到这个问题的人。
您必须在 manifest 中拥有 相机权限,并在您的 WebChromeClient 中的 onPermissionRequest 方法中授予它,并确保将 setMediaPlaybackRequiresUserGesture 设置为 webView 设置中的strong>false。
添加此权限:
<uses-permission android:name="android.permission.CAMERA" />
在 webView 设置中添加这个:
binding.webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
并在 onPermissionRequest 方法中授予权限:
@Override
public void onPermissionRequest(final PermissionRequest request) {
final String[] requestedResources = request.getResources();
request.grant(requestedResources);
}
有关更多信息,请参阅此链接:
【讨论】: