android7.0以上调用系统相机拍照并显示到ImageView上

 

/*
*  第一步:新建文件 res/xml/file_paths.xml
   <paths xmlns:android="http://schemas.android.com/apk/res/android">
      <external-path path="." name="camera_photos" />
   </paths>
*  第二步:AndroidManifest.xml文件的application标签中插入下边
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.lrogzin.memo.fileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
*  第三步:在你需要的地方调用startCamera()
*  第四步:在你的onActivityResult()中加入:
*
* */
public class UseSysCameraUtil {

    public static final int CAMERA_CODE = 110;
    public static Uri takePictureUri;//拍照图片uri
    private static Uri cropPictureTempUri;//裁剪图片uri
    private static File takePictureFile;//拍照图片File

    public static void startCamera(Activity activity, String displayName) {
        takePictureUri = createImagePathUri(activity, displayName);
        if (takePictureUri != null) {
            Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            i.putExtra(MediaStore.EXTRA_OUTPUT, takePictureUri);//输出路径(拍照后的保存路径)
            activity.startActivityForResult(i, CAMERA_CODE);
        } else {
            Toast.makeText(activity, "打开相机失败", Toast.LENGTH_LONG).show();
        }
    }

    public static Uri createImagePathUri(Activity activity, String displayName) {
        //适配 Android=Q Android=7 API=29
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            //图片名称
            //String displayName = String.valueOf(System.currentTimeMillis());
            //String displayName = "head";
            ContentValues values = new ContentValues(2);
            values.put(MediaStore.Images.Media.DISPLAY_NAME, displayName);
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
            //SD 卡是否可用,可用则用 SD 卡,否则用内部存储
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                takePictureUri = activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                takePictureUri = activity.getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
            }
        } else {
            String pathName = new StringBuffer().append(FileUtils.getExtPicturesPath()).append(File.separator)
                    .append(System.currentTimeMillis()).append(".jpg").toString();
            takePictureFile = new File(pathName);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //解决Android 7.0 拍照出现FileUriExposedException的问题
                String authority = activity.getPackageName() + ".fileProvider";
                takePictureUri = FileProvider.getUriForFile(activity, authority, takePictureFile);
            } else {
                takePictureUri = Uri.fromFile(takePictureFile);
            }
        }
        return takePictureUri;
    }

    public static void onCameraRes(int requestCode, int resultCode, Activity activity) {
        try {
            if (requestCode == CAMERA_CODE && resultCode == activity.RESULT_OK) {
                Bitmap headBitmap = BitmapFactory.decodeStream(activity.getContentResolver().openInputStream(takePictureUri));
                //mainAvatar.setImageBitmap(headBitmap);

            }
        } catch (Exception e) {
            //throw new RuntimeException(e);
            e.printStackTrace();
        }
    }

    public static Bitmap compressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        int options = 100;
        //循环判断如果压缩后图片是否大于100kb,大于继续压缩
        while (baos.toByteArray().length / 1024 > 100) {
            baos.reset();//重置baos即清空baos
            //第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差  ,第三个参数:保存压缩后的数据的流
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);
            //这里压缩options,把压缩后的数据存放到baos中
            //每次都减少10
            options -= 10;
            if (options <= 0)
                break;
        }
        //把压缩后的数据baos存放到ByteArrayInputStream中
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        //把ByteArrayInputStream数据生成图片
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
        return bitmap;
    }

    static int CROP_CODE = 3;

    //调用系统的裁剪功能的实现
   /*
   *   onActivityResult()
   *   case CROP_CODE:
                //裁剪返回的
                if (data != null) {
                    Bundle extras = data.getExtras();
                    headBitmap = extras.getParcelable("data");
                    if (headBitmap != null) {
                        mainAvatar.setImageBitmap(headBitmap);// 用ImageView显示出来
                        dialogAvatar.setImageBitmap(headBitmap);
                    }
                }
   */
    public static void cropPhoto(Uri uri, Activity activity) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 150);
        intent.putExtra("outputY", 150);
        intent.putExtra("return-data", true);
        activity.startActivityForResult(intent, CROP_CODE);
    }

    int PERMISSIONS_REQUEST_CAMERA = 1111;

    // 请求相机权限
    private void requestCameraPermission(Activity activity) {
        if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, PERMISSIONS_REQUEST_CAMERA);
        } else {
            //goCamera();
            //jumpToTakePhoto();
            //startCamera();
        }
    }

   /*@Override
   public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      if (requestCode == PERMISSIONS_REQUEST_CAMERA) {
         if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 权限被授予,执行拍照操作
            //goCamera();
            //jumpToTakePhoto();
            startCamera();
         } else {
            // 权限被拒绝
            Toast.makeText(activity, "Camera permission is required to take a photo.", Toast.LENGTH_SHORT).show();
         }
      }
   }*/

    /**
     * 获取图片路径
     *
     * @param context Context
     * @param uri     图片 Uri
     * @return 图片路径
     */
    public static String getImagePath(Context context, Uri uri) {
        Cursor cursor = null;
        try {
            String[] proj = {MediaStore.Images.Media.DATA};
            cursor = context.getContentResolver().query(uri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            String s = cursor.getString(column_index);
            return s;
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    /**
     * 获取图片 Uri
     *
     * @param context Context
     * @param path    图片路径
     * @return 图片 Uri
     */
    public static Uri getImageUri(Context context, String path) {
        Cursor cursor = context.getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media._ID},
                MediaStore.Images.Media.DATA + "=? ", new String[]{path}, null);
        if (cursor != null && cursor.moveToFirst()) {
            int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
            Uri baseUri = Uri.parse("content://media/external/images/media");
            return Uri.withAppendedPath(baseUri, "" + id);
        } else {
            if (new File(path).exists()) {
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.DATA, path);
                return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                return null;
            }
        }
    }

}

 

public final class FileUtils {

   /**
    * 得到SD卡根目录,SD卡不可用则获取内部存储的根目录
    */
   public static File getRootPath() {
      File path = null;
      if (sdCardIsAvailable()) {
         path = Environment.getExternalStorageDirectory(); //SD卡根目录    /storage/emulated/0
      } else {
         path = Environment.getDataDirectory();//内部存储的根目录    /data
      }
      return path;
   }

   /**
    * 获取图片目录
    *
    * @return 图片目录(/storage/emulated/0/Pictures)
    */
   public static File getExtPicturesPath() {
      File extPicturesPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
      if (!extPicturesPath.exists()) {
         extPicturesPath.mkdir();
      }
      return extPicturesPath;
   }

   /**
    * 获取缓存图片的目录
    *
    * @param context Context
    * @return 缓存图片的目录
    */
   public static String getImageCacheDir(Context context) {
      String cachePath;
      if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
         cachePath = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getPath();
      } else {
         cachePath = context.getCacheDir().getPath();
      }
      return cachePath;
   }

   /**
    * 删除缓存图片目录中的全部图片
    *
    * @param context
    */
   public static void deleteAllCacheImage(Context context) {
      String cacheImagePath = getImageCacheDir(context);
      File cacheImageDir = new File(cacheImagePath);
      File[] files = cacheImageDir.listFiles();
      if (files != null) {
         for (File file : files) {
            if (file.isFile()) {
               file.delete();
            }
         }
      }
   }

   /**
    * SD卡是否可用
    */
   public static boolean sdCardIsAvailable() {
      if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
         File sd = new File(Environment.getExternalStorageDirectory().getPath());
         return sd.canWrite();
      } else
         return false;
   }

   /**
    * 判断目录是否存在,不存在则判断是否创建成功
    *
    * @param dirPath 文件路径
    * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败
    */
   public static boolean createOrExistsDir(String dirPath) {
      return createOrExistsDir(getFileByPath(dirPath));
   }

   /**
    * 判断目录是否存在,不存在则判断是否创建成功
    *
    * @param file 文件
    * @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败
    */
   public static boolean createOrExistsDir(File file) {
      // 如果存在,是目录则返回true,是文件则返回false,不存在则返回是否创建成功
      return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());
   }

   /**
    * 根据文件路径获取文件
    *
    * @param filePath 文件路径
    * @return 文件
    */
   public static File getFileByPath(String filePath) {
      return isSpace(filePath) ? null : new File(filePath);
   }

   /**
    * 判断字符串是否为 null 或全为空白字符
    *
    * @param s
    * @return
    */
   private static boolean isSpace(final String s) {
      if (s == null)
         return true;
      for (int i = 0, len = s.length(); i < len; ++i) {
         if (!Character.isWhitespace(s.charAt(i))) {
            return false;
         }
      }
      return true;
   }

}

 

posted @ 2024-07-07 12:25  野生野鸡码农  阅读(39)  评论(0编辑  收藏  举报