我的应用是基于Web的,我需要从一个INPUT字段中上传图片。 我有两种情况,由于我不知道其他方法,因此根据页面选择"boolean boolFileChoser"之一取决于其URL请求:
a. 文件选择器
b. 相机拍摄照片。
我已经处理了文件选择器并且它可以完美地上传文件,问题在于相机。当我尝试上传相机照片时,它崩溃了。
据我所知,这是由于URI造成的。
a)文件选择器:content://media/external/images/1234
b)相机拍摄:file:///mnt/sdcard/Pic.jpg
我找不到改变它的方法。
请参见更新
现在它会因为尝试上传“content://media/external/images/1234”而导致nullpointerexception而崩溃。 (只有相机,并非文件选择器。) 此外,如果选择器/相机关闭(返回按钮),我将无法再次调用它。
情况a)和b)100%工作正常,以下是有效的代码,包括如何知道是否调用了fileChooser或camera:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode != RESULT_OK) {
/** fixed code **/
//To be able to use the filechooser again in case of error
mUploadMessage.onReceiveValue(null);
/** fixed code **/
return;
}
if (mUploadMessage==null) {
Log.d("androidruntime","no mUploadMessage");
return;
}
if (requestCode == FILECHOOSER_RESULTCODE) {
Uri selectedImage= intent == null || resultCode != RESULT_OK ? null : intent.getData();
Log.d("androidruntime","url: "+selectedImage.toString());
}else if (requestCode == CAMERAREQUEST_RESULTCODE) {
if(mCapturedImageURI==null){
Log.d("androidruntime","no mCapturedImageURI");
return;
}
/** fixed code **/
getContentResolver().notifyChange(mCapturedImageURI, null);
ContentResolver cr = getContentResolver();
Uri uriContent= Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), photo.getAbsolutePath(), null, null));
photo = null;
/** fixed code **/
}
mUploadMessage.onReceiveValue(selectedImage);
mUploadMessage = null;
}
private static final int FILECHOOSER_RESULTCODE = 2888;
private static final int CAMERAREQUEST_RESULTCODE = 1888;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
protected class AwesomeWebChromeClient extends WebChromeClient{
// Per Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType){
/**updated, out of the IF **/
mUploadMessage = uploadMsg;
/**updated, out of the IF **/
if(boolFileChooser){ //Take picture from filechooser
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
MainActivity.this.startActivityForResult( Intent.createChooser( i, "Escoger Archivo" ), MainActivity.FILECHOOSER_RESULTCODE );
} else { //Take photo and upload picture
Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
File photo = new File(Environment.getExternalStorageDirectory(), "Pic.jpg");
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
mCapturedImageURI = Uri.fromFile(photo);
startActivityForResult(cameraIntent, MainActivity.CAMERA_REQUEST);
}
}
// Per Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg){
openFileChooser(uploadMsg, "");
}
//Altre
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, "");
}
/** Added code to clarify chooser. **/
//The webPage has 2 filechoosers and will send a console message informing what action to perform, taking a photo or updating the file
public boolean onConsoleMessage(ConsoleMessage cm) {
onConsoleMessage(cm.message(), cm.lineNumber(), cm.sourceId());
return true;
}
public void onConsoleMessage(String message, int lineNumber, String sourceID) {
Log.d("androidruntime", "Per cònsola: " + cm.message());
if(message.endsWith("foto")){ boolFileChooser= true; }
else if(message.endsWith("pujada")){ boolFileChooser= false; }
}
/** Added code to clarify chooser. **/
}
更新1
我已经获取了 "content://media/external/images/xxx" 的uri格式,但是在尝试通过 "mUploadMessage.onReceiveValue(selectedImage);" 上传uri时,应用程序仍然崩溃。现在我得到了一个nullpointerexception。
更新2
已修复并正常工作。
我只在文件选择器情况下将 'ValueCallback uploadMsg' 设置为本地变量,因此当我尝试上传照片文件时,它总是抛出异常,因为它为空。一旦我从if-else语句中取出它,所有操作都正常工作。 先前的更新是处理文件上传的最简单方法。
如果取消相机/文件选择器意图(您必须在您的网页中处理它),我已经添加了 'mUploadMessage.onReceiveValue(null);',否则,您将无法再次启动INPUT字段(Intent)。
更新3
已添加代码部分至AwesomeChromeClient以区分选项,拍照或选择文件...这是我的方法,并按要求添加,我确信还有许多其他有效的方法可以实现,
代码现在100%功能正常。如果指示您想要图片或文件选择器,则可以执行此操作。