当前位置: 首页 > 编程笔记 >

Android实现拍照及图片裁剪(6.0以上权限处理及7.0以上文件管理)

章哲茂
2023-03-14
本文向大家介绍Android实现拍照及图片裁剪(6.0以上权限处理及7.0以上文件管理),包括了Android实现拍照及图片裁剪(6.0以上权限处理及7.0以上文件管理)的使用技巧和注意事项,需要的朋友参考一下

最近做项目中涉及到了图片相关功能 ,在使用安卓6.0手机及7.1手机拍照时,遇到了因权限及文件管理导致程序崩溃等问题。
 刚好把功能修改完,把代码简单地贴一下,方便以后使用。

—-主界面 代码 ——

public class MainActivity extends AppCompatActivity {
  //拍照按钮
  private Button take_photo;
  //显示裁剪后的图片
  private ImageView photo_iv;
  private static final int PERMISSIONS_FOR_TAKE_PHOTO = 10;
  //图片文件路径
  private String picPath;
  //图片对应Uri
  private Uri photoUri;
  //拍照对应RequestCode
  public static final int SELECT_PIC_BY_TACK_PHOTO = 1;
  //裁剪图片
  private static final int CROP_PICTURE = 3;


  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    take_photo = (Button) findViewById(R.id.take_photo);
    photo_iv = (ImageView) findViewById(R.id.photo_iv);
    take_photo.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        //小于6.0版本直接操作
        if (Build.VERSION.SDK_INT < 23) {
          takePictures();
        } else {
          //6.0以后权限处理
          permissionForM();
        }
      }
    });
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == Activity.RESULT_OK) {
      if (requestCode == SELECT_PIC_BY_TACK_PHOTO) {
        String[] pojo = {MediaStore.Images.Media.DATA};
        Cursor cursor = managedQuery(photoUri, pojo, null, null, null);
        if (cursor != null) {
          int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);
          cursor.moveToFirst();
          picPath = cursor.getString(columnIndex);
          if (Build.VERSION.SDK_INT < 14) {
            cursor.close();
          }
        }
        if (picPath != null && (picPath.endsWith(".png") || picPath.endsWith(".PNG") || picPath.endsWith(".jpg") || picPath.endsWith(".JPG"))) {
          photoUri = Uri.fromFile(new File(picPath));
          if (Build.VERSION.SDK_INT > 23) {
            photoUri = FileProvider.getUriForFile(this, "com.innopro.bamboo.fileprovider", new File(picPath));
            cropForN(picPath, CROP_PICTURE);
          } else {
            startPhotoZoom(photoUri, CROP_PICTURE);
          }
        } else {
          //错误提示
        }
      }
      if (requestCode == CROP_PICTURE) {
        if (photoUri != null) {
          Bitmap bitmap = BitmapFactory.decodeFile(picPath);
          if (bitmap != null) {
            photo_iv.setImageBitmap(bitmap);
          }
        }
      }
    }
  }

  /**
   * 拍照获取图片
   */
  private void takePictures() {
    //执行拍照前,应该先判断SD卡是否存在
    String SDState = Environment.getExternalStorageState();
    if (SDState.equals(Environment.MEDIA_MOUNTED)) {
      Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
      ContentValues values = new ContentValues();
      photoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
      intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
      startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO);
    } else {
      Toast.makeText(this, "手机未插入内存卡", Toast.LENGTH_LONG).show();
    }
  }


  /**
   * 图片裁剪,参数根据自己需要设置
   *
   * @param uri
   * @param REQUE_CODE_CROP
   */
  private void startPhotoZoom(Uri uri,
                int REQUE_CODE_CROP) {
    int dp = 500;
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setDataAndType(uri, "image/*");
    // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
    intent.putExtra("crop", "true");
    intent.putExtra("scale", true);// 去黑边
    intent.putExtra("scaleUpIfNeeded", true);// 去黑边
    // aspectX aspectY 是宽高的比例
    intent.putExtra("aspectX", 4);//输出是X方向的比例
    intent.putExtra("aspectY", 3);
    intent.putExtra("outputX", 600);//输出X方向的像素
    intent.putExtra("outputY", 450);
    intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    intent.putExtra("noFaceDetection", true);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    intent.putExtra("return-data", false);//设置为不返回数据
    startActivityForResult(intent, REQUE_CODE_CROP);
  }

  /**
   * 7.0以上版本图片裁剪操作
   *
   * @param imagePath
   * @param REQUE_CODE_CROP
   */
  private void cropForN(String imagePath, int REQUE_CODE_CROP) {
    Uri cropUri = getImageContentUri(new File(imagePath));
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setDataAndType(cropUri, "image/*");
    intent.putExtra("crop", "true");
    //输出是X方向的比例
    intent.putExtra("aspectX", 4);
    intent.putExtra("aspectY", 3);
    // outputX outputY 是裁剪图片宽高
    intent.putExtra("outputX", 600);
    intent.putExtra("outputY", 450);
    intent.putExtra("scale", true);
    intent.putExtra("return-data", false);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri);
    intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    intent.putExtra("noFaceDetection", true);
    startActivityForResult(intent, REQUE_CODE_CROP);
  }

  private Uri getImageContentUri(File imageFile) {
    String filePath = imageFile.getAbsolutePath();
    Cursor cursor = getContentResolver().query(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        new String[]{MediaStore.Images.Media._ID},
        MediaStore.Images.Media.DATA + "=? ",
        new String[]{filePath}, 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 (imageFile.exists()) {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DATA, filePath);
        return getContentResolver().insert(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
      } else {
        return null;
      }
    }
  }

  /**
   * 安卓6.0以上版本权限处理
   */
  private void permissionForM() {
    if (ContextCompat.checkSelfPermission(this,
        Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,
        Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,
        Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

      ActivityCompat.requestPermissions(this,
          new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
          PERMISSIONS_FOR_TAKE_PHOTO);
    } else {
      takePictures();
    }
  }

  @Override
  public void onRequestPermissionsResult(int requestCode,
                      @NonNull String[] permissions, @NonNull int[] grantResults) {

    if (requestCode == PERMISSIONS_FOR_TAKE_PHOTO) {
      if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        takePictures();
      }
      return;
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }

}

–主界面布局——–

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.innopro.improve.MainActivity">

  <Button
    android:id="@+id/take_photo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="拍照"
    android:textSize="18sp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

  <ImageView
    android:id="@+id/photo_iv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@mipmap/ic_launcher"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@id/take_photo" />

</android.support.constraint.ConstraintLayout>

–AndroidManifest.xml添加provider——–

   <provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="com.innopro.improve.fileprovider"
      android:exported="false"
      android:grantUriPermissions="true">
      <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
    </provider>

–资源文件下添加xml文件夹及file_paths文件——–

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <paths>
    <external-path
      name="camera_photos"
      path="" />
  </paths>
</resources>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Android实现拍照、选择图片并裁剪图片功能,包括了Android实现拍照、选择图片并裁剪图片功能的使用技巧和注意事项,需要的朋友参考一下 一、 实现拍照、选择图片并裁剪图片效果 按照之前博客的风格,首先看下实现效果。      二、 uCrop项目应用 想起之前看到的Yalantis/uCrop效果比较绚,但是研究源码之后发现在定制界面方面还是有一点的限制,于是在它的基础上做了修

  • 本文向大家介绍Android编程实现图片拍照剪裁的方法,包括了Android编程实现图片拍照剪裁的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android实现图片拍照剪裁的方法。分享给大家供大家参考,具体如下: 调用系统的裁剪工具对相册或者拍照的图片进行裁剪。 startActivityforResult用的很恰当,一些系统action需要注意。 XML文件: 希望本文所述对大家

  • 本文向大家介绍Android实现拍照及图片显示效果,包括了Android实现拍照及图片显示效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android拍照及图片显示的具体代码,供大家参考,具体内容如下 1、功能声明 当应用需要使用相机、NFC等外设时,需要在AndroidManifest.xml中进行声明。 这样,当设备缺少这些外设时,应用商店的安装程序可以拒绝安装设备。 声明

  • 本文向大家介绍Android实现拍照、选择相册图片并裁剪功能,包括了Android实现拍照、选择相册图片并裁剪功能的使用技巧和注意事项,需要的朋友参考一下 通过拍照或相册中获取图片,并进行裁剪操作,然后把图片显示到ImageView上。  当然也可以上传到服务器(项目中绝大部分情况是上传到服务器),参考网上资料及结合项目实际情况,  测试了多款手机暂时没有发现严重问题。代码有注释,直接贴代码: 布

  • 本文向大家介绍android系统拍照结合android-crop裁剪图片,包括了android系统拍照结合android-crop裁剪图片的使用技巧和注意事项,需要的朋友参考一下 在一个应用中更换用户的头像,一般有拍照和从图库中选择照片两种方法,现在网上也有很多开源的,但是很多都太复杂。而 Android-crop 这个库比较小,代码不复杂,比较适合,但是它没有拍照这个功能,需要我们自己整合进去。

  • 本文向大家介绍android完美实现 拍照 选择图片 剪裁等代码分享,包括了android完美实现 拍照 选择图片 剪裁等代码分享的使用技巧和注意事项,需要的朋友参考一下 前言,版本兼容问题主要是由于4.4以前和4.4以后的Uri的格式不同所造成的错误 1.拍照 和选择图片   ①选择图片   ②拍照 2.获取系统传来的值 标记符 3.图片选取后 根据Url 转成流 并保存 4.保存图片 记得加权