我的应用是基于网络的,我需要从INPUT野外营地上传图片。我有两种情况,因为我不知道另一种方法,根据页面我选择一个或另一个“boolean boolFileChoser”取决于其URL请求:
一个。文件选择器
湾相机拍照。
我已经处理过文件选择器并且它完美地上传文件,问题在于相机。一旦我尝试上传相机图片,它就会崩溃。
据我所知,因为URI。
a)文件选择器:content:// media / external / images / 1234
b)相机拍摄:file:///mnt/sdcard/Pic.jpg
我发现没有办法改变它。
请参阅更新
它现在崩溃,因为尝试上传“content:// media / external / images / 1234”时出现nullpointerexception。 (仅限相机,不是文件选择器。)。
此外,如果选择器/摄像机关闭(后退按钮),我将无法再次呼叫它。
击>
案例a)和b)100%工作,这是工作代码,包括我如何知道fileChooser或相机是否被调用:
@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);'如果Camera / filechooser意图被取消(您必须在网页中处理),如果没有,您将无法再次启动INPUT字段(Intent)。
更新3
在AwesomeChromeClient中添加了部分代码,以区分选项,拍照或选择文件..我的方式,并通过请愿添加,我敢肯定还有很多其他有效的方法做到了,
现在代码100%正常运行。如果您指明是否需要图片或文件选择器
答案 0 :(得分:7)
这是我从WebView输入字段实现相机上传和文件追踪器的方式:
以下是此重要主题的代码。删除了不相关的代码。
public class MainActivity extends Activity {
private WebView webView;
private String urlStart = "http://www.example.com/mobile/";
//File choser parameters
private static final int FILECHOOSER_RESULTCODE = 2888;
private ValueCallback<Uri> mUploadMessage;
//Camera parameters
private Uri mCapturedImageURI = null;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setAllowFileAccess(true);
webView.loadUrl(urlStart);
webView.setWebChromeClient(new WebChromeClient() {
// openFileChooser for Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
try{
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File externalDataDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM);
File cameraDataDir = new File(externalDataDir.getAbsolutePath() +
File.separator + "browser-photos");
cameraDataDir.mkdirs();
String mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator +
System.currentTimeMillis() + ".jpg";
mCapturedImageURI = Uri.fromFile(new File(mCameraFilePath));
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
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, new Parcelable[] { cameraIntent });
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
}
catch(Exception e){
Toast.makeText(getBaseContext(), "Camera Exception:"+e, Toast.LENGTH_LONG).show();
}
}
// For Android < 3.0
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg ) {
openFileChooser(uploadMsg, "");
}
// For Android > 4.1.1
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
openFileChooser(uploadMsg, acceptType);
}
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", "www.example.com: " + message);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
// TODO Auto-generated method stub
if(requestCode==FILECHOOSER_RESULTCODE)
{
if (null == this.mUploadMessage) {
return;
}
Uri result=null;
try{
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = intent == null ? mCapturedImageURI : intent.getData();
}
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(), "activity :"+e, Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
我希望它会对某人有所帮助:)。
答案 1 :(得分:2)
解决。在我的问题中,有功能代码以防任何人需要它。
以下是问题的解决方案:
如果我之前打开并取消了,则无法打开相机/文件追踪器:
//inside onActivityResult
if (resultCode != RESULT_OK) {
mUploadMessage.onReceiveValue(null);
return;
}
获取“content:// media / external / images / xxx”uri格式,通过“mUploadMessage.onReceiveValue(selectedImage);”上传uri,避免nullpointerexception
//inside OnActivityResult
getContentResolver().notifyChange(mCapturedImageURI, null);
ContentResolver cr = getContentResolver();
Uri uriContent = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), photo.getAbsolutePath(), null, null));
答案 2 :(得分:1)
已解决并且工作正常。
只需查看WebChromeClient类的代码即可。 您会发现参数已从之前更改。
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
throw new RuntimeException("Stub!");
}
解决方案:
您只需按照此github链接中的最新ChromeBrowser代码即可 Android Chrome browser code on Github
为您的项目使用相同的github代码。
注意:android 4.4 KitKat版本仍然存在问题。除了android 4.4之外,它适用于其他Android版本。
因为Google仍然存在缺陷。请查看以下链接。
openFileChooser not called when is clicked on android 4.4 webview