首先说下这个坑是怎么来的,本来要在项目中集成一个第三方提供的功能,但是第三方没有SDK,只给了个H5的页面,只能用webview给套进去了,本来以为事情很简单,分分钟的事情,可是页面里面竟然有图片上传的功能,这也没啥,网上找了段代码加上就OK了,可是本人的手机就是掉不起来文件选择对话框,谷歌和百度一番之后,坑出现了,并且对我这个情况无解,那就是安卓版本4.4、4.4.1、4.4.2这几个版本不被支持,除非H5是自己写的,可以Cordova实现,挖坑的就是谷歌这货自己。谁看到了这个文章,并且有解决办法,可以回复我,本人感激不尽。最后,上点源码,调试过的,谁想用可以直接拿去(包含了cookie处理),但是记得判断安卓版本号,源码如下:
public class KengActivity extends BaseActivity implements View.OnClickListener {
private WebView webView;
private ImageView ivBack;
private String url;
public final static int FILECHOOSER_RESULTCODE = 1;
public final static int FILECHOOSER_RESULTCODE_FOR_ANDROID_5 = 2;
public ValueCallback<Uri> mUploadMessage;
public ValueCallback<Uri[]> mUploadMessageForAndroid5;
@Override
public void onCreateActivity() {
setContentView(R.layout.activity_lanjingling_pay);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
url = getIntent().getExtras().getString("url");
initView();
initData();
}
private void initView() {
webView = (WebView) findViewById(R.id.webView);
ivBack = (ImageView) findViewById(R.id.ivBack);
}
private void initData() {
WebSettings webViewSettings = webView.getSettings();
webViewSettings.setJavaScriptEnabled(true);
webViewSettings.setSupportZoom(false);
webViewSettings.setBuiltInZoomControls(false);
webViewSettings.setAppCacheEnabled(false);
webViewSettings.setLoadWithOverviewMode(true);
webView.canGoBack();
webView.setWebChromeClient(new MyWebChromeClient());
/**
* 设置webview支持https
*/
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
}
});
/**
* 给webview跳转的url添加cookie
*/
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
PersistentCookieStore myCookieStore = new PersistentCookieStore(context);
List<HttpCookie> cookies = myCookieStore.getCookies();
for (int i = 0; i < cookies.size(); i++) {
HttpCookie httpCookie = cookies.get(i);
if (httpCookie.getName().equals("PHPSESSID")) {
cookieManager.setCookie(url, httpCookie.getName() + "=" + httpCookie.getValue());
}
}
CookieSyncManager.getInstance().sync();
webView.loadUrl(url);
LoadingDialog.showProgressDialog(context);
}
private class MyWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100) {
LoadingDialog.closeProgressDialog();
}
super.onProgressChanged(view, newProgress);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
KengActivity.this.startActivityForResult(
Intent.createChooser(i, "File Chooser"),
FILECHOOSER_RESULTCODE);
}
public void openFileChooser(ValueCallback uploadMsg,
String acceptType) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
KengActivity.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
}
// For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType, String capture) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
KengActivity.this.startActivityForResult(
Intent.createChooser(i, "File Chooser"),
FILECHOOSER_RESULTCODE);
}
@Override
public boolean onShowFileChooser(WebView webView,
ValueCallback<Uri[]> filePathCallback,
FileChooserParams fileChooserParams) {
openFileChooserImplForAndroid5(filePathCallback);
return true;//重要,没有这个会报错
}
}
private void openFileChooserImplForAndroid5(ValueCallback<Uri[]> uploadMsg) {
mUploadMessageForAndroid5 = uploadMsg;
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
startActivityForResult(chooserIntent,
FILECHOOSER_RESULTCODE_FOR_ANDROID_5);
}
@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();
if (result == null) {
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
return;
}
Bitmap bm = null;
//外界的程序访问ContentProvider所提供数据 可以通过ContentResolver接口
ContentResolver resolver = getContentResolver();
try {
Uri originalUri = intent.getData(); // 获得图片的uri
bm = MediaStore.Images.Media.getBitmap(resolver, originalUri);
// 这里开始的第二部分,获取图片的路径:
String[] proj = {MediaStore.Images.Media.DATA};
// 好像是android多媒体数据库的封装接口,具体的看Android文档
Cursor cursor = managedQuery(originalUri, proj, null, null,null);
// 按我个人理解 这个是获得用户选择的图片的索引值
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
// 将光标移至开头 ,这个很重要,不小心很容易引起越界
cursor.moveToFirst();
// 最后根据索引值获取图片路径
String path = cursor.getString(column_index);
Uri uri = Uri.fromFile(new File(path));
mUploadMessage.onReceiveValue(uri);
} catch (IOException e) {
Log.e("TAG-->Error", e.toString());
}
} else if (requestCode == FILECHOOSER_RESULTCODE_FOR_ANDROID_5) {
if (null == mUploadMessageForAndroid5)
return;
Uri result = (intent == null || resultCode != RESULT_OK) ? null: intent.getData();
if (result != null) {
mUploadMessageForAndroid5.onReceiveValue(new Uri[]{result});
} else {
mUploadMessageForAndroid5.onReceiveValue(new Uri[]{});
}
mUploadMessageForAndroid5 = null;
}
}
}