适配Android10 拍照,相册,裁剪,上传图片

适配Android10 拍照,相册,裁剪,上传图片,第1张

概述本文主要介绍了适配Android10调用系统相册,系统相机,系统裁剪和对应上传 *** 作

  这篇文章主要介绍了适配AndroID 10(Q)后,调用系统拍照,系统相册,系统裁剪和上传问题,这是一个很常用的功能,但是在AndroID 6.0,AndroID 7.0和AndroID 10.0以上版本的实现都有所不同,这篇文章从AndroID 4适配到AndroID 10。

  之前写毕设的时候,在写上传头像的功能时,参考网上的方法写了一大堆,在我的手机(AndroID 9)上可以正常运行,当时没多想,以为高版本可以向下兼容,后来我把程序发给同学去试验,结果都告诉我上传头像用不了,一问才知道他们用的是AndroID 10的手机,于是只能上网查找原因,然后发现AndroID 10的存储方式发生了变化,AndroID 10的文件系统采用了沙盒文件系统,最显著的变化就是文件系统变安全了,于是app也没办法拿到外部文件的绝对路径了,网上给出的方法就是将共享文件复制到沙盒目录下,然后再进行文件 *** 作。话不多说,上代码。

  demo源码

在文件清单AndroIDManifest.xml中添加权限:

1 <uses-permission androID:name="androID.permission.READ_EXTERNAL_STORAGE" /><!-- 储存卡的读权限 -->2 ="androID.permission.WRITE_EXTERNAL_STORAGE"  储存卡的写权限 3 ="androID.permission.CAMERA"  调用相机权限 -->

在官方7.0的以上的系统中,尝试传递 file://URI可能会触发fileUrIExposedException,使用fileProvIDer来共享文件,AndroIDManifest.xml:

application        ...        <!-- 兼容Android7.0拍照闪退 -->        provIDer            ="androIDx.core.content.fileProvIDer"            androID:authoritIEs="com.example.camera.test"            androID:exported="false"            androID:grantUriPermissions="true">            Meta-data                ="androID.support.file_PROVIDER_PATHS"                androID:resource="@xml/file_paths" />        </provIDer>    application>

在主界面放一个ImageVIEw和两个按钮,activity_main.xml:

<?xml version="1.0" enCoding="utf-8"?>linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    xmlns:tools="http://schemas.androID.com/tools"    androID:layout_wIDth="match_parent"    androID:layout_height    androID:orIEntation="vertical"    tools:context=".MainActivity">    ImageVIEw        androID:ID="@+ID/image"        androID:layout_wIDth="250dp"        androID:layout_height        androID:layout_margintop="20dp"        androID:layout_gravity="center_horizontal"/>    TextVIEw        ="@+ID/tv_camera"="wrap_content"="50dp"        androID:text="相机"        androID:textSize="18sp"        androID:textcolor="#FFF"        androID:padding="10dp"        androID:background="#1878FF"        androID:layout_marginHorizontal        androID:gravity="@+ID/tv_album"="相册"/>linearLayout>

接下来是主页面的代码:

获取控件,对两个按钮添加点击监听,判断权限:

    
    private ImageVIEw image;
private TextVIEw tvCamera,tvAlbum;
    @OverrIDe
protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); init(); } private init(){ image = findVIEwByID(R.ID.image); tvCamera = findVIEwByID(R.ID.tv_camera); tvAlbum = findVIEwByID(R.ID.tv_album); tvCamera.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public onClick(VIEw v) { //相机 if ((ContextCompat.checkSelfPermission(context,Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(context,Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) { 权限都齐的情况下,跳转相机 openCamera(); } else { if (activity != null) { 请求权限 ActivityCompat.requestPermissions(activity, String[]{ Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE },PHOTO_REQUEST_CAMERA); } } } }); tvAlbum.setonClickListener(相册 权限都齐的情况下,跳转相册 openAlbum(); } String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE,PHOTO_REQUEST_ALBUM); } } } }); }

权限申请回调:

    @OverrIDe    voID onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {        .onRequestPermissionsResult(requestCode,permissions,grantResults);        switch (requestCode) {            case PHOTO_REQUEST_CAMERA:                相机权限请求回调                if (grantResults.length > 0) {                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED                            && grantResults[1] == PackageManager.PERMISSION_GRANTED                            && grantResults[2] == PackageManager.PERMISSION_GRANTED) {                        跳转相机                        openCamera();                    }  {                        无权限提示                        Toast.makeText(context,"权限未通过",Toast.LENGTH_SHORT).show();                    }                }                break;             PHOTO_REQUEST_ALBUM:                跳转相册                        openAlbum();                    } ;        }    }

跳转相机:

    private  openCamera(){        Intent intent =  Intent(MediaStore.ACTION_IMAGE_CAPTURE);        判断是否有相机        null && context != null && intent.resolveActivity(activity.getPackageManager()) != ){            file file;            Uri uri =  (isAndroidQ){                适配Android10                uri = createImageUri(context);            }  {                Android10以下                file = createImagefile(context);                if (file != ){                    Android10以下                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){                        适配Android7.0文件权限                        uri = fileProvIDer.getUriForfile(context,"com.example.camera.test" {                        uri = Uri.fromfile(file);                    }                }            }            imageUri = uri;            Log.e(TAG,"相机保存的图片Uri:" + imageUri);            if (uri != ){                intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);                startActivityForResult(intent,CAMERA_REQUEST_CODE);            }        }    }

AndroID 10以上的创建Uri,Uri创建在沙盒内:

contentValues.put(MediaStore.Images.Media.relative_PATH,Environment.DIRECTORY_PICTURES + "/0/");

以上设置的保存路径为:".../包名/files/Pictures/0",可按需更改

用于保存拍照之后的照片:

    private Uri createImageUri(@NonNull Context context){        String status = Environment.getExternalStorageState();        ContentValues contentValues =  ContentValues();        contentValues.put(MediaStore.Images.Media.disPLAY_name,SAVE_AVATAR_name);        contentValues.put(MediaStore.Images.Media.MIME_TYPE,"image/*");        contentValues.put(MediaStore.Images.Media.relative_PATH,Environment.DIRECTORY_PICTURES + "/0/");        判断是否有SD卡         (status.equals(Environment.MEDIA_MOUNTED)){            return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);        }  {             context.getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI,contentValues);        }    }

AndroID 10以下的返回一个file来保存拍照后的图片:

 file createImagefile(@NonNull Context context){        file file = context.getExternalfilesDir(Environment.DIRECTORY_PICTURES);        null && !file.exists()){             (file.mkdir()){                Log.e(TAG,"文件夹创建成功");            }  {                Log.e(TAG,"file为空或者文件夹创建失败");            }        }        file tempfile =  file(file,SAVE_AVATAR_name);        Log.e(TAG,"临时文件路径:" + tempfile.get@R_301_4613@Path());        if (!Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(tempfile))){            return ;        }         tempfile;    }

跳转相册:

 openAlbum(){        Intent intent = new Intent(Intent.ACTION_PICK,1)">);        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,1)">);        startActivityForResult(intent,ALBUM_REQUEST_CODE);    }

跳转裁剪,裁剪在相机拍照后跳转,用一个file来加载:

 openCrop(Uri uri){        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) && context != ){            file = new file(getExternalfilesDir(Environment.DIRECTORY_PICTURES + "/0"),SAVE_AVATAR_name);        }        Intent intent = new Intent("com.androID.camera.action.CROP");        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);        intent.setDataAndType(uri,1)"> 设置裁剪        intent.putExtra("crop","true" aspectX aspectY 是宽高的比例        intent.putExtra("aspectX",1);        intent.putExtra("aspectY",1)"> 裁剪后输出图片的尺寸大小        intent.putExtra("outputX",250);        intent.putExtra("outputY",1)">适配Android10,存放图片路径        intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromfile(file));         图片格式        intent.putExtra("outputFormat","PNG");        intent.putExtra("noFaceDetection",1)">true); 取消人脸识别        intent.putExtra("return-data",1)"> true:不返回uri,false:返回uri        startActivityForResult(intent,TAILOR_REQUEST_CODE);    }

跳转相机、相册和裁剪的回调,如果有上传需求的,直接上传代码中的file即可:

protected voID onActivityResult( resultCode,@Nullable Intent data) {        .onActivityResult(requestCode,resultCode,data);        if (resultCode == -1){            回调成功             (requestCode) {                 CAMERA_REQUEST_CODE:                    相机回调                    Log.e(TAG,"相机回调");                     (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {                        照片裁剪                        openCrop(imageUri);                    }  {                        Toast.makeText(context,"未找到存储卡";                 ALBUM_REQUEST_CODE:                    相册回调                    Log.e(TAG,"相册回调"if (data != null && data.getData() != ) {                        image.setimageURI(data.getData());                        如果需要上传 *** 作的可以使用这个方法                        file file = fileUtils.uriTofile(data.getData(),context);                        这里的file就是需要上传的图片了                    }                     TAILOR_REQUEST_CODE:                    图片剪裁回调                    Log.e(TAG,"图片剪裁回调");                    GlIDe.with(context).load(file).into(image);                    Uri uri = Uri.fromfile(file);                    image.setimageURI(uri);                    如果需要上传全局的这个file就是需要上传的图片了                    file file = this.file;                    ;            }        }  {            Toast.makeText(context,"取消"          总结       

以上是内存溢出为你收集整理的适配Android10 拍照,相册,裁剪,上传图片全部内容,希望文章能够帮你解决适配Android10 拍照,相册,裁剪,上传图片所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1119322.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存