`

关于调用手机图库选择图片的问题

阅读更多

  前段时间学习了《第一行代码》的书,然后照着写了一遍调用手机图库的方法,发现怎么也不成功,于是查阅资料和查看作者郭霖的博客后,发现了android在API19以前和之后的方式不一样,特此进行记载。方便日后的学习。

 

一、活动中选择相机和图片的处理方法

 

/**
     * 实现了点击事件监听器的自定义按钮点击类,用于监听按钮点击的事件
     */
    class OnButtonListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                // 点击的选择图片
                case R.id.btn_selpic:
                    doSelpic();
                    break;
                // 点击的拍照
                case R.id.btn_takeaphoto:
                    doTakeaphoto();
                    break;
                default:
                    break;
            }
        }

        /**
         * 点击选择图片按钮后执行的代码
         */
        private void doSelpic() {
            // 获取设备的根目录
            File sdDir = Environment.getExternalStorageDirectory();
            // 创建缓存目录
            File cacheDir = new File(sdDir, "UPhotocache");
            // 如果不存在目录,则创建
            if (!cacheDir.exists()) {
                cacheDir.mkdir();
            }
            // 创建File对象,用于存储牌照后的图片
            outputImage = new File(cacheDir, "output_image.jpg");
            try {
                // 如果存在则删除
                if (outputImage.exists()) {
                    outputImage.delete();
                }
                // 创建一个新的文件
                outputImage.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 启动选择图片的活动
            imageUri = Uri.fromFile(outputImage);
            Intent intent = new Intent("android.intent.action.GET_CONTENT");
            intent.setType("image/*");
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            startActivityForResult(intent, CHOOSE_FROM_ALBUM);
        }

        /**
         * 点击拍照按钮后执行的代码
         */
        private void doTakeaphoto() {
            // 获取设备的根目录
            File sdDir = Environment.getExternalStorageDirectory();
            // 创建缓存目录
            File cacheDir = new File(sdDir, "UPhotocache");
            // 如果不存在目录,则创建
            if (!cacheDir.exists()) {
                cacheDir.mkdir();
            }
            // 创建File对象,用于存储牌照后的图片
            outputImage = new File(cacheDir, "output_image.jpg");
            try {
                // 如果存在则删除
                if (outputImage.exists()) {
                    outputImage.delete();
                }
                // 创建一个新的文件
                outputImage.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            imageUri = Uri.fromFile(outputImage);
            // 更新保存的路径
            imageSelPath = outputImage.getAbsolutePath();
            // 启动拍照程序
            Intent takeIntent = new Intent("android.media.action.IMAGE_CAPTURE");
            takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            // 设置回传的请求码
            startActivityForResult(takeIntent, TAKE_PHOTO);
        }

    }

 

 

二、回传结果后调用的方法逻辑代码

 

/**
     * 当选择的活动回传数据的时候调用
     *
     * @param requestCode 请求码
     * @param resultCode  结果码
     * @param data        数据
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 根据请求码处理不同的返回结果
        switch (requestCode) {
            case TAKE_PHOTO:
                // 当拍照程序返回结果为正确的时候
                if (resultCode == RESULT_OK) {
                    // 调用剪裁程序活动
                    Intent intent = new Intent("com.android.camera.action.CROP");
                    intent.setDataAndType(imageUri, "image/*");
                    intent.putExtra("scale", true);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                    startActivityForResult(intent, CROP_PHOTO);
                }
                break;
            case CHOOSE_FROM_ALBUM:
                // 当选择照片正确返回的时候
                if (resultCode == RESULT_OK) {
                    //判断手机系统的版本号
                    if (Build.VERSION.SDK_INT >= 19) {
                        handleImageOnKitKat(data);
                    } else {
                        handleImageBeforeKitkat(data);
                    }
                }
                break;
            case CROP_PHOTO:
                // 当剪裁程序返回的结果是正确的时候
                if (resultCode == RESULT_OK) {
                    // 将剪裁后的图片的路径传递给编辑图片的活动
                    Intent editIntent = new Intent(this, EditPicActivity.class);
                    editIntent.putExtra("EDIT_PIC", imageSelPath);
                    startActivity(editIntent);
                }
                break;
            default:
                break;
        }
    }

 

 

三、判断版本不同进行的图片选择代码

 /**
     * 当系统为4.4以上版本的时候,必须以以下方式才可以读取图片
     *
     * @param data 回传的intent对象
     */
    @TargetApi(19)
    private void handleImageOnKitKat(Intent data) {
        String imagePath = null;
        Uri uri = data.getData();
        imageUri = uri;
        if (DocumentsContract.isDocumentUri(this, uri)) {
            LogUtil.d("YYW", "获得了图片的Uri信息");
            // 如果文档类型是uri,则通过document id 处理
            String docId = DocumentsContract.getDocumentId(uri);
            if ("com.android.providers.media.documents".equals(uri
                    .getAuthority())) {
                String id = docId.split(":")[1];
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
                LogUtil.d("YYW", "com.android.providers.media.documents");
            } else if ("com.android.providers.downloads.documents".equals(uri
                    .getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(docId));
                imagePath = getImagePath(contentUri, null);
                LogUtil.d("YYW", "com.android.providers.downloads.documents");
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // 如果不是document类型的Uri,则使用普通方式处理
            imagePath = getImagePath(uri, null);
            LogUtil.d("YYW", "content");
        } else {
            LogUtil.d("YYW", "未知类型");
        }
        imageSelPath = imagePath;
        displayImage(imageSelPath);
    }

    /**
     * 当系统为4.4以下的时候必须以以下方式读取图片
     *
     * @param data 回传的intent对象
     */
    private void handleImageBeforeKitkat(Intent data) {
        Uri uri = data.getData();
        imageUri = uri;
        imageSelPath = getImagePath(uri, null);
        displayImage(imageSelPath);
    }

    /**
     * 获得选择的图片的真实路径
     *
     * @param uri       图片的标识符
     * @param selection 选择的选项,可为空
     * @return 选择的图片的真实路径
     */
    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;
    }

    /**
     * 将图片传递给编辑活动的方法
     *
     * @param imagePath 图片路径
     */
    private void displayImage(String imagePath) {
        if (imagePath != null) {
            Intent intent = new Intent("com.android.camera.action.CROP");
            intent.setDataAndType(imageUri, "image/*");
            intent.putExtra("scale", true);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            startActivityForResult(intent, CROP_PHOTO);
        } else {
            ToastUtil.show(this, R.string.fail_get_image);
        }
    }

 

注意:

    由于我需要实现的功能为:通过拍照或者选择图片后将其传递到另一个活动(EditPicActivity),所以可能与书本有所差异。读者切勿直接拷贝。应在理解的基础上进行代码编写。

 

分享到:
评论

相关推荐

    webview不能调用手机文件选择、相机和图库的问题demo

    然而,在实际使用过程中,开发者时常会遇到WebView无法调用手机上的文件选择器、相机以及图库功能的问题。这些问题通常涉及到Android权限管理、安全性和API兼容性等问题。本文将深入探讨这些问题,并提供解决方案。 ...

    h5app拍照或者图库选择图片限制图片数量demo

    【描述】"h5+规范做的app demo 用户拍照或者图库选择图片 并且限制图片数量 请在手机上测试"表明这是一个遵循H5+规范的示例应用,它允许用户既可以通过手机摄像头拍照,也可以从设备的相册中选择图片。关键特性是该...

    webview 调用手机相机和图库demo(亲测好用)

    webview 调用手机相机和图库demo(亲测好用) webview.setWebChromeClient(new WebChromeClient() public boolean onShowFileChooser (WebView webView, ValueCallback[]> uploadMsg, FileChooserParams ...

    phoneGap-android实现拍照和选择图库

    在Android平台上,PhoneGap提供了一个便捷的方式来整合设备的功能,比如摄像头和图库,使得Web开发者能够轻松地实现拍照和选择图库图片的操作。 1. PhoneGap基础: PhoneGap的核心是Cordova,一个开源的移动设备...

    android调用相机或图库获取图片

    以上就是在Android应用中调用相机和图库获取图片的基本步骤。在实际开发中,你可能还需要考虑兼容不同Android版本、图片的大小限制、用户隐私政策等问题,确保应用的稳定性和用户体验。记得在使用用户照片时,要遵循...

    mui调用手机摄像头及多文件上传.zip

    本教程将详细讲解如何使用 `mui` 实现调用手机摄像头及多文件上传功能,并支持图片的删除操作。 首先,`mui` 提供了丰富的组件和API,使得开发者可以便捷地实现与原生设备功能的交互。在调用摄像头和图库方面,`mui...

    Delphi11.3 安卓调用相册,并将图片放入image中CameraRoll.rar

    在使用Delphi 11.3开发Android应用时,调用设备相册并把选中的图片显示在Image组件上是一个常见的需求。这个压缩包“Delphi11.3 安卓调用相册,并将图片放入image中CameraRoll.rar”提供了一个范例或模板,帮助...

    input type=file 调取手机照相机和选择照片上传

    本文将深入探讨如何使用 `input type="file"` 激活手机的照相机功能以及选择图片上传。 首先,`<input type="file">` 是HTML中的一个表单元素,它的主要作用是让用户选择本地文件。在默认情况下,点击这个元素会...

    从本地图库获取图片和拍照获取图片

    在Android和iOS等移动操作系统中,用户经常需要从他们的设备图库中选择图片或直接通过摄像头拍摄新照片。本文将详细讲解如何实现“从本地图库获取图片”和“拍照获取图片”的功能,并涵盖相关技术点。 首先,我们...

    webview 调用手机相机和图库demo

    这个资源是从网上下载来的,不过经过本人改造,目前适合高版本android使用,经测试完全没有,可以直接在android studio 3.0上运行。 这个是一个非常简易的webview调用相机拍照和预览的demo,希望能帮助到需要的人。

    android调用系统相册选取图片

    在Android开发中,调用系统相册选取图片是一项常见的功能,它允许用户从手机的图库中选择一张图片并应用到应用中。本教程将详细解释如何实现这一过程。 首先,你需要在AndroidManifest.xml文件中添加必要的权限。...

    Android + <调用相机拍照 & 选择相册> + 数码相机

    【TakePicture】项目分为两大部分,分别从不同开发场景出发。 随着市场上不同版本、机型手机的出现,老项目迭代维护成本高。...2. 上传多张照片并做压缩处理,图片可实现在线预览,伸缩放大等功能。

    仿微信图片上传 +图库选择9张图+ 多单评价

    微信提供了丰富的图片选择功能,允许用户从手机图库中选择图片。在Android上,我们可以使用系统的`Intent.ACTION_PICK`来调用图库应用,让用户选取图片。同时,由于Android API版本的差异,可能需要使用如`android....

    Unity调用获取手机图片和下载图片功能 NativeGallery插件 跨平台

    - `NativeGallery`提供API接口,允许你在Unity中调用手机的相册,让用户选择图片。这通常涉及Android的`Intent`系统和iOS的`UIImagePickerController`。 - 在Android上,插件会启动一个`ACTION_PICK` Intent,用户...

    android本地图库自定义分类 实现一次选取多张照片

    android本地相册自定义分类、一次选择多张照片 因为Android的本地图片没有一次选择多图片的方法. 所以本人就开发了类似 类似仿微信的本地多张图片选择的DEMO. 本DEMO做的非常简单. 移植也好移植. 在DEMO中...

    打开安卓手机图库和相机并裁剪图片上传到unity

    在Unity中实现与安卓手机图库和相机的交互,以便用户选择图片并进行裁剪,然后上传至Unity项目,是一项常见的跨平台开发任务。这里主要涉及的技术点包括Unity的插件开发、Android原生API调用以及图片处理。 首先,...

    详解Vue调用手机相机和相册以及上传

    在本文中,我们将深入探讨如何使用Vue.js框架调用手机的相机和相册功能,并将选取的图片上传到服务器。Vue.js是一个轻量级的前端JavaScript框架,它提供了丰富的组件化和响应式设计,使得开发移动端应用变得简单易行...

    android简单实现从手机系统库获取图片和视频

    为了提供用户友好的选择体验,通常会使用Intent来启动系统的图库或视频选择器: ```java Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, SELECT_...

    Android实现相册图片选择限制效果Demo

    在Android应用开发中,用户经常需要从手机相册中选择图片进行各种操作,例如上传、编辑或显示。这个"Android实现相册图片选择限制效果Demo"提供了一个实用的方法来实现这一功能,并对选取图片的数量进行了限制,使得...

Global site tag (gtag.js) - Google Analytics