当前位置: 首页 > article >正文

Android——从相机/相册获取图片

从相机获取图片

  • 设置权限
    <uses-permission android:name="android.permission.CAMERA" />
  • 点击跳转
    private static final int REQUEST_CODE_TAKE = 1;
    public void takePhoto(View view) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            doTake();
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_TAKE);
        }
    }
  • 权限结果回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_TAKE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                doTake();
            } else {
                Toast.makeText(this, "你没有获得摄像头权限", Toast.LENGTH_SHORT).show();
            }
        }
    }
        register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result != null) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    try {
                        InputStream inputStream = getContentResolver().openInputStream(imageUri);
                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                        // 转成Base64字符串 方便上传到服务器
                        imageBase64 = ImageUtil.imageToBase64(bitmap);
                        ivAvatar.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
  • 在 onCreate 中注册 Activity 返回结果回调
    private void doTake() {
        File imageTemp = new File(getExternalCacheDir(), "imageOut.jpeg");
        if (imageTemp.exists()) {
            imageTemp.delete();
        }

        try {
            imageTemp.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

        imageUri = Uri.fromFile(imageTemp);
        if (Build.VERSION.SDK_INT > 24) {
            imageUri = FileProvider.getUriForFile(this, "com.example.study_android.fileprovider", imageTemp);
        }
        Intent intent = new Intent();
        intent.setAction("android.media.action.IMAGE_CAPTURE");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        register.launch(intent);
    }
  • 设置provider
        <provider
            android:authorities="com.example.study_android.fileprovider"
            android:name="androidx.core.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/files"/>
        </provider>
  • @xml/files
	<paths xmlns:android="http://schemas.android.com/apk/res/android">
	<external-path
	    name="image_path"
	    path="/"/>
	</paths>

从相册获取图片

  • 设置权限
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • 打开相册(需判断权限)
    public void choosePhoto(View view) {
        // 权限WRITE_EXTERNAL_STORAGE表示同时授予程序对SD卡读和写的能力。
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            openAlbum();
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_CHOOSE);
        }
    }

    private void openAlbum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        registerAlbum.launch(intent);
    }
  • 注册相册返回结果回调
        registerAlbum = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result != null) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Intent intent = result.getData();

                    if (Build.VERSION.SDK_INT < 19) {
                        handleImageBeforeApi19(intent);
                    } else {
                        handleImageOnApi19(intent);
                    }
                }
            }
        });
    private void handleImageBeforeApi19(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri, null);
        displayImage(imagePath);
    }
    /*
     * 因为Android系统从4.4版本开始,选取相册中的图片不再返回图片真实的Uri了,而是一个封装过的Uri
     * 因此如果是4.4版本以上的手机就需要对这个Uri进行解析才行
     * */
    @TargetApi(19)
    private void handleImageOnApi19(Intent data) {
        String imagePath = null;
        Uri uri = data.getData();

        if (DocumentsContract.isDocumentUri(this, uri)) {
            // 如果是document类型的Uri,则通过document id处理
            String documentId = DocumentsContract.getDocumentId(uri);

            if (TextUtils.equals(uri.getAuthority(), "com.android.providers.media.documents")) {
                String id = documentId.split(":")[1];
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);

            } else if (TextUtils.equals(uri.getAuthority(), "com.android.providers.downloads.documents")) {
                if (documentId != null && documentId.startsWith("msf:")) {
                    resolveMSFContent(uri);
                    return;
                }
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
                imagePath = getImagePath(contentUri, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // 如果是content类型的Uri,则使用普通方式处理
            imagePath = getImagePath(uri, null);
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            // 如果是file类型的Uri,直接获取图片路径
            imagePath = uri.getPath();
        }
        displayImage(imagePath);
    }
    private void resolveMSFContent(Uri uri) {
        File file = new File(getCacheDir(), "temp_file" + getContentResolver().getType(uri).split("/")[1]);
        try {
            InputStream inputStream = getContentResolver().openInputStream(uri);
            OutputStream outputStream = new FileOutputStream(file);
            byte[] buffer = new byte[4 * 1024];
            int read;
            while ((read = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, read);
            }
            outputStream.flush();
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
            ivAvatar.setImageBitmap(bitmap);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 获取图片真实路径
    @SuppressLint("Range")
    private String getImagePath(Uri uri, String selection) {
        String path = null;
        // 通过Uri和selection来获取真实的图片路径
        Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

案例代码


http://www.kler.cn/a/383370.html

相关文章:

  • 项目代码第6讲:UpdownController.cs;理解 工艺/工序 流程、机台信息;前端的“历史 警报/工艺 记录”
  • Vue2四、 scoped样式冲突,data是一个函数,组件通信-父传子-子传父-非父子
  • 路由器的原理
  • Spark-Streaming容错语义
  • leetcode-128.最长连续序列-day14
  • UVM 验证方法学之interface学习系列文章(十二)virtual interface 终结篇
  • 无人机避障——大疆与Airsim中的角速度信息订阅获取
  • [免费]SpringBoot+Vue(高校)学籍管理系统【论文+源码+SQL脚本】
  • 【原创】java+ssm+mysql收纳培训网系统设计与实现
  • 【Ajax】跨域
  • StarRocks 在 Shopee 数据产品的实践
  • 应用链风口下,一键发链该如何选择?
  • 数据结构模拟题[十]
  • Java项目实战II基于Java+Spring Boot+MySQL的智能推荐的卫生健康系统(开发文档+数据库+源码)
  • 编译google protobuf项目,生成相应语言的dll文件
  • React中类组件和函数组件的理解和区别
  • 微信小程序 uniapp+vue老年人身体监测系统 acyux
  • 域名申请网站需要了解的事项
  • springbootHR Nexus人力资源管理系统-计算机毕业设计源码23519
  • 背包九讲——背包问题求方案数
  • ssm032基于Java的汽车客运站管理系统的设计与实现+jsp(论文+源码)_kaic
  • 企业微信会话存档引用com.tencent.wework.Finance出错?
  • 新书速览|Java网络爬虫精解与实践
  • linux firewall 常用命令汇总
  • Android studio中关于printf和print和println的区别
  • 动态规划 之 路径问题 算法专题