前言
在做上一个项目时深深受到了图片上传的苦恼。图片上传主要分为两个部分,首先要获取图片,而获取图片可以分为从文件获取或者拍照获取。第二个部分才是上传图片,两个部分都是走了不少弯路。由于AndroID系统的碎片化比较严重,我们可能出现在第一台机子上能获取图片,但是换一个机子就不能获取图片的问题,并且在AndroID6.0,7.0之后也要做一定的适配,这样对于开发者来说,无疑很蛋疼。由于也是初学者,很多东西没有考虑到,适配起来也是有点难度的。
这几天也是从github上找到了一个库(地址在这TakePhoto),经过简单的学习之后,发现用起来还是蛮简单的,并且在不同机型之间都能达到同样的效果。更重要的是可以根据不同配置达到不同的效果
接下来看下用法
获取图片
1) 获取TakePhoto对象
一) 通过继承的方式
继承TakePhotoActivity、TakePhotoFragmentActivity、TakePhotoFragment三者之一。
通过getTakePhoto()获取TakePhoto实例进行相关 *** 作。
重写以下方法获取结果
voID takeSuccess(TResult result); voID takeFail(TResult result,String msg); voID takeCancel();
这种方法使用起来虽然简单,但是感觉定制性不高,必须继承指定的Activity,而 有时我们已经封装好了BaseActivity,不想再改了。有时候通过继承无法满足实际项目的需求。
二) 通过组装的方式去使用
实现TakePhoto.TakeResultListener,InvokeListener接口。
在 onCreate,onActivityResult,onSaveInstanceState方法中调用TakePhoto对用的方法。
重写onRequestPermissionsResult(int requestCode,String[] permissions,int[] grantResults),添加如下代码。
@OverrIDe public voID onRequestPermissionsResult(int requestCode,int[] grantResults) { super.onRequestPermissionsResult(requestCode,permissions,grantResults); //以下代码为处理AndroID6.0、7.0动态权限所需 TPermissionType type=PermissionManager.onRequestPermissionsResult(requestCode,grantResults); PermissionManager.handlePermissionsResult(this,type,invokeParam,this); }
重写TPermissionType invoke(InvokeParam invokeParam)方法,添加如下代码:
@OverrIDe public TPermissionType invoke(InvokeParam invokeParam) { TPermissionType type=PermissionManager.checkPermission(TContextwrap.of(this),invokeParam.getmethod()); if(TPermissionType.WAIT.equals(type)){ this.invokeParam=invokeParam; } return type; }
添加如下代码获取TakePhoto实例:
/** * 获取TakePhoto实例 * @return */ public TakePhoto getTakePhoto(){ if (takePhoto==null){ takePhoto= (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this,this)); } return takePhoto; }
2)自定义UI
不仅可以对于参数自定义,也可以对于UI的自定义,比如自定义相册,自定义Toolbar,自定义状态栏,自定义提示文字,自定义裁切工具(需要使用自带的TakePhoto裁剪才行)。
3)通过TakePhoto对象获取图片
支持从相册获取,也支持拍照,相关API
* 从相机获取图片并裁剪 * @param outPutUri 图片裁剪之后保存的路径 * @param options 裁剪配置 */voID onPickFromCaptureWithCrop(Uri outPutUri,CropOptions options);/** * 从相册中获取图片并裁剪 * @param outPutUri 图片裁剪之后保存的路径 * @param options 裁剪配置 */voID onPickFromgalleryWithCrop(Uri outPutUri,CropOptions options);/** * 从文件中获取图片并裁剪 * @param outPutUri 图片裁剪之后保存的路径 * @param options 裁剪配置 */voID onPickFromdocumentsWithCrop(Uri outPutUri,CropOptions options);/** * 图片多选,并裁切 * @param limit 最多选择图片张数的限制 * @param options 裁剪配置 * */voID onPickMultipleWithCrop(int limit,CropOptions options);
4)裁剪配置
CropOptions 用于裁剪的配置类,可以对图片的裁剪比例,最大输出大小,以及是否使用TakePhoto自带的裁剪工具进行裁剪等,进行个性化配置。
压缩图片 onEnableCompress(CompressConfig config,boolean showCompressDialog)
指定压缩工具 takePhoto里面自带压缩算法,也可以通过第三方的Luban进行压缩
对于TakePhoto的二次封装
封装是对第二种方法的封装,主要参考了第一种的思想封装的。
关于TakePhoto的库代码全部封装到一个TakePhotoUtil工具类中,看代码:
public class TakePhotoUtil implements TakePhoto.TakeResultListener,InvokeListener { private static final String TAG = TakePhotoUtil.class.getname(); private TakePhoto takePhoto; private InvokeParam invokeParam; private Activity activity; private Fragment fragment; public TakePhotoUtil(Activity activity){ this.activity = activity; } public TakePhotoUtil(Fragment fragment){ this.fragment = fragment; } /** * 获取TakePhoto实例 * @return */ public TakePhoto getTakePhoto(){ if (takePhoto==null){ takePhoto= (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(activity,this)); } return takePhoto; } public voID onCreate(Bundle savedInstanceState){ getTakePhoto().onCreate(savedInstanceState); } public voID onSaveInstanceState(Bundle outState){ getTakePhoto().onSaveInstanceState(outState); } public voID onActivityResult(int requestCode,int resultCode,Intent data){ getTakePhoto().onActivityResult(requestCode,resultCode,data); } public voID onRequestPermissionsResult(int requestCode,int[] grantResults) { PermissionManager.TPermissionType type=PermissionManager.onRequestPermissionsResult(requestCode,grantResults); PermissionManager.handlePermissionsResult(activity,this); } /** * * @param result */ @OverrIDe public voID takeSuccess(TResult result) { if(Listener != null){ Listener.takeSuccess(result); }// deleteCachePic(); } @OverrIDe public voID takeFail(TResult result,String msg) { if(Listener != null){ Listener.takeFail(result,msg); }// deleteCachePic(); } @OverrIDe public voID takeCancel() { if(Listener != null){ Listener.takeCancel(); } } public voID deleteCachePic(){ file file=new file(Environment.getExternalStorageDirectory(),"/takephoto/"); if(!file.exists()) return; file[] files = file.Listfiles(); for (file f: files) { f.delete(); } } public interface TakePhotoListener{ voID takeSuccess(TResult result); voID takeFail(TResult result,String msg); voID takeCancel(); } public TakePhotoListener Listener; public voID setTakePhotoListener(SimpleTakePhotoListener Listener){ this.Listener = Listener; } public static class SimpleTakePhotoListener implements TakePhotoListener{ @OverrIDe public voID takeSuccess(TResult result) { } @OverrIDe public voID takeFail(TResult result,String msg) { } @OverrIDe public voID takeCancel() { } } @OverrIDe public PermissionManager.TPermissionType invoke(InvokeParam invokeParam) { PermissionManager.TPermissionType type=PermissionManager.checkPermission(TContextwrap.of(activity),invokeParam.getmethod()); if(PermissionManager.TPermissionType.WAIT.equals(type)){ this.invokeParam=invokeParam; } return type; } /** * * @param select_type */ public voID takePhoto(Select_type select_type,SimpleTakePhotoListener Listener){ takePhoto(select_type,null,Listener); } public voID takePhoto(Select_type select_type,PhotoConfigOptions cropOptions,SimpleTakePhotoListener Listener){ if (takePhoto == null){ Toast.makeText(activity,"请先开启照片功能",Toast.LENGTH_SHORT).show(); return; } setTakePhotoListener(Listener); if(cropOptions == null){ cropOptions = new PhotoConfigOptions(); } cropOptions.configCompress(); //压缩配置 cropOptions.configTakePhoto(); //拍照配置 file file=new file(Environment.getExternalStorageDirectory(),"/takephoto/"+System.currentTimeMillis() + ".jpg"); if (!file.getParentfile().exists())file.getParentfile().mkdirs(); Uri imageUri = Uri.fromfile(file); switch (select_type){ case PICK_BY_SELECT: //从相册获取 if(cropOptions.limit > 1){ if(cropOptions.crop == true){ takePhoto.onPickMultipleWithCrop(cropOptions.limit,cropOptions.getCropOptions()); }else { takePhoto.onPickMultiple(cropOptions.limit); } } if(cropOptions.chooseFromfile){ if(cropOptions.crop == true){ takePhoto.onPickFromdocumentsWithCrop(imageUri,cropOptions.getCropOptions()); }else { takePhoto.onPickFromdocuments(); } }else { if(cropOptions.crop == true){ takePhoto.onPickFromgalleryWithCrop(imageUri,cropOptions.getCropOptions()); }else { takePhoto.onPickFromgallery(); } } break; case PICK_BY_TAKE: //拍照获取 if(cropOptions.crop == true){ takePhoto.onPickFromCaptureWithCrop(imageUri,cropOptions.getCropOptions()); }else { takePhoto.onPickFromCapture(imageUri); } break; default: break; } } /** * 图片的裁剪配置选项内部类 */ public class PhotoConfigOptions{ //裁剪配置 private boolean crop = true; //是否裁剪 private boolean withWonCrop = true; //是否采用自带的裁剪工具,默认选取第三方的裁剪工具 private boolean cropSize = true; //尺寸还是比例 //压缩配置 private boolean uSEOwnCompresstool = true; //使用自带的压缩工具 private boolean isCompress = true; //是否压缩 private boolean showProgressbar = true; //显示压缩进度条// private private int maxSize = 102400; //选择图片配置 private boolean uSEOwngallery = true; //选择使用自带的相册 private boolean chooseFromfile = false; //从文件获取图片 private int limit = 1; //选择最多图片的配置,选择多张图片会自动切换到TakePhoto自带相册 //其它配置 private boolean savePic = true; //选择完之后是否保存图片 private boolean correctTool = false; //纠正拍照的照片旋转角度 private int height = 800; private int wIDth = 800; /** * 裁剪相关配置 * @return */ public CropOptions getCropOptions(){ if(crop == false) return null; CropOptions.Builder builder = new CropOptions.Builder(); if(cropSize){ builder.setoutputX(wIDth).setoutputY(height); }else { builder.setAspectX(wIDth).setAspectY(height); } builder.setWithOwnCrop(withWonCrop); //默认采用第三方配置 return builder.create(); } /** * 图片压缩相关配置 */ public voID configCompress(){ if(isCompress == false) { takePhoto.onEnableCompress(null,false); return; } CompressConfig config; if(uSEOwnCompresstool){ config = new CompressConfig.Builder() .setMaxSize(maxSize) .setMaxPixel(wIDth>height?wIDth:height) .enableReserveRaw(savePic) .create(); }else { Lubanoptions options = new Lubanoptions.Builder() .setMaxHeight(height) .setMaxWIDth(maxSize) .create(); config = CompressConfig.ofLuban(options); config.enableReserveRaw(savePic); } takePhoto.onEnableCompress(config,showProgressbar); } public voID configTakePhoto(){ TakePhotoOptions.Builder builder = new TakePhotoOptions.Builder(); if(uSEOwngallery){ builder.setWithOwngallery(true); } if(correctTool){ builder.setCorrectimage(true); } takePhoto.setTakePhotoOptions(builder.create()); } public voID setCrop(boolean crop) { this.crop = crop; } public voID setWithWonCrop(boolean withWonCrop) { this.withWonCrop = withWonCrop; } public voID setCropSize(boolean cropSize) { this.cropSize = cropSize; } public voID setUSEOwnCompresstool(boolean uSEOwnCompresstool) { this.uSEOwnCompresstool = uSEOwnCompresstool; } public voID setCompress(boolean compress) { isCompress = compress; } public voID setShowProgressbar(boolean showProgressbar) { this.showProgressbar = showProgressbar; } public voID setMaxSize(int maxSize) { this.maxSize = maxSize; } public voID setUSEOwngallery(boolean uSEOwngallery) { this.uSEOwngallery = uSEOwngallery; } public voID setChooseFromfile(boolean chooseFromfile) { this.chooseFromfile = chooseFromfile; } public voID setlimit(int limit) { this.limit = limit; } public voID setSavePic(boolean savePic) { this.savePic = savePic; } public voID setCorrectTool(boolean correctTool) { this.correctTool = correctTool; } public voID setHeight(int height) { this.height = height; } public voID setWIDth(int wIDth) { this.wIDth = wIDth; } } /** * 照片获取方式,从相册获取或拍照处理 */ public enum Select_type{ PICK_BY_SELECT,PICK_BY_TAKE }}
封装了一个BaseTakePhotoActivity,里面的代码如下:
protected TakePhotoUtil takePhotoUtil; @OverrIDe protected voID onCreate(@Nullable Bundle savedInstanceState) { takePhotoUtil = new TakePhotoUtil(this); if(useTakePhoto()){ takePhotoUtil.onCreate(savedInstanceState); } super.onCreate(savedInstanceState); } @OverrIDe protected voID onSaveInstanceState(Bundle outState) { if(useTakePhoto()){ takePhotoUtil.onSaveInstanceState(outState); } super.onSaveInstanceState(outState); } @OverrIDe protected voID onActivityResult(int requestCode,Intent data) { if(useTakePhoto()){ takePhotoUtil.onActivityResult(requestCode,data); } super.onActivityResult(requestCode,data); } @OverrIDe public voID onRequestPermissionsResult(int requestCode,int[] grantResults) { if(useTakePhoto()){ takePhotoUtil.onRequestPermissionsResult(requestCode,grantResults); } super.onRequestPermissionsResult(requestCode,grantResults); } protected boolean useTakePhoto(){ return false; }
其他对于业务的封装,可以再封装一个BaseActivity,继承自BaseTakePhotoActivity,这样就可以不影响BaseActivity的使用,如果我们在主Activity中使用获取图片的功能需要两步
1)开启TakePhoto功能
@OverrIDe protected boolean useTakePhoto() { return true; }
2 ) 获取图片
takePhotoUtil.takePhoto(TakePhotoUtil.Select_type.PICK_BY_TAKE,new TakePhotoUtil.SimpleTakePhotoListener(){ @OverrIDe public voID takeSuccess(TResult result) { String s = result.getimage().getCompresspath(); Bitmap bitmap = BitmapFactory.decodefile(s); iv.setimageBitmap(bitmap); } });
takePhoto()的第一个参数是一个枚举类型的参数,分别为从相册获取和拍照获取,第二个参数为获取成功失败监听,有三个回调,由于有些回调不是必须的,所以对Listener做了一个适配,只需要回调想要的方法即可,获取成功之后就可以通过TResult封装的参数获取想要的图片以及图片地址。对于获取到的图片地址就可以做一些上传处理。
图片上传
可以借助okhttp3实现上传功能
Multipartbody.Builder builder = new Multipartbody.Builder().setType(Multipartbody.FORM); Requestbody requestbody = Requestbody.create(MediaType.parse(MulTIPART_FORM_DATA),file); Multipartbody.Part part = Multipartbody.Part.createFormData("dir",file.getname(),requestbody); builder.addPart(part); Request.Builder builder1 = new Request.Builder().url(url).post(builder.build()); Request request = builder1.build(); httpUtils.clIEnt.newCall(request).enqueue(new Callback() { @OverrIDe public voID onFailure(Call call,IOException e) { } @OverrIDe public voID onResponse(Call call,Response response) throws IOException { if(response.isSuccessful()){ final String s = response.body().string(); ((Activity)context).runOnUiThread(new Runnable() { @OverrIDe public voID run() { } }); } } });
大致代码如上
最后
由于当时没有找到这个库,于是跑去问公司另一个做AndroID的,看了下他封装的代码,确实也是值得学习的,他的代码也是适配到了Android7.0,贴下它的代码,方便以后学习:
public class CameraUtil { private static final int REQUEST_CAPTURE_CAMERA = 1221; private static final int REQUEST_CROP = 1222; private static final int REQUEST_OPEN_ALBUM = 1223; private static final String TAG = "Camera"; private static Uri mCacheUri; private CameraUtil() { } @RequiresPermission(allOf = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA}) public static voID getimageFromCamera(Activity activity) { if (checkExternalStorageState(activity)) { activity.startActivityForResult(getimageFromCamera(activity.getApplicationContext()),REQUEST_CAPTURE_CAMERA); } } @RequiresPermission(allOf = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA}) @Deprecated public static voID getimageFromCamera(Fragment fragment) { if (checkExternalStorageState(fragment.getContext())) { fragment.startActivityForResult(getimageFromCamera(fragment.getContext()),REQUEST_CAPTURE_CAMERA); } } private static Intent getimageFromCamera(Context context) { Intent getimageByCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); mCacheUri = getCachePhotoUri(context.getApplicationContext()); getimageByCamera.putExtra(MediaStore.EXTRA_OUTPUT,mCacheUri); getimageByCamera.putExtra("outputFormat",Bitmap.CompressFormat.JPEG.toString()); grantUriPermission(context,getimageByCamera,mCacheUri); return getimageByCamera; } private static boolean checkExternalStorageState(Context context) { if (TextUtils.equals(Environment.getExternalStorageState(),Environment.MEDIA_MOUNTED)) { return true; } Toast.makeText(context.getApplicationContext(),"请确认已经插入SD卡",Toast.LENGTH_LONG).show(); return false; } @SuppressWarnings("ResultOfMethodCallignored") public static file getCachePhotofile() { file file = new file(Environment.getExternalStorageDirectory(),"/lenso/cache/CameraTakePhoto" + System.currentTimeMillis() + ".jpg"); if (!file.getParentfile().exists()) file.getParentfile().mkdirs(); return file; } private static Uri getCachePhotoUri(Context context) { return fileProvIDer.getUriForfile(context,getAuthority(context),getCachePhotofile()); } private static Uri getCachePhotoUri(Context context,file file) { return fileProvIDer.getUriForfile(context,file); } public static voID onActivityResult(Activity activity,int requestCode,Intent data,OnActivityResultListener Listener) { onActivityResult(activity,requestCode,data,Listener); } /** * getCachePhotofile().getParentfile().getabsolutePath() * @param dir * @return */ public static boolean deleteDir(file dir) { if (dir != null && dir.isDirectory()) { String[] children = dir.List(); for (int i = 0; i < children.length; i++) { boolean success = deleteDir(new file(dir,children[i])); if (!success) { return false; } } } return dir.delete(); } public static file saveBitmap(Bitmap bitmap) { file file = getCachePhotofile(); if (bitmap == null || bitmap.isRecycled()) return file; fileOutputStream outputStream = null; try { outputStream = new fileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG,100,outputStream); } catch (fileNotFoundException e) { e.printstacktrace(); } finally { if (outputStream != null) try { outputStream.close(); } catch (IOException e) { e.printstacktrace(); } bitmap.recycle(); } return file; } public static voID copy(file file,file point) { if (!file.exists()) return; if (!point.getParentfile().exists()) point.getParentfile().mkdirs(); BufferedinputStream inputStream = null; bufferedoutputstream outputStream = null; try { inputStream = new BufferedinputStream(new fileinputStream(file)); outputStream = new bufferedoutputstream(new fileOutputStream(point)); byte[] buff = new byte[1024 * 1024 * 2]; int len; while ((len = inputStream.read(buff)) != -1) { outputStream.write(buff,len); outputStream.flush(); } } catch (fileNotFoundException e) { e.printstacktrace(); } catch (IOException e) { e.printstacktrace(); } finally { closeStream(inputStream); closeStream(outputStream); } } private static voID closeStream(Closeable closeable) { if (closeable != null) try { closeable.close(); } catch (IOException e) { e.printstacktrace(); } } public static voID onActivityResult(Activity activity,CropOption crop,OnActivityResultListener Listener) { if (resultCode == Activity.RESulT_CANCELED) return; Uri uri; switch (requestCode) { case REQUEST_OPEN_ALBUM: uri = data.getData(); if (uri != null) { mCacheUri = getCachePhotoUri(activity); copy(new file(getRealfilePath(activity,uri)),new file(getRealfilePath(activity,mCacheUri))); } else { Bitmap bitmap = data.getParcelableExtra("data"); file file = saveBitmap(bitmap); mCacheUri = getCachePhotoUri(activity,file); } case REQUEST_CAPTURE_CAMERA: uri = mCacheUri; if (Listener != null) { Listener.requestCaptureCamera(getRealfilePath(activity,uri),null); } if (crop == null) return; crop.setSource(uri); Intent intent = crop.create(); grantUriPermission(activity,intent,crop.getoutput()); activity.startActivityForResult(intent,REQUEST_CROP); break; case REQUEST_CROP: if (Listener != null && data != null) { Listener.requestCrop(getRealfilePath(activity,mCacheUri),(Bitmap) data.getParcelableExtra("data")); } break; } } @RequiresPermission(allOf = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}) public static voID getimageFromAlbum(Activity activity) { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*");//相片类型 activity.startActivityForResult(intent,REQUEST_OPEN_ALBUM); } @RequiresPermission(allOf = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}) @Deprecated public static voID getimageFromAlbum(Fragment fragment) { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*");//相片类型 fragment.startActivityForResult(intent,REQUEST_OPEN_ALBUM); } public interface OnActivityResultListener { voID requestCaptureCamera(String path,Bitmap bitmap); voID requestCrop(String path,Bitmap bitmap); } /** * Try to return the absolute file path from the given Uri * * @param context context * @param uri uri * @return the file path or null */ public static String getRealfilePath(final Context context,final Uri uri) { if (null == uri) return null; String path = uri.toString(); if (path.startsWith("content://" + getAuthority(context) + "/rc_external_path")) { return path.replace("content://" + getAuthority(context) + "/rc_external_path",Environment.getExternalStorageDirectory().getabsolutePath()); } final String scheme = uri.getScheme(); String data = null; if (scheme == null) data = uri.getPath(); else if (ContentResolver.SCHEME_file.equals(scheme)) { data = uri.getPath(); } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) { Cursor cursor = context.getContentResolver().query(uri,new String[]{MediaStore.Images.ImageColumns.DATA},null); if (null != cursor) { if (cursor.movetoFirst()) { int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); if (index > -1) { data = cursor.getString(index); } } cursor.close(); } } return data; } private static String getAuthority(Context context) { return context.getPackagename() + ".fileProvIDer"; } public static class CropOption { private int aspectX=1;//x比例 private int aspectY=1;//y比例 private boolean returnData = false;//是返回bitmap,否返回uri private String outputFormat;//输出流保存格式JPG PNG ... private int outputX=200;//返回的bitmap宽 private int outputY=200;//返回的bitmap高 private Uri output;//输出流保存路径 private Uri source;//需要截图的图片uri private boolean noFaceDetection = true;//是否关闭人脸识别功能// get和set方法省略 private Intent create() { if (source == null) throw new NullPointerException("没有设置图片uri"); Intent intent = new Intent("com.androID.camera.action.CROP"); intent.setDataAndType(source,"image/*"); intent.putExtra("crop","true"); if (aspectX > 0) intent.putExtra("aspectX",aspectX); if (aspectY > 0) intent.putExtra("aspectY",aspectY); if (outputX > 0) intent.putExtra("outputX",outputX); if (outputY > 0) intent.putExtra("outputY",outputY); intent.putExtra("return-data",returnData); if (!returnData) { output = output == null ? source : output; outputFormat = outputFormat == null ? Bitmap.CompressFormat.JPEG.toString() : outputFormat; intent.putExtra(MediaStore.EXTRA_OUTPUT,output); intent.putExtra("outputFormat",outputFormat); intent.setType("image/*"); intent.putExtra("noFaceDetection",noFaceDetection); } return intent; } } private static voID grantUriPermission(Context context,Intent intent,Uri uri) { List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivitIEs(intent,PackageManager.MATCH_DEFAulT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packagename = resolveInfo.activityInfo.packagename; context.grantUriPermission(packagename,uri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); } }}//xml文件部分<?xml version="1.0" enCoding="utf-8"?><resources > <paths> <external-path path="" name="rc_external_path" /> </paths></resources>//清单文件注册部分<provIDer androID:name="androID.support.v4.content.fileProvIDer" androID:authoritIEs="com.lenso.fileProvIDer" androID:exported="false" androID:grantUriPermissions="true"> <Meta-data androID:name="androID.support.file_PROVIDER_PATHS" androID:resource="@xml/file_path" /></provIDer>
也封装了从本地获取,以及拍照获取的相关功能,可以值得学习,毕竟不少坑。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android获取照片、裁剪图片、压缩图片全部内容,希望文章能够帮你解决Android获取照片、裁剪图片、压缩图片所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)