Android使用ImagePicker在返回數據給網頁

自定義圖片選擇器

/**
 * 拍照或者從相冊獲取圖片
 * Created by PersonalFolder on 16/11/10.
 */
public class ImagePick implements View.OnClickListener {

    private final int PICK_REQUEST = 0x1001;
    private final int TAKE_REQUEST = 0x1002;

    private static final String imgDir = Environment.getExternalStorageDirectory() + File.separator + "cloud";
    public static String imgFile = imgDir + File.separator + "tmp.jpg";

    private Activity activity;
    private Dialog dialog;

    public interface MyUri {
        void getUri(Uri uri);
    }

    public interface MyDismiss {
        void dismiss();
    }

    private MyDismiss md;

    public ImagePick(Activity activity) {
        this.activity = activity;

        dialog = new Dialog(activity, R.style.DialogStyle);
        //dialog.setCancelable(true);
        dialog.setCanceledOnTouchOutside(true);
        View root = LayoutInflater.from(activity).inflate(R.layout.select_img, null);
        // 設置點擊監聽
        root.findViewById(R.id.take_photo).setOnClickListener(this);
        root.findViewById(R.id.album_photo).setOnClickListener(this);
        root.findViewById(R.id.cancel).setOnClickListener(this);

        dialog.setContentView(root);
    }

    public void setCancel(MyDismiss md) {
        this.md = md;
    }

    /**
     * 顯示Dialog
     */
    public void show() {
        //這樣先md.dismiss可以保證dialog取消後可以再次打開
        if (md != null) {
            md.dismiss();
        }
        dialog.show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.take_photo:
                takePhoto();
                break;
            case R.id.album_photo:
                getAlbum();
                break;
            case R.id.cancel:
                if (md != null) {
                    md.dismiss();
                }
                break;
        }
        dialog.dismiss();
    }

    public void dismissImagePick(){
        if (md != null) {
            md.dismiss();
        }
        dialog.dismiss();
    }

    /**
     * 拍照
     */
    private void takePhoto() {
        String sdState = Environment.getExternalStorageState();
        // 如果SD卡可讀寫
        if (sdState.equals(Environment.MEDIA_MOUNTED)) {
            new File(imgDir).mkdirs();
            File file = new File(imgFile);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
            activity.startActivityForResult(intent, TAKE_REQUEST);
        } else {
            Toast.makeText(activity, "請確認已經插入SD卡", Toast.LENGTH_SHORT).show();
        }
    }
    /**
     * 從相冊獲取
     */
    private void getAlbum() {
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setType("image/*");
        activity.startActivityForResult(intent, PICK_REQUEST);
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data, MyUri uri) {
        if (resultCode != activity.RESULT_OK) {
            return;
        }
        if (requestCode == PICK_REQUEST) {
            if (data.getData() != null) {
                uri.getUri(data.getData());
            }
        } else if (requestCode == TAKE_REQUEST) {
            if (data != null) {
                Uri myUri;
                if (data.getData() != null) {
                    uri.getUri(data.getData());
                    return;
                }
                if (data.hasExtra("data")) {
                    Bitmap bitmap = data.getParcelableExtra("data");
                    try {
                        myUri = Uri.parse(MediaStore.Images.Media.insertImage(activity.getContentResolver(), bitmap, null, null));
                        uri.getUri(myUri);
                    } catch (Exception e) {
                        e.printStackTrace();
                        // 大神手機這行代碼報異常:MediaStore.Images.Media.insertImage(activity.getContentResolver(), bitmap, null, null)
                        getUri(uri);
                    }
                } else {
                    // Nexus 6 返回Intent{}得不到數據
                    getUri(uri);
                }
            } else {
                getUri(uri);
            }
        }
    }
    private void getUri(MyUri uri) {
        File file = new File(imgFile);
        if (file != null && file.exists()) {
            uri.getUri(Uri.fromFile(file));
        }
    }

    /**
     * 裁剪圖片,並按照給定的長寬輸出
     *
     * @param activity
     * @param uri          拍照或者選擇照片後獲得的URI
     * @param outputWidth  輸出的寬度
     * @param outputHeight 輸出的高度
     * @param requestCode  請求碼
     */
    public void cropImg(Activity activity, Uri uri, int outputWidth, int outputHeight, int requestCode) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", outputWidth);
        intent.putExtra("aspectY", outputHeight);
        intent.putExtra("outputX", outputWidth);
        intent.putExtra("outputY", outputHeight);
        intent.putExtra("outputFormat", "JPEG");
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("return-data", true);
        activity.startActivityForResult(intent, requestCode);
    }
}

重寫WebView輔助類WebChromeClient,返回數據給H5

 private ValueCallback<Uri> mFilePathCallback;
 private ValueCallback<Uri[]> mFilePathCallbackArray;
 private ImagePick ip;
    //...

 public class MainWebChromeClient extends WebChromeClient {

        // file upload callback (Android 2.2 (API level 8) -- Android 2.3 (API level 10)) (hidden method)
        public void openFileChooser(ValueCallback<Uri> filePathCallback) {
            handle(filePathCallback);
        }

        // file upload callback (Android 3.0 (API level 11) -- Android 4.0 (API level 15)) (hidden method)
        public void openFileChooser(ValueCallback filePathCallback, String acceptType) {
            handle(filePathCallback);
        }

        // file upload callback (Android 4.1 (API level 16) -- Android 4.3 (API level 18)) (hidden method)
        public void openFileChooser(ValueCallback<Uri> filePathCallback, String acceptType, String capture) {
            handle(filePathCallback);
        }


        // for Lollipop
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, android.webkit.WebChromeClient.FileChooserParams fileChooserParams) {
            // Double check that we don't have any existing callbacks
            if (mFilePathCallbackArray != null) {
                mFilePathCallbackArray.onReceiveValue(null);
            }
            mFilePathCallbackArray = filePathCallback;
            showDialog();
            return true;
        }

        /**
         * 處理5.0以下系統回調
         *
         * @param filePathCallback
         */
        private void handle(ValueCallback<Uri> filePathCallback) {
            if (mFilePathCallback != null) {
                mFilePathCallback.onReceiveValue(null);
            }
            mFilePathCallback = filePathCallback;
            showDialog();
        }


        /**
         * 顯示照片選取Dialog
         */
        public void showDialog() {
            if (ip == null) {
                ip = new ImagePick(MainActivity.this);
            }
            ip.setCancel(new ImagePick.MyDismiss() {
                @Override
                public void dismiss() {
                    handleCallback(null);
                }
            });
            ip.show();
        }

        /**
         * 攔截js彈窗
         * @param view
         * @param url
         * @param message
         * @param result
         * @return
         */
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {

            if (!message.contains("404") && !message.contains("服務器異常") && !message.contains("網絡無法連接")) {
                Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
            }
            result.confirm();
            return true;
        }

        /**
        *  Webview加載頁面進度
        */
        @Override
        public void onProgressChanged(WebView view, int newProgress) {

            super.onProgressChanged(view, newProgress);
        }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) { // 正常照片選取的時候調用
            ip.onActivityResult(requestCode, resultCode, data, new ImagePick.MyUri() {
                @Override
                public void getUri(Uri uri) {
                    handleCallback(uri);
                }
            });
        } else {
            // 取消了照片選取的時候調用
            handleCallback(null);
        }
    }

    /**
     * 處理WebView的回調
     *
     * @param uri
     */
    private void handleCallback(Uri uri) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (mFilePathCallbackArray != null) {
                if (uri != null) {
                    mFilePathCallbackArray.onReceiveValue(new Uri[]{uri});
                } else {
                    mFilePathCallbackArray.onReceiveValue(null);
                }
                mFilePathCallbackArray = null;
            }
        } else {
            if (mFilePathCallback != null) {
                if (uri != null) {
                    mFilePathCallback.onReceiveValue(uri);
                } else {
                    mFilePathCallback.onReceiveValue(null);
                }
                mFilePathCallback = null;
            }
        }

    }

通過上面兩大步就可以完成WebView其調用ImagePicker來選擇圖片,然後通過將用戶圖片數據返回給網頁。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章