//随便定义的静态值  调用相机的时候用的 在onActivityResult里面和requestCode 值相对应
private static final int REQUEST_TAKE_PHOTO_CODE = 123;
 
1.首先判断有没有开启权限    
if (!checkPermission()) { //没有或没有全部授权
        requestPermissions(); //请求权限
    }
 else {
//如果开启了 直接调用相机
    takePhoto();//拍照逻辑
}
 
//检查权限
private boolean checkPermission() {
    //是否有权限
    boolean haveCameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;

    boolean haveWritePermission = ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;

    return haveCameraPermission && haveWritePermission;

}
 
// 请求所需权限
@RequiresApi(api = Build.VERSION_CODES.M)
private void requestPermissions() {
    requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CODE);
}
 
//开启权限返回
 
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQUEST_PERMISSION_CODE:
            boolean allowAllPermission = false;
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {//被拒绝授权
                    allowAllPermission = false;
                    break;
                }
                allowAllPermission = true;
            }
            if (allowAllPermission) {
                takePhoto();//开始拍照或从相册选取照片
            } else {
                Toast.makeText(this, "该功能需要授权方可使用", Toast.LENGTH_SHORT).show();
            }

            break;
    }
}
 
//调用相机的方法
 
private void takePhoto() {
    // 步骤一:创建存储照片的文件
    String path = getFilesDir() + File.separator + "images" + File.separator;
    File file = new File(path, "test.jpg");
    if(!file.getParentFile().exists())
        file.getParentFile().mkdirs();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        //步骤二:Android 7.0及以上获取文件 Uri
        //com.rk.myfeaturesapp是自己App的包名fileprovider是死值
        mUri = FileProvider.getUriForFile(CamearActivity.this, "com.rk.myfeaturesapp.fileprovider", file);
    } else {
        //步骤三:获取文件Uri
        mUri = Uri.fromFile(file);
    }
    //步骤四:调取系统拍照
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    intent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
    startActivityForResult(intent,REQUEST_TAKE_PHOTO_CODE);
}
 
//返回的参数
 
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK && requestCode == REQUEST_TAKE_PHOTO_CODE) {//获取系统照片上传

        Bitmap bm = null;
        try {
            bm = getBitmapFormUri(mUri);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        imageView.setImageBitmap(bm);
    }
}
 
//返回的照片进行压缩
 
public Bitmap getBitmapFormUri(Uri uri) throws FileNotFoundException, IOException {
    InputStream input = getContentResolver().openInputStream(uri);

    //这一段代码是不加载文件到内存中也得到bitmap的真是宽高,主要是设置inJustDecodeBounds为true
    BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
    onlyBoundsOptions.inJustDecodeBounds = true;//不加载到内存
    onlyBoundsOptions.inDither = true;//optional
    onlyBoundsOptions.inPreferredConfig = Bitmap.Config.RGB_565;//optional
    BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
    input.close();
    int originalWidth = onlyBoundsOptions.outWidth;
    int originalHeight = onlyBoundsOptions.outHeight;
    if ((originalWidth == -1) || (originalHeight == -1))
        return null;

    //图片分辨率以480x800为标准
    float hh = 800f;//这里设置高度为800f
    float ww = 480f;//这里设置宽度为480f
    //缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
    int be = 1;//be=1表示不缩放
    if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放
        be = (int) (originalWidth / ww);
    } else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据宽度固定大小缩放
        be = (int) (originalHeight / hh);
    }
    if (be <= 0)
        be = 1;
    //比例压缩
    BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
    bitmapOptions.inSampleSize = be;//设置缩放比例
    bitmapOptions.inDither = true;
    bitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
    input = getContentResolver().openInputStream(uri);
    Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
    input.close();

    return compressImage(bitmap);//再进行质量压缩
}
 
//进行二次压缩
 
public 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 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
        baos.reset();//重置baos即清空baos
        //第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差  ,第三个参数:保存压缩后的数据的流
        image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options,把压缩后的数据存放到baos中
        options -= 10;//每次都减少10
        if (options<=0)
            break;
    }
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
    return bitmap;
}
 
//在Androidmanifest进行配置
在<application>里面进行配置
 
<provider
    android:name="androidx.core.content.FileProvider"
//android:authorities="com.rk.myfeaturesapp.fileprovider"和上面的保持一致
    android:authorities="com.rk.myfeaturesapp.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data

//tools:replace="android:resource"是调用手机相机录屏的时候用的

        tools:replace="android:resource"
        android:name="android.support.FILE_PROVIDER_PATHS"
//@xml/file_paths 在res下面创建个文件夹在xml里面创建一个xml名字为file_paths
        android:resource="@xml/file_paths" />
</provider>
 
 
 
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!--files-path  相当于 getFilesDir()-->
    <files-path name="my_images" path="images"/>
    <!--cache-path  相当于 getCacheDir()-->
    <cache-path name="lalala" path="cache_image"/>
    <!--external-path  相当于 Environment.getExternalStorageDirectory()-->
    <external-path  name="hahaha" path="comeOn"/>
    <!--external-files-path  相当于 getExternalFilesDir("") -->
    <external-files-path name="paly" path="freeSoft"/>
    <!--external-cache-path  相当于 getExternalCacheDir() -->
    <external-cache-path  name="lei" path="."/>
    
    //这一行代码的作用是在调用相机进行录屏的时候可以获取到SD卡的视频
    <root-path path="" name="camera_photos" />

    ...
</paths>