相机在当前应用中的地位越来越重要,在开发的时候经常遇到相机相关的问题.

权限

使用相机需要我们给与APP调用权限,一般根据APP的targetApi来区分.

API<=19

直接在清单文件中添加相加权限即可

<uses-permission android:name="android.permission.CAMERA" />

通常情况下我们还需要配合本地存储,保存拍摄的照片等等,因此针对需求添加读写本地存储的权限

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
API>19

在Android6.0+的系统上,我们需要动态申请权限,以保证当前APP拥有调用相机的权限,通常情况下我们可以这样写.

 if (ContextCompat.checkSelfPermission(context,
                Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions((Activity) context,
                    new String[]{Manifest.permission.CAMERA},
                    TAKE_PHOTO_REQUEST_CODE);
        } else {
           //调用相机进行某些操作
        }

但是国内厂商定制化系统会对Android系统进行各种各样的魔改,因此有可能你通过上述代码校验的时候返回了true,但是真正使用的使用相机无法正常调用,甚至APP崩溃.
有什么办法能够避免吗?
当然,个人比较推荐严大的AndPermission,很早就开始用了,权限管理比较方便(具体使用我就不多赘述了),对于国产机兼容也比较优秀,但是也会有兼顾不到的地方.
比如在魅族手机上,我们申请了权限,也回调了true,但是真正调用的时候却又显示没有相机权限,或者干脆相机无法打开.

/**
 * 判断摄像头是否可用
 * 主要针对6.0 之前的版本,现在主要是依靠try...catch... 报错信息,感觉不太好,
 * 以后有更好的方法的话可适当替换
 *
 * @return
 */
public static boolean isCameraCanUse() {
    boolean canUse = true;
    Camera mCamera = null;
    try {
        mCamera = Camera.open();
        // setParameters 是针对魅族MX5 做的。MX5 通过Camera.open() 拿到的Camera
        // 对象不为null
        Camera.Parameters mParameters = mCamera.getParameters();
        mCamera.setParameters(mParameters);
    } catch (Exception e) {
        canUse = false;
    }
    if (mCamera != null) {
        mCamera.release();
    }
    return canUse;
}

魅族手机需要单独判断相机是否可用.
通过上面的操作,基本上相机可以正常调用了.

调用系统相机

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra("android.intent.extras.CAMERA_FACING_FRONT", 1); // 调用前置摄像头
intent.putExtra("autofocus", true); // 自动对焦
intent.putExtra("fullScreen", false); // 全屏
intent.putExtra("showActionIcons", false);
startActivityForResult(intent, REQUESTCODE_照相机);

上面就是调用系统前置摄像头的方法,部分前置摄像头不支持自动对焦,需要去掉自动对焦的代码,相机全屏看个人喜好,当然调用后置的话更改android.intent.extras.CAMERA_FACING_FRONT为0就行了.
如果我们需要获取拍摄的图片路径

/**
     * Create a File Uri for saving a photo
     */
    private Uri getOutputPhotoFileUri(String suffix) {
        //get the mobile Pictures directory
        File picDir = new File(DownloadManager.UPLOAD_FLODER);
        if (!picDir.exists()) {
            picDir.mkdirs();
        }
        //get the current time
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File photoFile = new File(picDir.getPath() + File.separator + timeStamp + suffix);
        currentUri = null;
        currentUri = Uri.fromFile(photoFile);
        return currentUri;
    }

在调用相机的intent中加入

 intent.putExtra(MediaStore.EXTRA_OUTPUT, getOutputPhotoFileUri(".jpg"));

然后在onActivityResult方法中获取当前拍摄的状态

resultCode == Activity.RESULT_OK

Activity.RESULT_OK的值是-1,然而有时候返回的resultCode为0,这个时候可能是当前的缓存路径没有创建成功.
前面我们创建目录的时候使用的是

picDir.mkdirs();

这个方法是创建路径,当多级路径中某些不存在时会自动生成.

picDir.mkdir();

这个方法也是生成路径,但是只能生成单级路径,多级路径会创建失败,因此导致先前返回的resultCode=0.

Last modification:December 3rd, 2019 at 11:48 am
If you think my article is useful to you, please feel free to appreciate