Android在H5中訪問相機與相冊

有時候我們需要在H5中調用Android的相機與相冊,前段時間項目中用到了,鼓搗了一波。

老樣子,拷貝代碼就好使!

首先整個工具類,先訪問一下相機權限:

public class Authority {

    private static final int MY_PERMISSION_REQUEST_CODE = 10000;
    //申請的權限,字符串模式
    public static final String CALL_PHONE = Manifest.permission.CALL_PHONE;//打電話權限
    public static final String CAMERA = Manifest.permission.CAMERA;//相機攝像頭權限
    public static final String READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE;//讀取內存卡權限
    public static final String WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;//寫入內存卡權限

    //申請的權限,數組模式
    public static final String[] CALL_PHONE_ARR = {Manifest.permission.CALL_PHONE};//打電話權限
    public static final String[] CAMERA_ARR = {Manifest.permission.CAMERA};//相機攝像頭權限
    public static final String[] READ_EXTERNAL_STORAGE_ARR = {Manifest.permission.READ_EXTERNAL_STORAGE};//讀取內存卡權限
    public static final String[] WRITE_EXTERNAL_STORAGE_ARR = {Manifest.permission.WRITE_EXTERNAL_STORAGE};//寫入內存卡權限

    //權限數組
    public static final String[] str = {
            Manifest.permission.CALL_PHONE,//打電話
            Manifest.permission.CAMERA, //相機
//            Manifest.permission.ACCESS_NETWORK_STATE,//網絡
//            Manifest.permission.ACCESS_WIFI_STATE,//wifi
//            Manifest.permission.CHANGE_WIFI_STATE,//wifi
//            Manifest.permission.INTERNET,//網絡
            Manifest.permission.READ_EXTERNAL_STORAGE,//獲取sd
            Manifest.permission.WRITE_EXTERNAL_STORAGE//寫入sd
    };

    //申請權限,多項申請(Activity)
    public static void CallMobile(Activity mContext) {
        ActivityCompat.requestPermissions(
                mContext,
                str,
                MY_PERMISSION_REQUEST_CODE//回調的標識
        );
    }

    //申請權限,單項權限,(Activity)
    public static void CallMobileArr(Activity mContext, String[] str) {
        ActivityCompat.requestPermissions(
                mContext,
                str,
                MY_PERMISSION_REQUEST_CODE//回調的標識
        );
    }

    //申請權限(fragment)
    //  requestPermissions(Authority.CAMERA_ARR, 10000);這種模式,不可以顯示申請權限彈框.如果禁止所申請的權限,可以顯示自定義彈框
    //下面這種模式:可以顯示申請權限彈框.如果禁止所申請的權限,並且“下次不會再次提醒”已勾選,不會顯示彈框
    @TargetApi(Build.VERSION_CODES.M)
    public static void CallMobileFragment(Activity mContext, String[] str) {
        mContext.requestPermissions(str, MY_PERMISSION_REQUEST_CODE);
    }


    //判斷權限是否申請通過
    public static boolean lacksPermission(Context mContexts, String permission) {
        return ContextCompat.checkSelfPermission(mContexts, permission) ==
                PackageManager.PERMISSION_DENIED;
    }


    /**
     * @param s                  提示語
     * @param applicationContext 上下文
     * @param type               類型,是否關閉頁面 1關閉,0不關閉
     */
    public static void openAppDetails(String s, final Activity applicationContext, final int type) {
        final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(applicationContext);
        builder.setMessage(s);
        builder.setCancelable(false);
        builder.setPositiveButton("去手動授權", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.setData(Uri.parse("package:" + applicationContext.getPackageName()));
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                applicationContext.startActivity(intent);
                if (type == 1) {
                    applicationContext.finish();
                }

            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                if (type == 1) {
                    applicationContext.finish();
                }
            }
        });
        builder.show();
    }

    //設置popu背景色
    public static void setBackgroundAlpha(float bgAlpha, Activity mContext) {
        WindowManager.LayoutParams lp = mContext.getWindow()
                .getAttributes();
        lp.alpha = bgAlpha;
        mContext.getWindow().setAttributes(lp);
    }
}

然後是Activity部分,申請相機權限:

Authority.CallMobileArr(LiangFangActivity.this, new String[]{Manifest.permission.CAMERA});

相機權限的回調

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 10000) {
        int isClose = 0;
        for (int i = 0; i < permissions.length; i++) {
            if (permissions[i].equals(Manifest.permission.CAMERA) || permissions[i].equals(Manifest.permission.READ_EXTERNAL_STORAGE) || permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                if (grantResults[i] == -1) {
                    isClose = 1;
                    final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(LiangFangActivity.this);
                    builder.setMessage("攝像頭權限和存儲權限爲必要的權限。\n由於您拒絕了,這導致您無法正常使用該應用。");
                    builder.setCancelable(false);
                    builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                            LiangFangActivity.this.finish();
                        }
                    });
                    builder.show();
                }
            }
        }
    }
}

下面正文部分

寫了個方法,在onCreat方法裏調用即可

private void setCheckImg() {
    mLiangFangWebView.setWebChromeClient(new WebChromeClient() {
        // For Android < 3.0
        public void openFileChooser(ValueCallback<Uri> valueCallback) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }

        // For Android  >= 3.0
        public void openFileChooser(ValueCallback valueCallback, String acceptType) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }

        //For Android  >= 4.1
        public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
            uploadMessage = valueCallback;
            openImageChooserActivity();
        }

        // For Android >= 5.0
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
            uploadMessageAboveL = filePathCallback;
            openImageChooserActivity();
            return true;
        }
    });
}

然後選擇彈出了一個選擇框,相機還是相冊

    private void openImageChooserActivity() {
        AlertDialog dialog = new AlertDialog.Builder(this)
                .setMessage("請選擇")
                .setPositiveButton("相機", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        time = Calendar.getInstance().getTimeInMillis();


//                        file = new File(Environment.getExternalStorageDirectory().getPath()+"/", time + ".jpg");
                        pathTakePhoto = Environment.getExternalStorageDirectory().getPath()
                                + "/mbossclient/camera/temp/"
                                + (System.currentTimeMillis() + ".jpg");
                        File vFile = new File(pathTakePhoto);
                        if (!vFile.exists()) {
                            File vDirPath = vFile.getParentFile();
                            vDirPath.mkdirs();
                            Log.e("alshdkash", "onClick: " + vFile.getPath());
                        } else {
                            if (vFile.exists()) {
                                vFile.delete();
                            }
                        }

                        photoURI = FileProvider.getUriForFile(LiangFangActivity.this, App.context.getApplicationContext().getPackageName() + ".provider", vFile);
//        uriTakePhoto = Uri.fromFile(vFile);
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                        startActivityForResult(intent, FILE_CHOOSER_RESULT_CODE1);

                    }
                }).setNegativeButton("相冊", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                i.addCategory(Intent.CATEGORY_OPENABLE);
                i.setType("image/*");
                startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
            }
        }).create();
        dialog.show();
        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                cancelFilePathCallback();
            }
        });
    }

如果不選擇的話,調用此方法。需要一個返回值,沒有返回值會導致無法再次調起相機相冊,需要重新進入

private void cancelFilePathCallback() {
    if (uploadMessage != null) {
        uploadMessage.onReceiveValue(null);
        uploadMessage = null;
    } else if (uploadMessageAboveL != null) {
        uploadMessageAboveL.onReceiveValue(null);
        uploadMessageAboveL = null;
    }
}

然後是相機,相冊的回調

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == FILE_CHOOSER_RESULT_CODE) {
            if (null == uploadMessage && null == uploadMessageAboveL) {
                return;
            }
            Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
            if (uploadMessageAboveL != null) {
                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (uploadMessage != null) {
                uploadMessage.onReceiveValue(result);
                uploadMessage = null;
            }
        } else if (requestCode == FILE_CHOOSER_RESULT_CODE1) {

            if (uploadMessageAboveL != null) {
                Uri[] results2 = {photoURI};
                uploadMessageAboveL.onReceiveValue(results2);
                uploadMessageAboveL = null;
//                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (uploadMessage != null) {
                uploadMessage.onReceiveValue(photoURI);
                uploadMessage = null;
            }
        }
    }
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
    if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
        return;
    Uri[] results = null;
    if (resultCode == Activity.RESULT_OK) {
        if (intent != null) {
            String dataString = intent.getDataString();
            ClipData clipData = intent.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)};
        }
    }
    uploadMessageAboveL.onReceiveValue(results);
    uploadMessageAboveL = null;

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