在Android Webview中上传音频录制

时间:2015-01-03 13:45:09

标签: android audio webview upload recording

所以我正在尝试构建一个应用程序,它将从服务器加载一个页面,它将有一个上传录音的选项,我找到了一种方法如何在Android浏览器中使这个工作,但我无法得到它通过webview工作。所以,如果我在浏览器中加载此页面 http://www.francesco.iovine.name/w3c/mediacapture/
然后单击“使用录音机捕获音频”下的“浏览”按钮,它在“录音机”中打开,这是完美的,但如何在webview中以相同的方式工作?

这里有一些照片可以看到究竟发生了什么 https://www.dropbox.com/sh/a7bqk7b8of4wtbm/AAAOIHlS1fLQ---G9hTWglypa?dl=0
他们按顺序排列 Browser1 - 在浏览器中加载页面
Browser2 - 我使用录音机点击“捕获音频”下的“选择文件” Browser3 - 我录制并选择录音并点击完成
Browser4 - 我点击了上传并且有一个结果,它就像它应该上传一样

Webview1 - 在webview中加载页面
Webview2 - 我点击了使用录音机捕获音频下的选择文件,但我没有录音机,而是选择了不同的选项 Webview3 - 我选择了录音机并点击完成
Webview4 - 它没有通过浏览器识别文件。
Webview5 - 我点击了上传,它被识别为文件类型:application / octet-stream

这是我用于webview的代码。

感谢您的帮助,谢谢

package com.androidexample.webview;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.webkit.JsResult;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebSettings.PluginState;
import android.widget.Toast;

public class ShowWebView extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.show_web_view);
    WebView webView = (WebView) findViewById(R.id.webView1);

    initWebView(webView);
    webView.loadUrl("http://www.francesco.iovine.name/w3c/mediacapture/"); // TODO input your url

}

private final static Object methodInvoke(Object obj, String method, Class<?>[] parameterTypes, Object[] args) {
    try {
        Method m = obj.getClass().getMethod(method, new Class[] { boolean.class });
        m.invoke(obj, args);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

private void initWebView(WebView webView) {

    WebSettings settings = webView.getSettings();

    settings.setJavaScriptEnabled(true);
    settings.setAllowFileAccess(true);
    settings.setDomStorageEnabled(true);
    settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
    settings.setLoadWithOverviewMode(true);
    settings.setUseWideViewPort(true);
    settings.setSupportZoom(true);
    // settings.setPluginsEnabled(true);
    methodInvoke(settings, "setPluginsEnabled", new Class[] { boolean.class }, new Object[] { true });
    // settings.setPluginState(PluginState.ON);
    methodInvoke(settings, "setPluginState", new Class[] { PluginState.class }, new Object[] { PluginState.ON });
    // settings.setPluginsEnabled(true);
    methodInvoke(settings, "setPluginsEnabled", new Class[] { boolean.class }, new Object[] { true });
    // settings.setAllowUniversalAccessFromFileURLs(true);
    methodInvoke(settings, "setAllowUniversalAccessFromFileURLs", new Class[] { boolean.class }, new Object[] { true });
    // settings.setAllowFileAccessFromFileURLs(true);
    methodInvoke(settings, "setAllowFileAccessFromFileURLs", new Class[] { boolean.class }, new Object[] { true });

    webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
    webView.clearHistory();
    webView.clearFormData();
    webView.clearCache(true);

    webView.setWebChromeClient(new MyWebChromeClient());
    // webView.setDownloadListener(downloadListener);
}

UploadHandler mUploadHandler;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {

    if (requestCode == Controller.FILE_SELECTED) {
        // Chose a file from the file picker.
        if (mUploadHandler != null) {
            mUploadHandler.onResult(resultCode, intent);
        }
    }

    super.onActivityResult(requestCode, resultCode, intent);
}

class MyWebChromeClient extends WebChromeClient {
    public MyWebChromeClient() {

    }

    private String getTitleFromUrl(String url) {
        String title = url;
        try {
            URL urlObj = new URL(url);
            String host = urlObj.getHost();
            if (host != null && !host.isEmpty()) {
                return urlObj.getProtocol() + "://" + host;
            }
            if (url.startsWith("file:")) {
                String fileName = urlObj.getFile();
                if (fileName != null && !fileName.isEmpty()) {
                    return fileName;
                }
            }
        } catch (Exception e) {
            // ignore
        }

        return title;
    }

    @Override
    public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
        String newTitle = getTitleFromUrl(url);

        new AlertDialog.Builder(ShowWebView.this).setTitle(newTitle).setMessage(message).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                result.confirm();
            }
        }).setCancelable(false).create().show();
        return true;
        // return super.onJsAlert(view, url, message, result);
    }

    @Override
    public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {

        String newTitle = getTitleFromUrl(url);

        new AlertDialog.Builder(ShowWebView.this).setTitle(newTitle).setMessage(message).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                result.confirm();
            }
        }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                result.cancel();
            }
        }).setCancelable(false).create().show();
        return true;

        // return super.onJsConfirm(view, url, message, result);
    }

    // Android 2.x
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        openFileChooser(uploadMsg, "");
    }

    // Android 3.0
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        openFileChooser(uploadMsg, "", "filesystem");
    }

    // Android 4.1
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        mUploadHandler = new UploadHandler(new Controller());
        mUploadHandler.openFileChooser(uploadMsg, acceptType, capture);
    }
};

class Controller {
    final static int FILE_SELECTED = 4;

    Activity getActivity() {
        return ShowWebView.this;
    }
}

// copied from android-4.4.3_r1/src/com/android/browser/UploadHandler.java
//////////////////////////////////////////////////////////////////////

/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// package com.android.browser;
//
// import android.app.Activity;
// import android.content.ActivityNotFoundException;
// import android.content.Intent;
// import android.net.Uri;
// import android.os.Environment;
// import android.provider.MediaStore;
// import android.webkit.ValueCallback;
// import android.widget.Toast;
//
// import java.io.File;
// import java.util.Vector;
//
// /**
// * Handle the file upload callbacks from WebView here
// */
// public class UploadHandler {

class UploadHandler {
    /*
     * The Object used to inform the WebView of the file to upload.
     */
    private ValueCallback<Uri> mUploadMessage;
    private String mCameraFilePath;
    private boolean mHandled;
    private boolean mCaughtActivityNotFoundException;
    private Controller mController;
    public UploadHandler(Controller controller) {
        mController = controller;
    }
    String getFilePath() {
        return mCameraFilePath;
    }
    boolean handled() {
        return mHandled;
    }
    void onResult(int resultCode, Intent intent) {
        if (resultCode == Activity.RESULT_CANCELED && mCaughtActivityNotFoundException) {
            // Couldn't resolve an activity, we are going to try again so skip
            // this result.
            mCaughtActivityNotFoundException = false;
            return;
        }
        Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
                : intent.getData();
        // As we ask the camera to save the result of the user taking
        // a picture, the camera application does not return anything other
        // than RESULT_OK. So we need to check whether the file we expected
        // was written to disk in the in the case that we
        // did not get an intent returned but did get a RESULT_OK. If it was,
        // we assume that this result has came back from the camera.
        if (result == null && intent == null && resultCode == Activity.RESULT_OK) {
            File cameraFile = new File(mCameraFilePath);
            if (cameraFile.exists()) {
                result = Uri.fromFile(cameraFile);
                // Broadcast to the media scanner that we have a new photo
                // so it will be added into the gallery for the user.
                mController.getActivity().sendBroadcast(
                        new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
            }
        }
        mUploadMessage.onReceiveValue(result);
        mHandled = true;
        mCaughtActivityNotFoundException = false;
    }
    void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        final String imageMimeType = "image/*";
        final String videoMimeType = "video/*";
        final String audioMimeType = "audio/*";
        final String mediaSourceKey = "capture";
        final String mediaSourceValueCamera = "camera";
        final String mediaSourceValueFileSystem = "filesystem";
        final String mediaSourceValueCamcorder = "camcorder";
        final String mediaSourceValueMicrophone = "microphone";
        // According to the spec, media source can be 'filesystem' or 'camera' or 'camcorder'
        // or 'microphone' and the default value should be 'filesystem'.
        String mediaSource = mediaSourceValueFileSystem;
        if (mUploadMessage != null) {
            // Already a file picker operation in progress.
            return;
        }
        mUploadMessage = uploadMsg;
        // Parse the accept type.
        String params[] = acceptType.split(";");
        String mimeType = params[0];
        if (capture.length() > 0) {
            mediaSource = capture;
        }
        if (capture.equals(mediaSourceValueFileSystem)) {
            // To maintain backwards compatibility with the previous implementation
            // of the media capture API, if the value of the 'capture' attribute is
            // "filesystem", we should examine the accept-type for a MIME type that
            // may specify a different capture value.
            for (String p : params) {
                String[] keyValue = p.split("=");
                if (keyValue.length == 2) {
                    // Process key=value parameters.
                    if (mediaSourceKey.equals(keyValue[0])) {
                        mediaSource = keyValue[1];
                    }
                }
            }
        }
        //Ensure it is not still set from a previous upload.
        mCameraFilePath = null;
        if (mimeType.equals(imageMimeType)) {
            if (mediaSource.equals(mediaSourceValueCamera)) {
                // Specified 'image/*' and requested the camera, so go ahead and launch the
                // camera directly.
                startActivity(createCameraIntent());
                return;
            } else {
                // Specified just 'image/*', capture=filesystem, or an invalid capture parameter.
                // In all these cases we show a traditional picker filetered on accept type
                // so launch an intent for both the Camera and image/* OPENABLE.
                Intent chooser = createChooserIntent(createCameraIntent());
                chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(imageMimeType));
                startActivity(chooser);
                return;
            }
        } else if (mimeType.equals(videoMimeType)) {
            if (mediaSource.equals(mediaSourceValueCamcorder)) {
                // Specified 'video/*' and requested the camcorder, so go ahead and launch the
                // camcorder directly.
                startActivity(createCamcorderIntent());
                return;
            } else {
                // Specified just 'video/*', capture=filesystem or an invalid capture parameter.
                // In all these cases we show an intent for the traditional file picker, filtered
                // on accept type so launch an intent for both camcorder and video/* OPENABLE.
                Intent chooser = createChooserIntent(createCamcorderIntent());
                chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(videoMimeType));
                startActivity(chooser);
                return;
            }
        } else if (mimeType.equals(audioMimeType)) {
            if (mediaSource.equals(mediaSourceValueMicrophone)) {
                // Specified 'audio/*' and requested microphone, so go ahead and launch the sound
                // recorder.
                startActivity(createSoundRecorderIntent());
                return;
            } else {
                // Specified just 'audio/*',  capture=filesystem of an invalid capture parameter.
                // In all these cases so go ahead and launch an intent for both the sound
                // recorder and audio/* OPENABLE.
                Intent chooser = createChooserIntent(createSoundRecorderIntent());
                chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(audioMimeType));
                startActivity(chooser);
                return;
            }
        }
        // No special handling based on the accept type was necessary, so trigger the default
        // file upload chooser.
        startActivity(createDefaultOpenableIntent());
    }
    private void startActivity(Intent intent) {
        try {
            mController.getActivity().startActivityForResult(intent, Controller.FILE_SELECTED);
        } catch (ActivityNotFoundException e) {
            // No installed app was able to handle the intent that
            // we sent, so fallback to the default file upload control.
            try {
                mCaughtActivityNotFoundException = true;
                mController.getActivity().startActivityForResult(createDefaultOpenableIntent(),
                        Controller.FILE_SELECTED);
            } catch (ActivityNotFoundException e2) {
                // Nothing can return us a file, so file upload is effectively disabled.
                Toast.makeText(mController.getActivity(), R.string.uploads_disabled,
                        Toast.LENGTH_LONG).show();
            }
        }
    }
    private Intent createDefaultOpenableIntent() {
        // Create and return a chooser with the default OPENABLE
        // actions including the camera, camcorder and sound
        // recorder where available.
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("*/*");
        Intent chooser = createChooserIntent(createCameraIntent(), createCamcorderIntent(),
                createSoundRecorderIntent());
        chooser.putExtra(Intent.EXTRA_INTENT, i);
        return chooser;
    }
    private Intent createChooserIntent(Intent... intents) {
        Intent chooser = new Intent(Intent.ACTION_CHOOSER);
        chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents);
        chooser.putExtra(Intent.EXTRA_TITLE,
                mController.getActivity().getResources()
                        .getString(R.string.choose_upload));
        return chooser;
    }
    private Intent createOpenableIntent(String type) {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType(type);
        return i;
    }
    private Intent createCameraIntent() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File externalDataDir = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_DCIM);
        File cameraDataDir = new File(externalDataDir.getAbsolutePath() +
                File.separator + "browser-photos");
        cameraDataDir.mkdirs();
        mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator +
                System.currentTimeMillis() + ".jpg";
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCameraFilePath)));
        return cameraIntent;
    }
    private Intent createCamcorderIntent() {
        return new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    }
    private Intent createSoundRecorderIntent() {
        return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);

    }
}
}

1 个答案:

答案 0 :(得分:-1)

按下输入时获取popUp对话框...将这些代码添加到MainActivity.java:

UploadHandler mUploadHandler;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {

    if (requestCode == Controller.FILE_SELECTED) {
        // Chose a file from the file picker.
        if (mUploadHandler != null) {
            mUploadHandler.onResult(resultCode, intent);
        }
    }

    super.onActivityResult(requestCode, resultCode, intent);
}

class MyWebChromeClient extends WebChromeClient {
    public MyWebChromeClient() {

    }

    private String getTitleFromUrl(String url) {
        String title = url;
        try {
            URL urlObj = new URL(url);
            String host = urlObj.getHost();
            if (host != null && !host.isEmpty()) {
                return urlObj.getProtocol() + "://" + host;
            }
            if (url.startsWith("file:")) {
                String fileName = urlObj.getFile();
                if (fileName != null && !fileName.isEmpty()) {
                    return fileName;
                }
            }
        } catch (Exception e) {
            // ignore
        }

        return title;
    }

    @Override
    public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
        String newTitle = getTitleFromUrl(url);

        new AlertDialog.Builder(MainActivity.this).setTitle(newTitle).setMessage(message).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                result.confirm();
            }
        }).setCancelable(false).create().show();
        return true;
        // return super.onJsAlert(view, url, message, result);
    }

    @Override
    public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {

        String newTitle = getTitleFromUrl(url);

        new AlertDialog.Builder(MainActivity.this).setTitle(newTitle).setMessage(message).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                result.confirm();
            }
        }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                result.cancel();
            }
        }).setCancelable(false).create().show();
        return true;

        // return super.onJsConfirm(view, url, message, result);
    }

    // Android 2.x
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        openFileChooser(uploadMsg, "");
    }

    // Android 3.0
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        openFileChooser(uploadMsg, "", "filesystem");
    }

    // Android 4.1
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        mUploadHandler = new UploadHandler(new Controller());
        mUploadHandler.openFileChooser(uploadMsg, acceptType, capture);
    }
};

之后...创建一个名为UploadHandler的类来处理文件:

class UploadHandler {
private final static String IMAGE_MIME_TYPE = "image/*";
private final static String VIDEO_MIME_TYPE = "video/*";
private final static String AUDIO_MIME_TYPE = "audio/*";
private final static String FILE_PROVIDER_AUTHORITY = "com.android.browser-classic.file";
/*
 * The Object used to inform the WebView of the file to upload.
 */
private ValueCallback<Uri[]> mUploadMessage;
private boolean mHandled;
private Controller mController;
private FileChooserParams mParams;
private Uri mCapturedMedia;
public UploadHandler(Controller controller) {
    mController = controller;
}
boolean handled() {
    return mHandled;
}
void onResult(int resultCode, Intent intent) {
    Uri[] uris;
    // As the media capture is always supported, we can't use
    // FileChooserParams.parseResult().
    uris = parseResult(resultCode, intent);
    mUploadMessage.onReceiveValue(uris);
    mHandled = true;
}
void openFileChooser(ValueCallback<Uri[]> callback, FileChooserParams fileChooserParams) {
    if (mUploadMessage != null) {
        // Already a file picker operation in progress.
        return;
    }
    mUploadMessage = callback;
    mParams = fileChooserParams;
    Intent[] captureIntents = createCaptureIntent();
    assert(captureIntents != null && captureIntents.length > 0);
    Intent intent = null;
    // Go to the media capture directly if capture is specified, this is the
    // preferred way.
    if (fileChooserParams.isCaptureEnabled() && captureIntents.length == 1) {
        intent = captureIntents[0];
    } else {
        intent = new Intent(Intent.ACTION_CHOOSER);
        intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, captureIntents);
        intent.putExtra(Intent.EXTRA_INTENT, fileChooserParams.createIntent());
    }
    startActivity(intent);
}
private Uri[] parseResult(int resultCode, Intent intent) {
    if (resultCode == Activity.RESULT_CANCELED) {
        return null;
    }
    Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
            : intent.getData();
    // As we ask the camera to save the result of the user taking
    // a picture, the camera application does not return anything other
    // than RESULT_OK. So we need to check whether the file we expected
    // was written to disk in the in the case that we
    // did not get an intent returned but did get a RESULT_OK. If it was,
    // we assume that this result has came back from the camera.
    if (result == null && intent == null && resultCode == Activity.RESULT_OK
            && mCapturedMedia != null) {
        result = mCapturedMedia;
    }
    Uri[] uris = null;
    if (result != null) {
        uris = new Uri[1];
        uris[0] = result;
    }
    return uris;
}
private void startActivity(Intent intent) {
    try {
        mController.getActivity().startActivityForResult(intent, Controller.FILE_SELECTED);
    } catch (ActivityNotFoundException e) {
        // No installed app was able to handle the intent that
        // we sent, so file upload is effectively disabled.
        Toast.makeText(mController.getActivity(), R.string.uploads_disabled,
                Toast.LENGTH_LONG).show();
    }
}
private Intent[] createCaptureIntent() {
    String mimeType = "*/*";
    String[] acceptTypes = mParams.getAcceptTypes();
    if ( acceptTypes != null && acceptTypes.length > 0) {
        mimeType = acceptTypes[0];
    }
    Intent[] intents;
    if (mimeType.equals(IMAGE_MIME_TYPE)) {
        intents = new Intent[1];
        intents[0] = createCameraIntent(createTempFileContentUri(".jpg"));
    } else if (mimeType.equals(VIDEO_MIME_TYPE)) {
        intents = new Intent[1];
        intents[0] = createCamcorderIntent();
    } else if (mimeType.equals(AUDIO_MIME_TYPE)) {
        intents = new Intent[1];
        intents[0] = createSoundRecorderIntent();
    } else {
        intents = new Intent[3];
        intents[0] = createCameraIntent(createTempFileContentUri(".jpg"));
        intents[1] = createCamcorderIntent();
        intents[2] = createSoundRecorderIntent();
    }
    return intents;
}
private Uri createTempFileContentUri(String suffix) {
    try {
        File mediaPath = new File(mController.getActivity().getFilesDir(), "captured_media");
        if (!mediaPath.exists() && !mediaPath.mkdir()) {
            throw new RuntimeException("Folder cannot be created.");
        }
        File mediaFile = File.createTempFile(
                String.valueOf(System.currentTimeMillis()), suffix, mediaPath);
        return FileProvider.getUriForFile(mController.getActivity(),
                FILE_PROVIDER_AUTHORITY, mediaFile);
    } catch (java.io.IOException e) {
        throw new RuntimeException(e);
    }
}
private Intent createCameraIntent(Uri contentUri) {
    if (contentUri == null) throw new IllegalArgumentException();
    mCapturedMedia = contentUri;
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |
              Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedMedia);
    intent.setClipData(ClipData.newUri(mController.getActivity().getContentResolver(),
            FILE_PROVIDER_AUTHORITY, mCapturedMedia));
    return intent;
}
private Intent createCamcorderIntent() {
    return new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
}
private Intent createSoundRecorderIntent() {
    return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
}
}
在strings.xml中添加以下两个字符串:

<string name="uploads_disabled">File uploads are disabled.</string>
<string name="choose_upload">Choose file for upload</string>

如果您使用的是proguard,则可能需要在proguard-project.txt中选择以下选项:

-keepclassmembers class * extends android.webkit.WebChromeClient {
public void openFileChooser(...);
}

我在这里的讨论中找到了所有这些File Upload in WebView