Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

2024-02-27 1956阅读

温馨提示:这篇文章已超过388天没有更新,请注意相关的内容是否还可用!

Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

前言

       在项目研发中,相信大家都遇到过给用户增加头像照片的需求。

       随着手机版本的不断更新,android 8、android 9、android 10、android 12、android 13、鸿蒙系统等等;遇到这个功能需求,大家肯定会想,“这还不好写? 之前就已经写过了。” 把老项目跑了一遍之后发现无法运行。要不大多数就会出现奔溃的情况!

       这也就遇到常见的 高版本适配情况,以及针对不同版本该如何处理?

Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

       碰到这种情况也不要慌张,博主将为大家推出两篇热乎连载篇。从两个不同开发场景下,来给大家分享两篇文章,来更加详细的了解该如何去实现?【特此来记录】

       本篇将为大家详细讲解如何调用摄像头拍照 & 选择相册,并裁剪图片。

效果

实测android 8、android 9、android 11、android 13、鸿蒙系统均有效;

手机机型分别为OPPO、华为、VIVO手机。

对于效果演示,将单独拿出两个来举例:

  • VIVO android 13
  • 华为 鸿蒙系统2.0.1
    vivo华为
    Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

    功能

    1. 动态申请拍照,读,写权限
    2. 自定义弹出框
    3. 调用系统相机拍照

      3.1 调用系统相机申请拍照权限回调

      3.2 拍照完成回调

    4. 自动获取sdk权限

      4.1 访问相册完成回调

    具体实现

    .gradle配置文件:

    Android 拍照以及相册中选择(适配高版本)————上传头像并裁剪(一)

    AndroidManifest文件:

    
    
    
              
    
    

    filepaths.xml文件:

    
        
            
        
        
    
    
    /**
     * @author 拉莫帅
     * @date 2023/4/01
     * @address
     * @Desc TakePicture 上传头像
     */
    public class MainActivity extends BaseActivity implements View.OnClickListener {
        public static String[] permission = {
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA};
        private CircleImg img;
        private View view;
        private String BaseUrl = "";
        private Uri newUri;
        private File outputImage;
        private Uri cropImageUri;
        private File fileCropUri;//裁剪的照片
        private Uri imageUri;//拍照所得到的图像的保存路径
        private static final int OUTPUT_X = 295;
        private static final int OUTPUT_Y = 413;
        private static final int CODE_GALLERY_REQUEST = 0xa0;
        private static final int CODE_CAMERA_REQUEST = 0xa1;
        private static final int CODE_RESULT_REQUEST = 0xa2;
        private static final int REQUESTCODE_CUTTING = 0xa3;
        private static final int CAMERA_PERMISSIONS_REQUEST_CODE = 0x03;
        private static final int STORAGE_PERMISSIONS_REQUEST_CODE = 0x04;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setStatusBg(1);
            AppUtils.requestPermission(permission);
            img = findViewById(R.id.userinfo_iv_head);
            img.setOnClickListener(this);
        }
        @Override
        protected View addContentLayout() {
            view = getLayoutInflater().inflate(R.layout.activity_main, contentLayout, false);
            return view;
        }
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.userinfo_iv_head:
                    select();
                    break;
                case R.id.rl_head_camera:
                    takePhoto();
                    AppUtils.dismiss();
                    break;
                case R.id.rl_head_photo:
                    autoObtainStoragePermission();
                    AppUtils.dismiss();
                    break;
                case R.id.rl_head_cancel:
                    AppUtils.dismiss();
                    break;
            }
        }
        private void select() {        
            AppUtils.selectPhoto(MainActivity.this, R.layout.dialog_head, R.layout.activity_main, this);
        }
        /**
         * 拍照
         *
         * @param
         */
        private void takePhoto() {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
                    || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
                    ToastUtils.showShort(this, "您已经拒绝过一次");
                }
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, CAMERA_PERMISSIONS_REQUEST_CODE);
            } else {//有权限直接调用系统相机拍照
                if (AppUtils.hasSdcard()) {
                        outputImage = new File(Environment.getExternalStorageDirectory().getPath(), System.currentTimeMillis() + ".jpg");
                        //通过FileProvider创建一个content类型的Uri
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            imageUri = FileProvider.getUriForFile(this, "com.harry.takepicture.provider", outputImage);
                        } else {
                            imageUri = Uri.fromFile(outputImage);
                        }
                        PhotoUtils.takePicture(this, imageUri, CODE_CAMERA_REQUEST);             
                } else {
                    ToastUtils.showShort(this, "设备没有SD卡!");
                }
            }
        }
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            switch (requestCode) {
                //调用系统相机申请拍照权限回调
                case CAMERA_PERMISSIONS_REQUEST_CODE: {
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        if (AppUtils.hasSdcard()) {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                                imageUri = FileProvider.getUriForFile(MainActivity.this, "com.harry.takepicture.provider", outputImage);
                            } else {
                                imageUri = Uri.fromFile(outputImage);
                            }
                            
                            PhotoUtils.takePicture(this, imageUri, CODE_CAMERA_REQUEST);                   
                        } else {
                            ToastUtils.showShort(this, "设备没有SD卡!");
                        }
                    } else {
                        ToastUtils.showShort(this, "请允许打开相机!!");
                    }
                    break;
                }
            }
        }
        /**
         * 自动获取sdk权限
         */
        private void autoObtainStoragePermission() {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSIONS_REQUEST_CODE);
            } else {
                PhotoUtils.openPic(this, CODE_GALLERY_REQUEST);
            }
        }
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == RESULT_OK) {
                fileCropUri = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");
                switch (requestCode) {
                    //拍照完成回调
                    case CODE_CAMERA_REQUEST:
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            Uri contentUri = FileProvider.getUriForFile(this, "com.harry.takepicture.provider", outputImage);
                            cropPhoto(contentUri);
                        } else {
                            imageUri = Uri.fromFile(outputImage);
                            cropPhoto(imageUri);
                        }
                    //访问相册完成回调
                    case CODE_GALLERY_REQUEST:
                        if (AppUtils.hasSdcard()) {
                            cropImageUri = Uri.fromFile(fileCropUri);
                            if (data == null) {
                                return;
                            } else {
                                newUri = getUri(data);
                            }
                            PhotoUtils.cropImageUri(this, newUri, cropImageUri, 1, 1, OUTPUT_X, OUTPUT_Y, CODE_RESULT_REQUEST);
                        } else {
                            ToastUtils.showShort(this, "设备没有SD卡!");
                        }
                        break;
                    case REQUESTCODE_CUTTING:
                        if (data != null) {
                            setPicToView(data);
                        }
                        break;
                    case CODE_RESULT_REQUEST:
                        String a = cropImageUri.getPath();
                        Log.e("tb", "a---" + a);
                        Bitmap bitmap = PhotoUtils.getBitmapFromUri(cropImageUri, this);
                        if (bitmap != null) {
                            File file = new File(a);
                            Log.e("tb", "file--------------------------" + file);
                            BaseUrl = Base64Utils.getImageStr(file);
                            Log.e("tb", "BaseUrl--------------------------" + BaseUrl);
                            showImages(bitmap, a);
                        }
                        break;
                    default:
                }
            }
        }
        private void setPicToView(Intent picdata) {
            Bundle extras = picdata.getExtras();
            if (extras != null) {
                // 取得SDCard图片路径做显示
                Bitmap photo = extras.getParcelable("data");
                String saveFile = FileUtil.saveFile(this, "crop", photo);
                if (photo != null) {
                    File file = new File(saveFile);
                    Log.e("tb", "file--------------------------" + file);
                    BaseUrl = Base64Utils.getImageStr(file);
                    Log.e("tb", "BaseUrl--------------------------" + BaseUrl);
                    showImages(photo, saveFile);
                }
            }
        }
    	/**
         * 裁剪
         * 
         * @param uri
         */
        private void cropPhoto(Uri uri) {
            Intent intent = new Intent("com.android.camera.action.CROP");
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intent.setDataAndType(uri, "image/*");
            intent.putExtra("crop", "true");
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1);
            intent.putExtra("outputX", 300);
            intent.putExtra("outputY", 300);
            intent.putExtra("return-data", true);
            Log.e("tag", "intent====" + intent);
            startActivityForResult(intent, REQUESTCODE_CUTTING);
        }
    	/**
         * 展示
         * 
         * @param bitmap
         * @param urlpath
         */
        private void showImages(Bitmap bitmap, String urlpath) {
            Drawable drawable = new BitmapDrawable(null, bitmap);
            Log.e("tag", "urlPath====" + urlpath);
            img.setImageDrawable(drawable);
        }
        /**
         * 解决手机上获取图片路径为null的情况
         *
         * @param intent
         * @return
         */
        public Uri getUri(android.content.Intent intent) {
            Uri uri = intent.getData();
            String type = intent.getType();
            if (uri.getScheme().equals("file") && (type.contains("image/"))) {
                String path = uri.getEncodedPath();
                if (path != null) {
                    path = Uri.decode(path);
                    ContentResolver cr = this.getContentResolver();
                    StringBuffer buff = new StringBuffer();
                    buff.append("(").append(MediaStore.Images.ImageColumns.DATA).append("=")
                            .append("'" + path + "'").append(")");
                    Cursor cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                            new String[]{MediaStore.Images.ImageColumns._ID},
                            buff.toString(), null, null);
                    int index = 0;
                    for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
                        index = cur.getColumnIndex(MediaStore.Images.ImageColumns._ID);
                        // set _id value
                        index = cur.getInt(index);
                    }
                    if (index == 0) {
                        // do nothing
                    } else {
                        Uri uri_temp = Uri
                                .parse("content://media/external/images/media/"
                                        + index);
                        if (uri_temp != null) {
                            uri = uri_temp;
                        }
                    }
                }
            }
            return uri;
        }
    }
    

    总结

           到这里就结束了。看到这里,关于上传头像的具体流程也已经清楚,最主要的代码也已经给大家粘贴了过来。

           完整版源码下载地址:Android + + 数码相机

           感兴趣的小伙伴们,大家赶快去测试一下吧。

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]