因为这个app地嵌入h5做导航,所以需要调用android的交互进行获取定位信息和其他一些功能,做的效果是H5调Android打电话以及调用android手机相册选择图片,现在总结下:
一.打电话以及定位:
1.定义h5调用的名称:
webView.addJavascriptInterface(new RailwayJavascriptInterface(), "xxx");
2.定义对象,h5调用xxx.对象里的方法即可,比如xxx.getGPS():
private class RailwayJavascriptInterface {
@JavascriptInterface
public String getGPS() {
//h5获取当前位置
LocationInfo info = LocationUtil.getIntance(BrowserActivity.this).getLocationInfo();
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("lng", info.getLongitude() * Math.pow(10, 6));
jsonObject.put("lat", info.getLatitude() * Math.pow(10, 6));
} catch (JSONException e) {
e.printStackTrace();
}
return jsonObject.toString();
}
@JavascriptInterface
public void goBack() {
//销毁当前activity
finish();
}
@JavascriptInterface
public void callTaxPhone(String tel) {
//拨打司机电话
Log.d("lwp","tel:"+tel);
if (tel == null || tel.length() == 0) {
ToastUtil.toastShort(BrowserActivity.this, "电话号码为空!");
} else {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL);
// intent.setAction(Intent.ACTION_CALL_BUTTON);
intent.setData(Uri.parse("tel:" + tel));
startActivity(intent);
}
}
}
···
解决sdk小于19的漏洞问题:
if (android.os.Build.VERSION.SDK_INT < 19) {
webView.removeJavascriptInterface("searchBoxJavaBridge_");
webView.removeJavascriptInterface("accessibility");
webView.removeJavascriptInterface("accessibilityTraversal");
webView.removeJavascriptInterface("xxx");
}
二.选择相册或者拍照显示在h5的图片框上:
1.定义webchromeclient:
private WebChromeClient webChromeClient = new WebChromeClient() {
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
uploadMessage = valueCallback;
//调用系统相机或者相册
showDialog();
}
//For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
FileChooserParams fileChooserParams) {
uploadMessageAboveL = filePathCallback;
showDialog();
return true;
}
//获取网页标题
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
Log.i("ansen", "网页标题:" + title);
}
};
2.设置WebChromeClient:
webView.setWebChromeClient(webChromeClient);
3.显示拍照还是选择图库:
private void showDialog() {
View view = LayoutInflater.from(this).inflate(R.layout.item_photo_menu, null);
mBottomDialog = new Dialog(this, R.style.BottomDialog);
//初始化
initDialog(view);
mBottomDialog.setContentView(view);
mBottomDialog.setCanceledOnTouchOutside(false);
Window dialogWindow = mBottomDialog.getWindow();
dialogWindow.setGravity(Gravity.BOTTOM);
WindowManager.LayoutParams lp = dialogWindow.getAttributes(); // 获取对话框当前的参数值
lp.width = getResources().getDisplayMetrics().widthPixels; // 宽度;
view.measure(0, 0);
lp.height = view.getMeasuredHeight();
lp.alpha = 9f; // 透明度
dialogWindow.setAttributes(lp);
mBottomDialog.show();
}
···
//拍照
private void takePhoto() {
StringBuilder fileName = new StringBuilder();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileName.append(UUID.randomUUID()).append("_upload.png");
File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File tempFile = new File(path, fileName.toString());
if (!path.exists()) {
path.mkdirs();
}
// LogUtils.e("tempFile=" + tempFile);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//解决android 7.0拍照闪退
ContentValues contentValues = new ContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, tempFile.getAbsolutePath());
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
} else {
Uri uri = Uri.fromFile(tempFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
mCurrentPhotoPath = tempFile.getAbsolutePath();
startActivityForResult(intent, 100);
}
···
//图片比例压缩
private Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
// 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 400f;// 这里设置高度为800f
float ww = 240f;// 这里设置宽度为480f
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;// be=1表示不缩放
if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be;// 设置缩放比例
// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
}
//图片质量压缩
private Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
while (baos.toByteArray().length / 1024 > 1000) { // 循环判断如果压缩后图片是否大于1000kb,大于继续压缩
baos.reset();// 重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
return bitmap;
}
//选择图片或者拍照完成的回调,最后调用value传给h5
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 || requestCode == 200) {
//取消拍照或者图片选择时,返回null,否则<input file> 就是没有反应
if (resultCode != RESULT_OK) {
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null);
}
if (uploadMessageAboveL != null) {
uploadMessageAboveL.onReceiveValue(null);
}
return;
}
//拍照成功和选取照片时
if (resultCode == RESULT_OK) {
Uri imageUri = null;
switch (requestCode) {
case 200:
if (data != null) {
//进行图片的压缩
String path = getAbsoluteImagePath(data.getData());
Log.d("lwp","path:"+path);
Bitmap bitmap = getimage(path);
//转成url
imageUri = Uri.parse(MediaStore.Images.Media.insertImage(
getContentResolver(), bitmap, null, null));
//
// imageUri = data == null || resultCode != RESULT_OK ? null
// : data.getData();
}
break;
case 100:
//相机
if (!TextUtils.isEmpty(mCurrentPhotoPath)) {
// File file = new File(mCurrentPhotoPath);
// imageUri = Uri.fromFile(file);
//进行图片的压缩
Bitmap bitmap1 = getimage(mCurrentPhotoPath);
Log.d("lwp","mCurrentPhotoPath:"+mCurrentPhotoPath);
//转成url
imageUri = Uri.parse(MediaStore.Images.Media.insertImage(
getContentResolver(), bitmap1, null, null));
}
break;
}
Log.e("imgurl:",imageUri.toString());
// tranformUriToFile(imageUri);
//上传文件
if (uploadMessage != null) {
uploadMessage.onReceiveValue(imageUri);
}
if (uploadMessageAboveL != null) {
uploadMessageAboveL.onReceiveValue(new Uri[]{imageUri});
}
}
}
}
//value定义
private ValueCallback<Uri> uploadMessage;
private ValueCallback<Uri[]> uploadMessageAboveL;
问题:至于h5的图片在app上没显示这样解决:
webView.getSettings().setBlockNetworkImage(false); // 解决图片不显示
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}