美文网首页
Android WebView支持file标签

Android WebView支持file标签

作者: lhl_012 | 来源:发表于2019-01-11 11:04 被阅读11次

    1、权限动态申请

    2、UploadHandler.java

    import android.app.Activity;
    import android.content.ActivityNotFoundException;
    import android.content.ClipData;
    import android.content.Intent;
    import android.net.Uri;
    import android.provider.MediaStore;
    import android.support.v4.content.FileProvider;
    import android.webkit.WebChromeClient.FileChooserParams;
    import android.webkit.ValueCallback;
    import android.widget.Toast;
    
    import java.io.File;
    
    /**
     * Handle the file upload. This does not support selecting multiple files yet.
     */
    public 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 static String FILE_PROVIDER_AUTHORITY;
        private ValueCallback<Uri[]> mUploadMessage;
        private Activity mController;
        private FileChooserParams mParams;
        private Uri mCapturedMedia;
    
        public UploadHandler(Activity controller) {
            mController = controller;
            FILE_PROVIDER_AUTHORITY = mController.getPackageName() + ".provider";
        }
    
        public 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);
            mUploadMessage = null;
        }
    
        public 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;
            // 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.startActivityForResult(intent, 4);
            } catch (ActivityNotFoundException e) {
                // No installed app was able to handle the intent that
                // we sent, so file upload is effectively disabled.
                Toast.makeText(mController, "禁止上传",
                        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.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, 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.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);
        }
    }
    

    3、使用

    var uploadHandler : UploadHandler(this)?=null
    uploadHandler = UploadHandler(this);//this传入activity对象
    

    WebChromeClient重写onShowFileChooser

    webview.webChromeClient = object : WebChromeClient() {
        override fun onShowFileChooser(webView: WebView, uploadMsg: ValueCallback<Array<Uri>>, fileChooserParams: WebChromeClient.FileChooserParams): Boolean {
            if (null == uploadHandler) {
                uploadHandler = UploadHandler(this@WebViewActivity)
            }
            uploadHandler?.openFileChooser(uploadMsg, fileChooserParams)
            return true
        }
    }
    
    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
            super.onActivityResult(requestCode, resultCode, intent)
            if (null != uploadHandler) {
                uploadHandler?.onResult(resultCode, intent)
            }
        }
    

    相关文章

      网友评论

          本文标题:Android WebView支持file标签

          本文链接:https://www.haomeiwen.com/subject/aagtdqtx.html