只简述我发现问题的根源,有些是适配了7.0,会报权限失败问题,那是由于没有动态授权导致,接下来我一步一步给大家实现7.0适配,使用的是Kotlin语言
1.在mainfest标签里加入以下该权限
2.在application下加入该
android:name="android.support.v4.content.FileProvider" android:authorities="com.wocus.myapplication.fileprovider" //这里写自己的包名,后面固定 android:exported="false" android:grantUriPermissions="true"> android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" /> 提供filepaths源码,在res目录下创建xml文件夹,在里面新建filepaths.xml文件 a.新建3个file对象用于存储读取出来的图片 varcamerafile:File?=null//照相机File对象 vargalleryfile:File?=null//相册的File对象 varcropfile:File?=null//照相机的File对象 b.首先在开始调用拍照或者选择图片的时候要动态验证权限 @SuppressLint("NewApi") fun requestReadExternalPermission(){ if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if(shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) { }else{ requestPermissions(arrayOf(Manifest.permission.CAMERA,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE),0) } } } //权限回调方法 override funonRequestPermissionsResult(requestCode: Int,permissions: Array,grantResults: IntArray) { when(requestCode){ 0->{ if(grantResults.size>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { }else{ Toasty.error(baseContext,"授权失败").show() } } } super.onRequestPermissionsResult(requestCode,permissions,grantResults) } c.拍照的代码 /** * 选择照相机拍照 */ fungetCamera(){ varintent:Intent= Intent(MediaStore.ACTION_IMAGE_CAPTURE) if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ img_paths=SimpleDateFormat("yyyyMMddHHmmss").format(Date())+".jpg" varpath:File= getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) camerafile= File(path,img_paths) if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) {//7.0及以上 intent.putExtra(MediaStore.EXTRA_OUTPUT,FileProvider.getUriForFile(this,"com.wocus.myapplication.fileprovider",camerafile)) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) }else{ intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(camerafile)) } startActivityForResult(intent,100) }else{ Toasty.error(this,"存储卡不可用!").show() } } d.从相册选择图片的代码 /** * 从相册选择照片 */ fungetGallery(){ img_paths=SimpleDateFormat("yyyyMMddHHmmss").format(Date())+".jpg" varpath:File= getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) galleryfile= File(path,img_paths) varintent:Intent= Intent(Intent.ACTION_GET_CONTENT) intent.addCategory(Intent.CATEGORY_OPENABLE) intent.setType("image/*") if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){ intent.putExtra(MediaStore.EXTRA_OUTPUT,FileProvider.getUriForFile(baseContext,"com.wocus.myapplication.fileprovider",galleryfile)) intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) startActivityForResult(intent,200) }else{ startActivityForResult(intent,200) } } e.回传方法的代码 override funonActivityResult(requestCode: Int,resultCode: Int,data: Intent?) { super.onActivityResult(requestCode,resultCode,data) if(requestCode==100&& resultCode== Activity.RESULT_OK){//拍照回传 img_paths=SimpleDateFormat("yyyyMMddHHmmss").format(Date())+".jpg" varpath:File= getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) cropfile= File(path,img_paths) if(Build.VERSION.SDK_INT>=24){ varinputUri:Uri=FileProvider.getUriForFile(baseContext,"com.wocus.myapplication.fileprovider",camerafile) startPhotoZoom(inputUri) }else{ varinputUri:Uri=Uri.fromFile(camerafile) startPhotoZoom(inputUri) } }else if(requestCode==200&& resultCode== Activity.RESULT_OK){//选择照片回传 img_paths=SimpleDateFormat("yyyyMMddHHmmss").format(Date())+".jpg" varpath:File= getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) cropfile= File(path,img_paths) if(Build.VERSION.SDK_INT>=24){ varimgUri:File= File(GetImagePath.getPath(baseContext,data!!.data)) vardataUri:Uri=FileProvider.getUriForFile(baseContext,"com.wocus.myapplication.fileprovider",imgUri) startPhotoZoom(dataUri) }else{ startPhotoZoom(data!!.data) } }else{//裁剪回传 varbm:Bitmap=BitmapFactory.decodeFile(cropfile!!.absolutePath) img_up_photo.setImageBitmap(bm) } } f.裁剪代码 /** * 图片剪裁 */ funstartPhotoZoom(inputUri:Uri){ if(inputUri==null)return varintent:Intent= Intent("com.android.camera.action.CROP") //sdk>=24 if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) { varoutPutUri:Uri = Uri.fromFile(cropfile) intent.setDataAndType(inputUri,"image/*") intent.putExtra(MediaStore.EXTRA_OUTPUT,outPutUri) intent.putExtra("noFaceDetection", false);//去除默认的人脸识别,否则和剪裁匡重叠 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) }else{ varoutPutUri:Uri = Uri.fromFile(cropfile) if(Build.VERSION.SDK_INT>= android.os.Build.VERSION_CODES.KITKAT) { varurl = GetImagePath.getPath(this,inputUri)//这个方法是处理4.4以上图片返回的Uri对象不同的处理方法 intent.setDataAndType(Uri.fromFile(File(url)),"image/*") }else{ intent.setDataAndType(inputUri,"image/*") } intent.putExtra(MediaStore.EXTRA_OUTPUT,outPutUri) } // 设置裁剪 intent.putExtra("crop","true") // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX",1) intent.putExtra("aspectY",1) // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX",200) intent.putExtra("outputY",200) intent.putExtra("return-data", false) intent.putExtra("outputFormat",Bitmap.CompressFormat.JPEG.toString())// 图片格式 startActivityForResult(intent,300)//这里就将裁剪后的图片的Uri返回了 } g.分享一个图片相关工具类,网上很多人用的是这个 packagecom.wocus.myapplication.util; importandroid.annotation.SuppressLint; importandroid.content.ContentUris; importandroid.content.Context; importandroid.database.Cursor; importandroid.net.Uri; importandroid.os.Build; importandroid.os.Environment; importandroid.provider.DocumentsContract; importandroid.provider.MediaStore; public classGetImagePath { // 4.4以上 content://com.android.providers.media.documents/document/image:3952 // 4.4以下 content://media/external/images/media/3951 @SuppressLint("NewApi") public staticStringgetPath(finalContext context, finalUri uri) { final booleanisKitKat = Build.VERSION.SDK_INT>= Build.VERSION_CODES.KITKAT; // DocumentProvider if(isKitKat && DocumentsContract.isDocumentUri(context,uri)) { // ExternalStorageProvider if(isExternalStorageDocument(uri)) { finalString docId = DocumentsContract.getDocumentId(uri); finalString[] split = docId.split(":"); finalString type = split[0]; if("primary".equalsIgnoreCase(type)) { returnEnvironment.getExternalStorageDirectory() +"/"+ split[1]; } } // DownloadsProvider else if(isDownloadsDocument(uri)) { finalString id = DocumentsContract.getDocumentId(uri); finalUri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"),Long.valueOf(id)); returngetDataColumn(context,contentUri, null, null); } // MediaProvider else if(isMediaDocument(uri)) { finalString docId = DocumentsContract.getDocumentId(uri); finalString[] split = docId.split(":"); finalString type = split[0]; Uri contentUri =null; if("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; }else if("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; }else if("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } finalString selection ="_id=?"; finalString[] selectionArgs =newString[]{ split[1] }; returngetDataColumn(context,contentUri,selection,selectionArgs); } } // MediaStore (and general) else if("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address if(isGooglePhotosUri(uri)) returnuri.getLastPathSegment(); returngetDataColumn(context,uri, null, null); } // File else if("file".equalsIgnoreCase(uri.getScheme())) { returnuri.getPath(); } return null; } //Android 4.4以下版本自动使用该方法 public staticStringgetDataColumn(Context context,Uri uri,String selection, String[] selectionArgs) { Cursor cursor =null; finalString column ="_data"; finalString[] projection = { column }; try{ cursor = context.getContentResolver().query(uri,projection,selection,selectionArgs, null); if(cursor !=null&& cursor.moveToFirst()) { final intindex = cursor.getColumnIndexOrThrow(column); returncursor.getString(index); } }finally{ if(cursor !=null) cursor.close(); } return null; } /** *@paramuriThe Uri to check. *@returnWhether the Uri authority is ExternalStorageProvider. */ public static booleanisExternalStorageDocument(Uri uri) { return"com.android.externalstorage.documents".equals(uri.getAuthority()); } /** *@paramuriThe Uri to check. *@returnWhether the Uri authority is DownloadsProvider. */ public static booleanisDownloadsDocument(Uri uri) { return"com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** *@paramuriThe Uri to check. *@returnWhether the Uri authority is MediaProvider. */ public static booleanisMediaDocument(Uri uri) { return"com.android.providers.media.documents".equals(uri.getAuthority()); } /** *@paramuriThe Uri to check. *@returnWhether the Uri authority is Google Photos. */ public static booleanisGooglePhotosUri(Uri uri) { return"com.google.android.apps.photos.content".equals(uri.getAuthority()); } } 就到这里就OK了,关于为什么会出现问题可以度娘,我这里提供相关解决方案,如大家有任何疑问,我的QQ752422962,联系我3.实现拍照和选择相册裁剪的代码