【问题标题】:Cancel a file upload in a Webview在 Webview 中取消文件上传
【发布时间】:2015-11-21 00:31:06
【问题描述】:

我为 web 视图中的文件上传器实现了 this solution。 当我单击 HTML 中的“选择文件”按钮时,它第一次启动“选择源”选项(如相机、画廊、文档等),一切正常。如果我再做一次(做得好之后),它可以正常工作。但是如果我取消这个操作,按下Android的后退按钮,我无法再次上传文件,直到我重新启动应用程序。 这是用许多 html 文件上传器表单测试的,我总是遇到同样的问题。

这是我的实现:

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

    if (resultCode == RESULT_OK) {

        // This is for Android 4.4.4- (JellyBean & KitKat)
        if (requestCode == FILECHOOSER_RESULTCODE) {

            if (null == mUploadMessage) {
                super.onActivityResult(requestCode, resultCode, intent);
                return;
            }

            final boolean isCamera;

            if (intent == null) {
                isCamera = true;
            } else {
                final String action = intent.getAction();
                if (action == null) {
                    isCamera = false;
                } else {
                    isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                }
            }

            Uri selectedImageUri;

            if (isCamera) {

                selectedImageUri = mOutputFileUri;
                mUploadMessage.onReceiveValue(selectedImageUri);
                mUploadMessage = null;

                return;

            } else {

                try {

                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), intent.getData());
                    selectedImageUri = intent == null ? null : ImageUtility.savePicture(this, bitmap, 1400);

                    mUploadMessage.onReceiveValue(selectedImageUri);
                    mUploadMessage = null;

                    return;

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            // And this is for Android 5.0+ (Lollipop)
        } else if (requestCode == INPUT_FILE_REQUEST_CODE) {

            Uri[] results = null;

            // Check that the response is a good one
            if (resultCode == Activity.RESULT_OK) {
                if (intent == null) {
                    // If there is not data, then we may have taken a photo
                    if (mCameraPhotoPath != null) {
                        results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                    }
                } else {

                    Bitmap bitmap = null;

                    try {
                        bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), intent.getData());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    Uri dataUri = ImageUtility.savePicture(this, bitmap, 1400);

                    if (dataUri != null) {
                        results = new Uri[]{dataUri};
                    }
                }
            }

            mFilePathCallback.onReceiveValue(results);
            mFilePathCallback = null;

            return;
        }
    } else {

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

private class MyWebChromeClient extends WebChromeClient {


    /**
     * This is the method used by Android 5.0+ to upload files towards a web form in a Webview
     *
     * @param webView
     * @param filePathCallback
     * @param fileChooserParams
     * @return
     */
    @Override
    public boolean onShowFileChooser(
            WebView webView, ValueCallback<Uri[]> filePathCallback,
            WebChromeClient.FileChooserParams fileChooserParams) {

        if (mFilePathCallback != null) {
            mFilePathCallback.onReceiveValue(null);
        }
        mFilePathCallback = filePathCallback;

        Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
        contentSelectionIntent.setType("image/*");

        Intent[] intentArray = getCameraIntent();

        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "Seleccionar Fuente");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

        startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);

        return true;
    }

    @Override
    public void onProgressChanged(WebView view, int newProgress) {

        mProgressBar.setVisibility(View.VISIBLE);
        WebActivity.this.setValue(newProgress);
        super.onProgressChanged(view, newProgress);
    }

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

        Log.d("LogTag", message);
        result.confirm();
        return true;
    }

    /**
     * Despite that there is not a Override annotation, this method overrides the open file
     * chooser function present in Android 3.0+
     *
     * @param uploadMsg
     * @author Tito_Leiva
     */
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {

        mUploadMessage = uploadMsg;
        Intent i = getChooserIntent(getCameraIntent(), getGalleryIntent("image/*"));
        i.addCategory(Intent.CATEGORY_OPENABLE);
        WebActivity.this.startActivityForResult(Intent.createChooser(i, "Selecciona la imagen"), FILECHOOSER_RESULTCODE);

    }

    public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
        mUploadMessage = uploadMsg;
        Intent i = getChooserIntent(getCameraIntent(), getGalleryIntent("*/*"));
        i.addCategory(Intent.CATEGORY_OPENABLE);
        WebActivity.this.startActivityForResult(
                Intent.createChooser(i, "Selecciona la imagen"),
                FILECHOOSER_RESULTCODE);
    }

    /**
     * Despite that there is not a Override annotation, this method overrides the open file
     * chooser function present in Android 4.1+
     *
     * @param uploadMsg
     * @author Tito_Leiva
     */
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        mUploadMessage = uploadMsg;
        Intent i = getChooserIntent(getCameraIntent(), getGalleryIntent("image/*"));
        WebActivity.this.startActivityForResult(Intent.createChooser(i, "Selecciona la imagen"), FILECHOOSER_RESULTCODE);

    }

    private Intent[] getCameraIntent() {

        // Determine Uri of camera image to save.
        Intent takePictureIntent = new Intent(WebActivity.this, CameraActivity.class);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
                takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
            } catch (IOException ex) {
                // Error occurred while creating the File
                Log.e(TAG, "Unable to create Image File", ex);
            }

            // 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[] intentArray;
        if (takePictureIntent != null) {
            intentArray = new Intent[]{takePictureIntent};
        } else {
            intentArray = new Intent[0];
        }

        return intentArray;

    }

    private Intent getGalleryIntent(String type) {

        // Filesystem.
        final Intent galleryIntent = new Intent();
        galleryIntent.setType(type);
        galleryIntent.addCategory(Intent.CATEGORY_OPENABLE);
        galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

        return galleryIntent;
    }

    private Intent getChooserIntent(Intent[] cameraIntents, Intent galleryIntent) {

        // Chooser of filesystem options.
        final Intent chooserIntent = Intent.createChooser(galleryIntent, "Seleccionar Fuente");

        // Add the camera options.
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents);

        return chooserIntent;
    }
}

private class MyWebViewClient extends WebViewClient {

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        mUrl = url;
        Log.i("URL", mUrl);
        super.onPageStarted(view, url, favicon);
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {

        mUrl = url;
        view.loadUrl(mUrl);
        return true;

    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);

        mProgressBar.setVisibility(View.GONE);
    }
}

【问题讨论】:

    标签: android file-upload webview


    【解决方案1】:

    我找到了解决方案。在onActivityResult() 方法中,当resultCode 不是RESULT_OK 时,必须给uri 回调一个空对象

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent intent) {
    
        if (resultCode == RESULT_OK) {
    
            // This is for Android 4.4.4- (JellyBean & KitKat)
            if (requestCode == FILECHOOSER_RESULTCODE) {
    
                if (null == mUploadMessage) {
                    super.onActivityResult(requestCode, resultCode, intent);
                    return;
                }
    
                final boolean isCamera;
    
                if (intent == null) {
                    isCamera = true;
                } else {
                    final String action = intent.getAction();
                    if (action == null) {
                        isCamera = false;
                    } else {
                        isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    }
                }
    
                Uri selectedImageUri;
    
                if (isCamera) {
    
                    selectedImageUri = mOutputFileUri;
                    mUploadMessage.onReceiveValue(selectedImageUri);
                    mUploadMessage = null;
    
                    return;
    
                } else {
    
                    try {
    
                        Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), intent.getData());
                        selectedImageUri = intent == null ? null : ImageUtility.savePicture(this, bitmap, 1400);
    
                        mUploadMessage.onReceiveValue(selectedImageUri);
                        mUploadMessage = null;
    
                        return;
    
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                // And this is for Android 5.0+ (Lollipop)
            } else if (requestCode == INPUT_FILE_REQUEST_CODE) {
    
                Uri[] results = null;
    
                // Check that the response is a good one
                if (resultCode == Activity.RESULT_OK) {
                    if (intent == null) {
                        // If there is not data, then we may have taken a photo
                        if (mCameraPhotoPath != null) {
                            results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                        }
                    } else {
    
                        Bitmap bitmap = null;
    
                        try {
                            bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), intent.getData());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
    
                        Uri dataUri = ImageUtility.savePicture(this, bitmap, 1400);
    
                        if (dataUri != null) {
                            results = new Uri[]{dataUri};
                        }
                    }
                }
    
                mFilePathCallback.onReceiveValue(results);
                mFilePathCallback = null;
    
                return;
            }
        } else {
    
            //for Android 5.0+
            if (mFilePathCallback != null) {
                mFilePathCallback.onReceiveValue(null);
                mFilePathCallback = null;
    
            }
    
            //for Android 4.4.4-
            if (mUploadMessage != null) {
                mUploadMessage.onReceiveValue(null);
                mUploadMessage = null;
    
            }
    
            return;
        }
    } 
    

    【讨论】:

      【解决方案2】:

      这是问题的解决方案:

      如果取消文件选择器操作,onActivityResult() 返回 null。那是 resultCode 不等于 RESULT_OK

      将此代码放入您的 onActivityResult()。

       //inside onActivityResult
          if (resultCode != RESULT_OK)
           {
               mUploadMessage.onReceiveValue(null);
               return;
           }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-19
        • 2012-07-28
        • 2016-04-27
        • 2012-05-22
        • 1970-01-01
        • 2014-05-08
        相关资源
        最近更新 更多