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

作者:迟做总比不做强 时间:2022-05-19 09:18:14 

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

来源:http://blog.csdn.net/true100/article/details/78285270

标签:android6.0,权限,拍照
0
投稿

猜你喜欢

  • 详解maven中央仓库连不上的解决办法

    2023-02-25 08:43:54
  • Java中五种不同方法的创建对象

    2021-07-25 01:11:37
  • IDEA(jetbrain通用)使用教程图解

    2023-04-15 04:05:49
  • hadoop分布式环境搭建过程

    2023-09-23 15:18:50
  • springboot集成nacos读取nacos配置数据的原理

    2021-08-09 13:38:25
  • Flutter web bridge 通信总结分析详解

    2022-05-23 05:15:42
  • Java多线程高并发中的Fork/Join框架机制详解

    2021-06-17 01:08:08
  • 非常实用的侧滑删除控件SwipeLayout

    2023-02-01 14:52:39
  • 值得收藏的2017年Java开发岗位面试题

    2023-11-29 15:22:01
  • SpringCloud微服务基础简介

    2022-09-01 23:16:24
  • java unicode转码为中文实例

    2021-08-14 04:44:14
  • Android Studio 透明状态栏的实现示例

    2022-12-06 21:44:23
  • C#使用NPOI导入Excel的方法详解

    2021-08-29 07:39:35
  • Unity3D实现打砖块游戏

    2021-11-13 11:29:44
  • SpringBoot3.0整合chatGPT的完整步骤

    2023-01-29 01:34:36
  • Android中自定义View的实现方式总结大全

    2023-02-03 08:55:55
  • Android自定义控件实现按钮滚动选择效果

    2023-04-02 09:42:02
  • java多线程中执行多个程序的实例分析

    2023-03-11 18:21:58
  • C#实现winform中RichTextBox在指定光标位置插入图片的方法

    2022-04-04 01:50:16
  • springboot 返回json格式数据时间格式配置方式

    2023-12-17 23:27:10
  • asp之家 软件编程 m.aspxhome.com