一,Android调用JS接口
1,用到的HTML代码:
//assets/web_js.html
2,在Activity中调用HTML中方法:
在初始化WebView时加入webView.getSettings().setJavaScriptEnabled(true);
表示允许Android
与JS
交互。接下来在需要交互的地方调用JS
方法:
case R.id.btn_web_js:
//wvWeb.loadUrl("javascript:javaCallJavascript('"+params+"')");
wvWeb.loadUrl("javascript:javaCallJavascript('Android中的Java通过WebView调用了javaScript的有参构造方法')");
break;
case R.id.btn_web_js_01:
wvWeb.loadUrl("javascript:javaCallJavascriptNoParam()");
break;
注意:在调用传参的方法时,如果传入的参数没有提前定义,而是直接传入的话。加上单引号(‘’)。具体写法参考上面的
二,JS调用Android方法
1,用到的HTML代码:
Title
JS与Android(Java)的交互
2,在JS中调用Android中方法:
在初始化WebView时加入
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().addJavascriptInterface(new JavaScriptUtil(), "java_call_js");//其中“java_call_js”为双方约定好的标记
3,JavaScriptUtil
中写交互的方法
/*
* 作为addJavascriptInterface()方法的第二个参数,该类将被映射为JavaScript对象
*/
private final class JavaScriptUtil {
JavaScriptUtil() {
}
@JavascriptInterface
public void webMessage(String msg) {
Log.e("LHC", "msg:" + msg);
ToastUtil.show(msg);
}
}
注意:方法必须加入"@JavascriptInterface",不然js无法调用;方法传入的参数类型为基本类型,无法接受对象
三,JS调用Android方法,Android方法有调用JS方法
Title
JS与Android(Java)的交互
2,JavaScriptUtil
中写交互的方法
private final class JavaScriptUtil {
JavaScriptUtil() {
}
@JavascriptInterface
public void javaCallJsMethod() {
runOnUiThread(new Runnable() {
@Override
public void run() {
wvWeb.loadUrl("javascript:javaCallJavascriptNoParam()");
}
});
}
}
注意:JS调用的Android方法中在调用JS方法时,要写在主线程中,不然会报错
四,调用Android相机,相册
private ValueCallback mUploadMessage;
private ValueCallback mUploadCallbackAboveL;
private final static int PHOTO_REQUEST = 100;
private final static int VIDEO_REQUEST = 120;
private boolean videoFlag = false;
//自定义 WebChromeClient 辅助WebView处理图片上传操作【 文件上传标签】
public class MyChromeWebClient extends WebChromeClient {
// For Android 3.0-
public void openFileChooser(ValueCallback uploadMsg) {
Log.d(TAG, "openFileChoose(ValueCallback uploadMsg)");
mUploadMessage = uploadMsg;
if (videoFlag) {
recordVideo();
} else {
takePhoto();
}
}
// For Android 3.0+
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
Log.d(TAG, "openFileChoose( ValueCallback uploadMsg, String acceptType )");
mUploadMessage = uploadMsg;
if (videoFlag) {
recordVideo();
} else {
takePhoto();
}
}
//For Android 4.1
public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) {
Log.d(TAG, "openFileChoose(ValueCallback uploadMsg, String acceptType, String capture)");
mUploadMessage = uploadMsg;
if (videoFlag) {
recordVideo();
} else {
takePhoto();
}
}
// For Android 5.0+
public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) {
Log.d(TAG, "onShowFileChooser(ValueCallback uploadMsg, String acceptType, String capture)");
mUploadCallbackAboveL = filePathCallback;
if (videoFlag) {
recordVideo();
} else {
takePhoto();
}
return true;
}
}
/**
* 拍照
*/
private void takePhoto() {
File fileUri = new File(Environment.getExternalStorageDirectory().getPath() + "/" + SystemClock.currentThreadTimeMillis() + ".jpg");
imageUri = Uri.fromFile(fileUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
imageUri = FileProvider.getUriForFile(WebViewNewActivity.this, getPackageName() + ".fileprovider", fileUri);//通过FileProvider
// 创建一个content类型的Uri
}
PhotoUtils.takePicture(WebViewNewActivity.this, imageUri, PHOTO_REQUEST);
}
/**
* 录像
*/
private void recordVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
//限制时长
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);
//开启摄像机
startActivityForResult(intent, VIDEO_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PHOTO_REQUEST) {
if (null == mUploadMessage && null == mUploadCallbackAboveL) return;
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
if (mUploadCallbackAboveL != null) {
onActivityResultAboveL(requestCode, resultCode, data);
} else if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
} else if (requestCode == VIDEO_REQUEST) {
if (null == mUploadMessage && null == mUploadCallbackAboveL) return;
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
if (mUploadCallbackAboveL != null) {
if (resultCode == RESULT_OK) {
mUploadCallbackAboveL.onReceiveValue(new Uri[]{result});
mUploadCallbackAboveL = null;
} else {
mUploadCallbackAboveL.onReceiveValue(new Uri[]{});
mUploadCallbackAboveL = null;
}
} else if (mUploadMessage != null) {
if (resultCode == RESULT_OK) {
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
} else {
mUploadMessage.onReceiveValue(Uri.EMPTY);
mUploadMessage = null;
}
}
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {
if (requestCode != PHOTO_REQUEST || mUploadCallbackAboveL == null) {
return;
}
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
results = new Uri[]{imageUri};
} else {
String dataString = data.getDataString();
ClipData clipData = data.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)};
}
}
mUploadCallbackAboveL.onReceiveValue(results);
mUploadCallbackAboveL = null;
}
四,WebView中打开下载链接
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {//8.0以上
Uri url = request.getUrl();
String strUrl = url.toString();
if (!TextUtils.isEmpty(strUrl)) {
if (strUrl.endsWith(".pdf")) {//打开一个pdf文件的下载链接
// openBrowsable(strUrl);
downloadBySystem(strUrl, "inline", "application/pdf");
}else{
view.loadUrl(strUrl);
}
}
return true;
}
/**
* 直接用浏览器打开
* @param strUrl 文件下载路径
*/
private void openBrowsable(String strUrl) {
Uri uri = Uri.parse(strUrl);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
startActivity(intent);
}
/**
* 系统下载
* @param url 文件下载路径
* @param contentDisposition 描述
* @param mimeType 类型
*/
private void downloadBySystem(String url, String contentDisposition, String mimeType){
if (TextUtils.isEmpty(url)) return;
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));//指定下载地址
request.allowScanningByMediaScanner();//允许媒体扫描,根据下载的文件类型被加入相册,音乐等媒体库
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);//设置通知的显示类型,下载进行时和完成后进行通知
String[] split = url.split("/");
request.setTitle(split[split.length -1]);//设置通知栏的标题,默认使用文件名
request.setDescription("Description");//设置通知栏的描述
request.setAllowedOverMetered(false);//设置是否允许在计费流量下下载
request.setVisibleInDownloadsUi(false);//设置是否允许记录在下载管理界面可见
request.setAllowedOverRoaming(true);//设置是否允许在漫游时下载
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);//设置允许下载的网络类型
String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType);
Log.e("LHC", "fileName:"+ fileName);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);//
DownloadManager downloadManager = (DownloadManager) getSystemService(Activity.DOWNLOAD_SERVICE);
long downloadId = downloadManager.enqueue(request);
Log.e("LHC", "downloadId:"+ downloadId);
}
private class DownloadCompleteReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null){
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())){
long downloadID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
Log.e("LHC", "downloadID:"+downloadID);
DownloadManager downloadManager = (DownloadManager) getSystemService(Activity.DOWNLOAD_SERVICE);
String mimeTypeForDownloadedFile = downloadManager.getMimeTypeForDownloadedFile(downloadID);
Log.e("LHC", "mimeTypeForDownloadedFile:"+mimeTypeForDownloadedFile);
if (TextUtils.isEmpty(mimeTypeForDownloadedFile)){
mimeTypeForDownloadedFile = "*/*";
}
Uri uriForDownloadedFile = downloadManager.getUriForDownloadedFile(downloadID);
Log.e("LHC", "uriForDownloadedFile:"+uriForDownloadedFile);
if (uriForDownloadedFile != null){
Intent handlerIntent = new Intent(Intent.ACTION_VIEW);
handlerIntent.setDataAndType(uriForDownloadedFile, mimeTypeForDownloadedFile);
context.startActivity(handlerIntent);
}
}
}
}
}
protected void initData() {
downloadCompleteReceiver = new DownloadCompleteReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(downloadCompleteReceiver, intentFilter);
}
五,WebView中长按图片保存
webView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
final WebView.HitTestResult hitTestResult = webView.getHitTestResult();
// 如果是图片类型或者是带有图片链接的类型
if (hitTestResult.getType() == WebView.HitTestResult.IMAGE_TYPE ||
hitTestResult.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
// 弹出保存图片的对话框
AlertDialog.Builder builder = new AlertDialog.Builder(WebActivity.this);
builder.setTitle("提示");
builder.setMessage("保存图片到本地");
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
picUrl = hitTestResult.getExtra();//获取图片链接
//保存图片到相册
new Thread(new Runnable() {
@Override
public void run() {
new SaveImage().execute();
}
}).start();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
// 自动dismiss
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
AlertDialog dialog = builder.create();
dialog.show();
return true;
}
return false;//保持长按可以复制文字
}
});
/***
* 功能:用线程保存图片
*
* @author wangyp
*/
private class SaveImage extends AsyncTask {
@Override
protected String doInBackground(String... params) {
String result = "";
try {
String sdcard = Environment.getExternalStorageDirectory().toString();
File file = new File(sdcard + "/Download");
if (!file.exists()) {
file.mkdirs();
}
int idx = picUrl.lastIndexOf(".");
file = new File(sdcard + "/Download/" + new Date().getTime() + System.currentTimeMillis()+ ".png");
InputStream inputStream = null;
URL url = new URL(picUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(20000);
if (conn.getResponseCode() == 200) {
inputStream = conn.getInputStream();
}
byte[] buffer = new byte[4096];
int len = 0;
FileOutputStream outStream = new FileOutputStream(file);
while ((len = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
outStream.close();
result = "保存成功";
} catch (Exception e) {
result = "保存失败!";
}
return result;
}
@Override
protected void onPostExecute(String result) {
showToast(result);
}
}