前言
站在用戶的角度思考問題,與客戶深入溝通,找到韓城網(wǎng)站設(shè)計(jì)與韓城網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都做網(wǎng)站、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名與空間、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋韓城地區(qū)。
在做上一個(gè)項(xiàng)目時(shí)深深受到了圖片上傳的苦惱。圖片上傳主要分為兩個(gè)部分,首先要獲取圖片,而獲取圖片可以分為從文件獲取或者拍照獲取。第二個(gè)部分才是上傳圖片,兩個(gè)部分都是走了不少彎路。由于Android系統(tǒng)的碎片化比較嚴(yán)重,我們可能出現(xiàn)在第一臺(tái)機(jī)子上能獲取圖片,但是換一個(gè)機(jī)子就不能獲取圖片的問題,并且在Android6.0,7.0之后也要做一定的適配,這樣對(duì)于開發(fā)者來說,無疑很蛋疼。由于也是初學(xué)者,很多東西沒有考慮到,適配起來也是有點(diǎn)難度的。
這幾天也是從github上找到了一個(gè)庫(地址在這TakePhoto),經(jīng)過簡(jiǎn)單的學(xué)習(xí)之后,發(fā)現(xiàn)用起來還是蠻簡(jiǎn)單的,并且在不同機(jī)型之間都能達(dá)到同樣的效果。更重要的是可以根據(jù)不同配置達(dá)到不同的效果
接下來看下用法
獲取圖片
1) 獲取TakePhoto對(duì)象
一) 通過繼承的方式
繼承TakePhotoActivity、TakePhotoFragmentActivity、TakePhotoFragment三者之一。
通過getTakePhoto()獲取TakePhoto實(shí)例進(jìn)行相關(guān)操作。
重寫以下方法獲取結(jié)果
void takeSuccess(TResult result); void takeFail(TResult result,String msg); void takeCancel();
這種方法使用起來雖然簡(jiǎn)單,但是感覺定制性不高,必須繼承指定的Activity,而 有時(shí)我們已經(jīng)封裝好了BaseActivity,不想再改了。有時(shí)候通過繼承無法滿足實(shí)際項(xiàng)目的需求。
二) 通過組裝的方式去使用
實(shí)現(xiàn)TakePhoto.TakeResultListener,InvokeListener接口。
在 onCreate,onActivityResult,onSaveInstanceState方法中調(diào)用TakePhoto對(duì)用的方法。
重寫onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults),添加如下代碼。
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); //以下代碼為處理Android6.0、7.0動(dòng)態(tài)權(quán)限所需 TPermissionType type=PermissionManager.onRequestPermissionsResult(requestCode,permissions,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實(shí)例:
/** * 獲取TakePhoto實(shí)例 * @return */ public TakePhoto getTakePhoto(){ if (takePhoto==null){ takePhoto= (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this,this)); } return takePhoto; }
2)自定義UI
不僅可以對(duì)于參數(shù)自定義,也可以對(duì)于UI的自定義,比如自定義相冊(cè),自定義Toolbar, 自定義狀態(tài)欄,自定義提示文字,自定義裁切工具(需要使用自帶的TakePhoto裁剪才行)。
3)通過TakePhoto對(duì)象獲取圖片
支持從相冊(cè)獲取,也支持拍照,相關(guān)Api
* 從相機(jī)獲取圖片并裁剪 * @param outPutUri 圖片裁剪之后保存的路徑 * @param options 裁剪配置 */ void onPickFromCaptureWithCrop(Uri outPutUri, CropOptions options); /** * 從相冊(cè)中獲取圖片并裁剪 * @param outPutUri 圖片裁剪之后保存的路徑 * @param options 裁剪配置 */ void onPickFromGalleryWithCrop(Uri outPutUri, CropOptions options); /** * 從文件中獲取圖片并裁剪 * @param outPutUri 圖片裁剪之后保存的路徑 * @param options 裁剪配置 */ void onPickFromDocumentsWithCrop(Uri outPutUri, CropOptions options); /** * 圖片多選,并裁切 * @param limit 最多選擇圖片張數(shù)的限制 * @param options 裁剪配置 * */ void onPickMultipleWithCrop(int limit, CropOptions options);
4)裁剪配置
CropOptions 用于裁剪的配置類,可以對(duì)圖片的裁剪比例,最大輸出大小,以及是否使用TakePhoto自帶的裁剪工具進(jìn)行裁剪等,進(jìn)行個(gè)性化配置。
壓縮圖片onEnableCompress(CompressConfig config,boolean showCompressDialog)
指定壓縮工具 takePhoto里面自帶壓縮算法,也可以通過第三方的Luban進(jìn)行壓縮
對(duì)于TakePhoto的二次封裝
封裝是對(duì)第二種方法的封裝,主要參考了第一種的思想封裝的。
關(guān)于TakePhoto的庫代碼全部封裝到一個(gè)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實(shí)例 * @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, String[] permissions, int[] grantResults) { PermissionManager.TPermissionType type=PermissionManager.onRequestPermissionsResult(requestCode,permissions,grantResults); PermissionManager.handlePermissionsResult(activity,type,invokeParam,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, "請(qǐng)先開啟照片功能", 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: //從相冊(cè)獲取 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; } } /** * 圖片的裁剪配置選項(xiàng)內(nèi)部類 */ public class PhotoConfigOptions{ //裁剪配置 private boolean crop = true; //是否裁剪 private boolean withWonCrop = true; //是否采用自帶的裁剪工具,默認(rèn)選取第三方的裁剪工具 private boolean cropSize = true; //尺寸還是比例 //壓縮配置 private boolean useOwnCompressTool = true; //使用自帶的壓縮工具 private boolean isCompress = true; //是否壓縮 private boolean showProgressBar = true; //顯示壓縮進(jìn)度條 // private private int maxSize = 102400; //選擇圖片配置 private boolean useOwnGallery = true; //選擇使用自帶的相冊(cè) private boolean chooseFromFile = false; //從文件獲取圖片 private int limit = 1; //選擇最多圖片的配置,選擇多張圖片會(huì)自動(dòng)切換到TakePhoto自帶相冊(cè) //其它配置 private boolean savePic = true; //選擇完之后是否保存圖片 private boolean correctTool = false; //糾正拍照的照片旋轉(zhuǎn)角度 private int height = 800; private int width = 800; /** * 裁剪相關(guān)配置 * @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); //默認(rèn)采用第三方配置 return builder.create(); } /** * 圖片壓縮相關(guān)配置 */ 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; } } /** * 照片獲取方式, 從相冊(cè)獲取或拍照處理 */ public enum Select_type{ PICK_BY_SELECT, PICK_BY_TAKE } }
封裝了一個(gè)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, int resultCode, Intent data) { if(useTakePhoto()){ takePhotoUtil.onActivityResult(requestCode, resultCode, data); } super.onActivityResult(requestCode, resultCode, data); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if(useTakePhoto()){ takePhotoUtil.onRequestPermissionsResult(requestCode, permissions, grantResults); } super.onRequestPermissionsResult(requestCode, permissions, grantResults); } protected boolean useTakePhoto(){ return false; }
其他對(duì)于業(yè)務(wù)的封裝,可以再封裝一個(gè)BaseActivity,繼承自BaseTakePhotoActivity,這樣就可以不影響B(tài)aseActivity的使用,如果我們?cè)谥鰽ctivity中使用獲取圖片的功能需要兩步
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()的第一個(gè)參數(shù)是一個(gè)枚舉類型的參數(shù),分別為從相冊(cè)獲取和拍照獲取,第二個(gè)參數(shù)為獲取成功失敗監(jiān)聽,有三個(gè)回調(diào),由于有些回調(diào)不是必須的,所以對(duì)Listener做了一個(gè)適配,只需要回調(diào)想要的方法即可,獲取成功之后就可以通過TResult封裝的參數(shù)獲取想要的圖片以及圖片地址。對(duì)于獲取到的圖片地址就可以做一些上傳處理。
圖片上傳
可以借助okhttp3實(shí)現(xiàn)上傳功能
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() { } }); } } });
大致代碼如上
最后
由于當(dāng)時(shí)沒有找到這個(gè)庫,于是跑去問公司另一個(gè)做Android的,看了下他封裝的代碼,確實(shí)也是值得學(xué)習(xí)的,他的代碼也是適配到了Android7.0,貼下它的代碼,方便以后學(xué)習(xí):
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.WRITE_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(), "請(qǐng)確認(rèn)已經(jīng)插入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, getAuthority(context), file); } public static void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data, OnActivityResultListener listener) { onActivityResult(activity, null, requestCode, resultCode, 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, 0, 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, int requestCode, int resultCode, Intent data, 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, null, 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;//是否關(guān)閉人臉識(shí)別功能 // get和set方法省略 private Intent create() { if (source == null) throw new NullPointerException("沒有設(shè)置圖片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) { ListresInfoList = 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"?> //清單文件注冊(cè)部分
也封裝了從本地獲取,以及拍照獲取的相關(guān)功能,可以值得學(xué)習(xí),畢竟不少坑。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。