Cordova Android点击输入类型=文件会弹出系统文件浏览器,而不是相机选项

kg7wmglp  于 2022-11-15  发布在  Android
关注(0)|答案(1)|浏览(162)

问题

在Cordova Android中,当点击html type=“file”输入时,会出现系统文件选择器,而不是相机选项。

预计会发生什么情况?

如果在系统浏览器中执行相同的操作,则会出现预期的对话框:

版本信息

"cordova-android": "^8.0.0",
"cordova-plugin-camera": "^4.1.0"

科多瓦-客户端9.0.0
完整test case repo here
这是我的第一个Android Cordova应用程序,我是否缺少某个插件?我不记得在任何阶段都被要求使用相机的权限,所以我想知道上面链接的config.xml中是否缺少了什么?

35g0bw71

35g0bw711#

您需要如下设置captureaccept属性:

<input type="file" capture="camera" accept="image/*" />

编辑

此外,请确定您的platforms/android/AndroidManifest.xml包含下列元素:

<application android:allowBackup="false" android:hardwareAccelerated="true" android:icon="@mipmap/icon" android:label="@string/app_name">
    <provider android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true" android:name="android.support.v4.content.FileProvider">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
    </provider>
    <provider android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true" android:name="org.apache.cordova.camera.FileProvider">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/camera_provider_paths" />
    </provider>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

如果它们不存在,请创建包含以下内容的文件platforms/android/res/xml/file_paths.xml

<!-- file_paths.xml -->
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="photos" path="photos/" />
</paths>

和文件platforms/android/res/xml/camera_provider_paths.xml

<!-- camera_provider_paths.xml -->
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

如果这样做似乎仍不奏效,您可能还需要添加/修改platforms/android/CordovaLib/src/org/apache/cordova/engine目录中的SystemWebChromeClient.java文件,以包括以下内容:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, final ValueCallback<Uri[]> filePathsCallback, final WebChromeClient.FileChooserParams fileChooserParams) {
    // Image from file intent
    boolean multiple = fileChooserParams.getMode() == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE;
    String type = "*/*";
    if (fileChooserParams.getAcceptTypes() != null && fileChooserParams.getAcceptTypes().length > 0) {
        type = fileChooserParams.getAcceptTypes()[0];
    }
    Intent fileIntent = new Intent(Intent.ACTION_GET_CONTENT);
    fileIntent.addCategory(Intent.CATEGORY_OPENABLE);
    fileIntent.setTypeAndNormalize(type);
    fileIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, multiple);

    // Image from camera intent
    Uri tempUri = null;
    Intent captureIntent = null;
    if (fileChooserParams.isCaptureEnabled()) {
        captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        Context context = parentEngine.getView().getContext();
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA) && captureIntent.resolveActivity(context.getPackageManager()) != null) {
            try {
                File tempFile = createTempFile(context);
                Log.d(LOG_TAG, "Temporary photo capture file: " + tempFile);
                tempUri = createUriForFile(context, tempFile);
                Log.d(LOG_TAG, "Temporary photo capture URI: " + tempUri);
                captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
            } catch (IOException e) {
                Log.e(LOG_TAG, "Unable to create temporary file for photo capture", e);
                captureIntent = null;
            }
        } else {
            Log.w(LOG_TAG, "Device does not support photo capture");
            captureIntent = null;
        }
    }
    final Uri captureUri = tempUri;

    // Chooser intent
    Intent chooserIntent = Intent.createChooser(fileIntent, null);
    if (captureIntent != null) {
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { captureIntent });
    }

    try {
        Log.i(LOG_TAG, "Starting intent for file chooser");
        parentEngine.cordova.startActivityForResult(new CordovaPlugin() {
            @Override
            public void onActivityResult(int requestCode, int resultCode, Intent intent) {
                // Handle result
                Uri[] result = null;
                if (resultCode == Activity.RESULT_OK) {
                    List<Uri> uris = new ArrayList<Uri>();
                    if (intent == null && captureUri != null) { // camera
                        Log.v(LOG_TAG, "Adding camera capture: " + captureUri);
                        uris.add(captureUri);

                    } else if (intent.getClipData() != null) { // multiple files
                        ClipData clipData = intent.getClipData();
                        int count = clipData.getItemCount();
                        for (int i = 0; i < count; i++) {
                            Uri uri = clipData.getItemAt(i).getUri();
                            Log.v(LOG_TAG, "Adding file (multiple): " + uri);
                            if (uri != null) {
                                uris.add(uri);
                            }
                        }

                    } else if (intent.getData() != null) { // single file
                        Log.v(LOG_TAG, "Adding file (single): " + intent.getData());
                        uris.add(intent.getData());
                    }

                    if (!uris.isEmpty()) {
                        Log.d(LOG_TAG, "Receive file chooser URL: " + uris.toString());
                        result = uris.toArray(new Uri[uris.size()]);
                    }
                }
                filePathsCallback.onReceiveValue(result);
            }
        }, chooserIntent, FILECHOOSER_RESULTCODE);
    } catch (ActivityNotFoundException e) {
        Log.w("No activity found to handle file chooser intent.", e);
        filePathsCallback.onReceiveValue(null);
    }
    return true;
}

相关问题