私は webview を使用して web アプリケーションを実行しています。アプリでは、ユーザーがサーバーに画像をアップロードできるようにしています。Android > 3 ではすべて正常に動作しています。Android 2.3.3 ブラウザでも期待どおりに動作していますが、 webview にファイルが入力されておらず、サーバーが空のオブジェクトを取得しています。カメラから写真を撮っているときにのみ発生しています(つまり、通常のギャラリーは正常に機能しています)。file:/// の Uri と content:/// の Uri が異なることに気付きました
私のコードが添付されています: HTML (私の簡単なテストページ):
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form id="fuForm" name="fuForm" action="/questions/upload" method="POST" enctype="multipart/form-data">
<label for="fileToUpload">Select a File to Upload</label><br />
<input type="file" name="fileToUpload" id="fileToUpload"/>
<input type="submit"/>
</form>
</body>
</html>
MainActivity コード:
webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setSavePassword(false);
webView.getSettings().setSaveFormData(false);
webView.setWebViewClient(new MyWebViewClient());
webView.setWebChromeClient(new MyWebChromeViewClient());
webView.loadUrl(url);
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
private class MyWebChromeViewClient extends WebChromeClient {
//@Override
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 intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
cameraIntents.add(intent);
}
uploadMessage = uploadMsg;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
Intent chooserIntent = Intent.createChooser(intent,"Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
activity.startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
}
// For Android < 3.0
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
// super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == RESULT_OK && requestCode == FILECHOOSER_RESULTCODE) {
if (null == uploadMessage)
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 result;
if (isCamera) {
result = imageUri;
} else {
result = intent == null ? null : intent.getData();
}
uploadMessage.onReceiveValue(result);
} else {
uploadMessage.onReceiveValue(null);
}
uploadMessage = null;
}
どんな助けでも大歓迎です...
ジョー。