从相机或画廊的WebView上传图片 [英] Upload an Image from camera or gallery in WebView

查看:295
本文介绍了从相机或画廊的WebView上传图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的WebView在此应用程序中打开一个页面,上传按钮。

WebView in this app opens a page with upload button.

下面是code座,允许打开一个对话框,从画廊或相机上传图片。

Below is the code block that allows to open a dialog box to upload image from gallery or camera.

在我的活动我有:

 private WebView wv;  

//make HTML upload button work in Webview   
 private ValueCallback<Uri> mUploadMessage;  
 private final static int FILECHOOSER_RESULTCODE=1;

 @Override  
 protected void onActivityResult(int requestCode, int resultCode, Intent intent) {  
  if(requestCode==FILECHOOSER_RESULTCODE)  
  {  
   if (null == mUploadMessage) return;  
            Uri result = intent == null || resultCode != RESULT_OK ? null  
                    : intent.getData();  
            mUploadMessage.onReceiveValue(result);  
            mUploadMessage = null;        
  }  
 }  

内的onCreate我有以下几点:

    wv.setWebChromeClient(new WebChromeClient()  {
        private Uri imageUri;   

        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType )  {      
             File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyApp");
            // Create the storage directory if it does not exist
            if (! imageStorageDir.exists()){
                imageStorageDir.mkdirs();                  
            }
            File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");  
            imageUri = Uri.fromFile(file); 

            final List<Intent> cameraIntents = new ArrayList<Intent>();
            final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            final PackageManager packageManager = getPackageManager();
            final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
            for(ResolveInfo res : listCam) {
                final String packageName = res.activityInfo.packageName;
                final Intent i = new Intent(captureIntent);
                i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
                i.setPackage(packageName);
                i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                cameraIntents.add(i);

            }


            mUploadMessage = uploadMsg; 
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);  
            i.addCategory(Intent.CATEGORY_OPENABLE);  
            i.setType("image/*"); 
            Intent chooserIntent = Intent.createChooser(i,"Image Chooser");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
            MainActivity.this.startActivityForResult(chooserIntent,  FILECHOOSER_RESULTCODE); 
        }

我能看到点击上传按钮选项的摄像头,图片库和文件浏览器。

I am able to see option for camera, image gallery and file explorer on clicking Upload button.

文件浏览器和库按预期工作。问题是,当我拍照用的相机,它是不是在选择文件选项,显示状态上传的没有选择的文件。

File explorer and Gallery is working as expected. The problem is that, when I take a picture using camera, it is not uploaded in the "choose file" option which shows status "No file chosen".

如何选择相机:

服用快照使用相机:回去检查选项出现

如何选择复选标记:

文件是没有上传:(在选择文件选项

的期望是什么:

我检查,我有正确的写作许可,因而命名为MyApp的生成目录和图片存储在它(如果采取通过点击网页上上传按钮后调用摄像头)。

I checked that I have the proper writing permission and hence a directory named "MyApp" is generated and the picture is stored within it (if taken by invoking camera after clicking upload button on webpage).

如何以编程告诉应用程序选择照片从相机拍摄(已存储在MyApp的目录)打对勾后?

How to programatically tell the application to choose picture taken from camera (that was stored in MyApp directory) after hitting check mark?

推荐答案

更新6/18:这似乎并没有工作,三星Galaxy S2采用Android 4.2.1。这工作得很好上的HTC One X + 4.1.2。要提醒。

Update 6/18: This doesn't seem to work on Samsung Galaxy S2 with Android 4.2.1. This worked fine on HTC One X+ with 4.1.2. Be cautioned.

我面临同样的问题。这里的问题以及如何解决它。

I faced the same problem. Here's the problem and how I solved it.

问题:

openFileChooser 被调用时,回调对象 ValueCallback&LT;乌里&GT; 被传递。这是实际的回拨到Web视图时,我们有一个文件已经准备好了。我们这个对象保存到 mUploadMessage 和使用 mUploadMessage.onReceiveValue()函数 onActivityResult 将文件恢复到web视图。当你选择摄像头,点击图片,将其保存并返回到web视图的活动,我们的活动可能得到回收,这意味着我们实际上失去了回调对象 mUploadMessage 。因此,该文件不能被传递回web视图上传

When openFileChooser is called, the call back object ValueCallback<Uri> is being passed. This is the actual call back to web view when we have a file ready for it. We save this object to mUploadMessage and use mUploadMessage.onReceiveValue() function in onActivityResult to return the file to Webview. While you choose camera, click a picture, save it and return to the webview activity, our activity might get recycled, which means we actually lose the call back object mUploadMessage. And hence, the file cannot be passed back to webview for upload.

修正:

修正涉及执行一些JavaScript,因此启用JavaScript的web视图。基本上,我们会得到另一个回调对象,如果我们丧失了previous之一。

Fix involves executing some javascript, so enable javascript on webview. Basically, we will get another call back object if we lost the previous one.

我们需要创建一个布尔字段 mUploadFileOnLoad 和三个领域。

We need to create a boolean field 'mUploadFileOnLoad' and three fields.

    private int mReturnCode;
    private int mResultCode;
    private Intent mResultIntent;
    private boolean mUploadFileOnLoad = false;

当我们回到我们从相机的活动, onActivityResult 将被调用。如果活动被重建,mUploadMessage为空。因此,我们将这些参数保存到字段,设置 mUploadFileOnLoad 来真实的回报。 else部分是非常重要的。

When we return to our activity from camera, onActivityResult will be called. If activity is reconstructed, mUploadMessage is null. So, we will save the parameters to fields and set mUploadFileOnLoad to true and return. The else part is very important.

    @Override
    protected void onActivityResult(int requestCode, 
                                    int resultCode,
                                    Intent intent) 
    {  
      //if the callback object has been recycled      
      if(null==mUploadMessage)
      {
        //Save the result
        mReturnCode = requestCode;
        mResultCode = resultCode;
        mResultIntent = intent;
        //remember to invoke file upload using Javascript
        mUploadFileOnLoad = true;
        return;
      }else
        mUploadFileOnLoad = false;
      //rest of the code
    }

该解决方案的重要部分是 WebViewClient WebChromeClient

    new WebChromeClient() {

        //Other overloaded functions

        //See http://stackoverflow.com/a/15423907/375093 for full explanation
        //The undocumented magic method override
        //Eclipse will swear at you if you try to put @Override here
        // For Android < 3.0
        public void openFileChooser(ValueCallback<Uri> uploadMsg) {
            //If we lost the callback object
            if(mUploadFileOnLoad)
            {
                mUploadMessage = uploadMsg;
                //use the saved result objects to invoke onActivityResult
                onActivityResult(mReturnCode, mResultCode, mResultIntent);
                return;
            }
         //Rest of the code....
         }

        new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            if(mUploadFileOnLoad)
            {
               webview.loadUrl("javascript:document.getElementById('my_file').click()");
            }
        }

在上面, my_file &LT的ID;输入&GT; 网​​页中的元素

In the above, my_file is the id of the <input> element in the web page.

<input type="file" id="my_file">

所以,综上所述,我们所做的事情是 - 当我们没有一个回调对象,我们挽救其他活动接收的数据集 mUploadFileOnLoad 来真实,等待页面加载。当页面加载时,我们使用JavaScript调用文件选择,所以我们得到一个回调对象。既然我们已经有了结果,我们调用 onActivityResult 和回报。现在onActivityResult已经从web视图回调。

So, in summary, what we did is - When we don't have a callback object, we save the data received from other activity and set mUploadFileOnLoad to true and wait for page to load. When page loads, we use Javascript to invoke the file chooser so we get a callback object. Since we already have results, we invoke onActivityResult and return. onActivityResult now has a callback from the webview.

这篇关于从相机或画廊的WebView上传图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆