从相机或画廊的WebView上传图片 [英] Upload an Image from camera or gallery in 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屋!