Android 混合開發以及注意事項以及h5上圖片在android機器上不顯示問題
阿新 • • 發佈:2018-12-14
因為這個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);
}