1. 程式人生 > >Android 混合開發以及注意事項以及h5上圖片在android機器上不顯示問題

Android 混合開發以及注意事項以及h5上圖片在android機器上不顯示問題

因為這個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);
     }