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>

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

(0)

相关推荐

  • Android实现拍照、选择图片并裁剪图片功能

    一. 实现拍照.选择图片并裁剪图片效果 按照之前博客的风格,首先看下实现效果. 二. uCrop项目应用 想起之前看到的Yalantis/uCrop效果比较绚,但是研究源码之后发现在定制界面方面还是有一点的限制,于是在它的基础上做了修改Android-Crop,把定制界面独立出来,让用户去自由设置.下图为使用Android-Crop实现的模仿微信选择图片并裁剪Demo. 三. 实现思路 比较简单的选择设备图片裁剪,并将裁剪后的图片保存到指定路径: 调用系统拍照,将拍照图片保存在SD卡,然后裁剪图

  • Android应用中拍照后获取照片路径并上传的实例分享

    Activity 中的代码,我只贴出重要的事件部分代码 public void doPhoto(View view) { destoryBimap(); String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); s

  • Android圆形头像拍照后“无法加载此图片”的问题解决方法(适配Android7.0)

    Feature: 点击选择拍照或者打开相册,选取图片进行裁剪最后设置为圆形头像. Problem: 拍好照片,点击裁剪,弹Toast"无法加载此图片". Solution: 在裁剪的class里加两行代码 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 主要代码如下: public static final S

  • Android拍照保存在系统相册不显示的问题解决方法

    可能大家都知道我们保存相册到Android手机的时候,然后去打开系统图库找不到我们想要的那张图片,那是因为我们插入的图片还没有更新的缘故,先讲解下插入系统图库的方法吧,很简单,一句代码就能实现 复制代码 代码如下: MediaStore.Images.Media.insertImage(getContentResolver(), mBitmap, "", ""); 通过上面的那句代码就能插入到系统图库,这时候有一个问题,就是我们不能指定插入照片的名字,而是系统给了我

  • android图像绘制(六)获取本地图片或拍照图片等图片资源

    从SD卡中获取图片资源,或者拍一张新的图片. 先贴代码 获取图片: 注释:拍照获取的话,可以指定图片的保存地址,在此不说明. 复制代码 代码如下: CharSequence[] items = {"相册", "相机"}; new AlertDialog.Builder(this) .setTitle("选择图片来源") .setItems(items, new OnClickListener() { public void onClick(Dia

  • Android仿微信发表说说实现拍照、多图上传功能

    本文实例为大家分享了Android仿微信发表说说.心情功能,供大家参考,具体内容如下 既能实现拍照,选图库,多图案上传的案例,目前好多App都有类似微信朋友圈的功能,能过发表说说等附带图片上传.下面的就是实现该功能的过程:大家还没有看过Android Retrofit 2.0框架上传图片解决方案这篇文章,在看今天的就很容易,接在本项目中用到了一个library:photopicker,封装了图片的选择功能,是否选相机,还有选中图片后可以查看图片的功能.  一. 首先:将photopicker到工

  • android 拍照和上传的实现代码

    复制代码 代码如下: import java.io.ByteArrayOutputStream;   import java.io.File;   import android.app.Activity;   import android.content.Intent;   import android.graphics.Bitmap;   import android.net.Uri;   import android.os.Bundle;   import android.os.Enviro

  • Android启动相机拍照并返回图片

    具体实现过程请看下面代码: 简单的调用了一下系统的拍照功能 代码如下所示: //拍照的方法 private void openTakePhoto(){ /** * 在启动拍照之前最好先判断一下sdcard是否可用 */ String state = Environment.getExternalStorageState(); //拿到sdcard是否可用的状态码 if (state.equals(Environment.MEDIA_MOUNTED)){ //如果可用 Intent intent

  • Android拍照得到全尺寸图片并进行压缩

    废话不多说了,直接给大家贴代码了,具体代码如下所示: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <

  • 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 in

  • Android 7.0中拍照和图片裁剪适配的问题详解

    前言 Android 7.0系统发布后,拿到能升级的nexus 6P,就开始了7.0的适配.发现在Android 7.0以上,在相机拍照和图片裁剪上,可能会碰到以下一些错误: Process: com.yuyh.imgsel, PID: 22995 // 错误1 android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.yuyh.imgsel/cache/1486438962645.jpg ex

  • android系统拍照结合android-crop裁剪图片

    在一个应用中更换用户的头像,一般有拍照和从图库中选择照片两种方法,现在网上也有很多开源的,但是很多都太复杂.而 Android-crop 这个库比较小,代码不复杂,比较适合,但是它没有拍照这个功能,需要我们自己整合进去. 调用系统相机拍照 1.返回略缩图的拍照 // 调用系统的拍照 private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAP

  • Android实现拍照及图片显示效果

    本文实例为大家分享了Android拍照及图片显示的具体代码,供大家参考,具体内容如下 1.功能声明 当应用需要使用相机.NFC等外设时,需要在AndroidManifest.xml中进行声明. 这样,当设备缺少这些外设时,应用商店的安装程序可以拒绝安装设备. 声明示例代码如下: <uses-feature android:name="android.hardware.camera2" <!-- required为false时,不强制要求设备支持该功能 --> <

  • Android图片裁剪功能实现代码

    在Android应用中,图片裁剪也是一个经常用到的功能.Android系统中可以用隐式意图调用系统应用进行裁剪,但是这样做在不同的手机可能表现出不同的效果,甚至在某些奇葩手机上还会出其他更奇怪的问题,所以调用系统功能进行图片裁剪在很多时候对我们来说并不是一个好的选择.这时候就需要我们自己去实现这种裁剪功能了. 功能分析 要完成图片裁剪的功能,我们需要先知道图片裁剪的功能有哪些.图片裁剪之前,我们需要有一个框指示我们需要裁剪的样式合大小.图片显示出来后大小和位置可能并不是我们所期望的,所以我们还需

  • Android获取本地相册图片和拍照获取图片的实现方法

    需求:从本地相册找图片,或通过调用系统相机拍照得到图片. 容易出错的地方: 1.当我们指定了照片的uri路径,我们就不能通过data.getData();来获取uri,而应该直接拿到uri(用全局变量或者其他方式)然后设置给imageView imageView.setImageURI(uri); 2.我发现手机前置摄像头拍出来的照片只有几百KB,直接用imageView.setImageURI(uri);没有很大问题,但是后置摄像头拍出来的照片比较大,这个时候使用imageView.setIm

  • Android实现拍照、选择相册图片并裁剪功能

    通过拍照或相册中获取图片,并进行裁剪操作,然后把图片显示到ImageView上.  当然也可以上传到服务器(项目中绝大部分情况是上传到服务器),参考网上资料及结合项目实际情况,  测试了多款手机暂时没有发现严重问题.代码有注释,直接贴代码: public class UploadPicActivity extends Activity implements View.OnClickListener { private Button take_photo_btn; private Button s

  • Android调用系统图片裁剪限定尺寸及7.0照相问题的解决方法

    本文实例为大家分享了Android调用系统图片裁剪限定尺寸及7.0照相问题的解决方法,供大家参考,具体内容如下 内容:手机系统的裁剪介绍,7.0调用相机崩溃解决 代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="h

  • android调用原生图片裁剪后图片尺寸缩放的解决方法

    在安卓开发中,如果对拍照后的图片进行图片裁剪,如果是调用系统的裁剪,如下: /* * 裁剪图片 */ private void cropPhoto() { Intent intent = new Intent("com.android.camera.action.CROP"); Uri uri = Uri.parse("file://" + picSavePath); intent.setDataAndType(uri, "image/*");

随机推荐