安卓内核开发
其实是Android的webview默认是不支持<input type="file"/>文件上传的。现在的前端页面需要处理的是:
权限
文件路径AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
宿主返回代码
private ValueCallback<Uri> uploadMessage;
private ValueCallback<Uri[]> uploadMessageAboveL;
private final static int FILE_CHOOSER_RESULT_CODE = 10000;
// 2.回调方法触发本地选择文件
private void openImageChooserActivity() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
// i.setType("image/*");//图片上传
// i.setType("file/*");//文件上传
i.setType("*/*");//文件上传
startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
}
// 3.选择图片后处理
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_CHOOSER_RESULT_CODE) {
if (null == uploadMessage && null == uploadMessageAboveL) return;
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
// Uri result = (((data == null) || (resultCode != RESULT_OK)) ? null : data.getData());
if (uploadMessageAboveL != null) {
onActivityResultAboveL(requestCode, resultCode, data);
} else if (uploadMessage != null) {
uploadMessage.onReceiveValue(result);
uploadMessage = null;
}
} else {
//这里uploadMessage跟uploadMessageAboveL在不同系统版本下分别持有了
//WebView对象,在用户取消文件选择器的情况下,需给onReceiveValue传null返回值
//否则WebView在未收到返回值的情况下,无法进行任何操作,文件选择器会失效
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null);
uploadMessage = null;
} else if (uploadMessageAboveL != null) {
uploadMessageAboveL.onReceiveValue(null);
uploadMessageAboveL = null;
}
}
}
// 4. 选择内容回调到Html页面
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
return;
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (intent != null) {
String dataString = intent.getDataString();
ClipData clipData = intent.getClipData();
if (clipData != null) {
results = new Uri[clipData.getItemCount()];
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
results[i] = item.getUri();
}
}
if (dataString != null)
results = new Uri[]{Uri.parse(dataString)};
}
}
uploadMessageAboveL.onReceiveValue(results);
uploadMessageAboveL = null;
}
webview完整扩展
private class Cyber_ChromeClient extends WebChromeClient {
{
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
// mProgress.setProgress(newProgress);
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
// mTitle.setText(title);
}
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
}
@Override
public boolean onJsAlert(WebView view, String url, String message, final android.webkit.JsResult result) {
new AlertDialog.Builder(cyber_instance)
.setTitle("悠然智慧管理4.0")
.setMessage(message)
.setPositiveButton(android.R.string.ok,
new AlertDialog.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
result.confirm();
}
}).setCancelable(false).create().show();
return true;
}
//2020-5-15
/**
* 对网络连接状态进行判断
* @return true, 可用; false, 不可用
*/
private boolean isOpenNetwork() {
ConnectivityManager connManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connManager.getActiveNetworkInfo(); if(networkInfo!= null) {
//2.获取当前网络连接的类型信息
//
int networkType = networkInfo.getType();
if(ConnectivityManager.TYPE_WIFI == networkType){
//当前为wifi网络
}else if(ConnectivityManager.TYPE_MOBILE == networkType){
//当前为mobile网络
}
return connManager.getActiveNetworkInfo().isAvailable(); }
return false;
}
/**
* 覆盖默认的window.confirm展示界面,避免title里显示为“:来自file:”
*/
public boolean onJsConfirm(WebView view, String url, String message,
final JsResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
builder.setTitle("优然智慧管理系统")
.setMessage(message)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setNeutralButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
result.cancel();
}
});
// 屏蔽keycode等于84之类的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
//Log.v("onJsConfirm", "keyCode==" + keyCode + "event="+ event);
return true;
}
});
// 禁止响应按back键的事件
// builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
return true;
// return super.onJsConfirm(view, url, message, result);
}
/**
* 覆盖默认的window.prompt展示界面,避免title里显示为“:来自file:”
* window.prompt('请输入您的域名地址', '618119.com');
*/
public boolean onJsPrompt(WebView view, String url, String message,
String defaultValue, final JsPromptResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
builder.setTitle("优然智慧管理系统").setMessage(message);
final EditText et = new EditText(view.getContext());
et.setSingleLine();
et.setText(defaultValue);
builder.setView(et)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm(et.getText().toString());
}
})
.setNeutralButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
// 屏蔽keycode等于84之类的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
//Log.v("onJsPrompt", "keyCode==" + keyCode + "event="+ event);
if (keyCode == KeyEvent.KEYCODE_ENTER) {
result.confirm(et.getText().toString());
dialog.dismiss();
return true;
}else{
return false;
}
//
}
});
// 禁止响应按back键的事件
// builder.setCancelable(false);
final AlertDialog dialog = builder.create();
//2021-3-18 回车检测
et.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
// 监听到回车键,会执行2次该方法。按下与松开
result.confirm(et.getText().toString());
dialog.dismiss();
}
return false;
}
});
dialog.show();
return true;
// return super.onJsPrompt(view, url, message, defaultValue,
// result);
}
/2020-5-15
//20240604 文件
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> valueCallback) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
// For Android >= 3.0
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
// For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
uploadMessageAboveL = filePathCallback;
openImageChooserActivity();
return true;
}
}
}
调用浏览
//非常重要
cwpd_Web.setWebViewClient(new Cyber_WebviewClient());
cwpd_Web.setWebChromeClient(new Cyber_ChromeClient());