前⾔
在做上⼀个项⽬时深深受到了图⽚上传的苦恼。图⽚上传主要分为两个部分,⾸先要获取图⽚,⽽获取图⽚可以分为从⽂件获取或者拍照获取。第⼆个部分才是上传图⽚,两个部分都是⾛了不少弯路。由于Android系统的碎⽚化⽐较严重,我们可能出现在第⼀台机⼦上能获取图⽚,但是换⼀个机⼦就不能获取图⽚的问题,并且在Android6.0,7.0之后也要做⼀定的适配,这样对于开发者来说,⽆疑很蛋疼。由于也是初学者,很多东西没有考虑到,适配起来也是有点难度的。
这⼏天也是从github上找到了⼀个库(地址在这),经过简单的学习之后,发现⽤起来还是蛮简单的,并且在不同机型之间都能达到同样的效果。更重要的是可以根据不同配置达到不同的效果接下来看下⽤法获取图⽚
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, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); //以下代码为处理Android6.0、7.0动态权限所需
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实例:
/**
* 获取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, 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, \"请先开启照⽚功能\ 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, 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; }
其他对于业务的封装,可以再封装⼀个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\ 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.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\ 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卡\ 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\ }
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;//是否关闭⼈脸识别功能// 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\ if (aspectX > 0)
intent.putExtra(\"aspectX\ if (aspectY > 0)
intent.putExtra(\"aspectY\ if (outputX > 0)
intent.putExtra(\"outputX\ if (outputY > 0)
intent.putExtra(\"outputY\ intent.putExtra(\"return-data\ if (!returnData) {
output = output == null ? source : output;
outputFormat = outputFormat == null ? Bitmap.CompressFormat.JPEG.toString() : outputFormat; intent.putExtra(MediaStore.EXTRA_OUTPUT, output); intent.putExtra(\"outputFormat\ intent.setType(\"image/*\");
intent.putExtra(\"noFaceDetection\ }
return intent; } }
private static void grantUriPermission(Context context, Intent intent, Uri uri) {
List String packageName = resolveInfo.activityInfo.packageName; context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); } }} //xml⽂件部分 //清单⽂件注册部分 android:grantUriPermissions=\"true\"> 也封装了从本地获取,以及拍照获取的相关功能,可以值得学习,毕竟不少坑。以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- efsc.cn 版权所有 赣ICP备2024042792号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务