欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-04 09:05:40
最近做项目中涉及到了图片相关功能 ,在使用安卓6.0手机及7.1手机拍照时,遇到了因权限及文件管理导致程序崩溃等问题。  刚好把功能修改完,把代码简单地贴一下,...

最近做项目中涉及到了图片相关功能 ,在使用安卓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>

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