android拍照与相册选择照片并保存本地

最近项目中有用到拍照与相册选择照片并保存本地的操作,在网上查看了很多的例子,然后进行了总结,还算基本满足了自己的需求,所以今天在这里做一个总结,将相关知识点总结出来免得忘记(人老了记性不好 =。=)。

这个Demo的布局非常简单,就是两个TextView来表示拍照按钮和选择相册按钮,一个ImageView来显示选择的照片,所以布局文件在这里就不贴出了,我们将java代码贴出来:


要用到的一些状态信息,这个可以自己设置就好:

private static String IMAGE_FILE_NAME = System.currentTimeMillis()+".jpg";

    /**
     * 请求不同状态的状态码
     */
    private static final int IMAGE_REQUEST_CODE = 0;
    private static final int SELECT_PIC_KITKAT = 3;
    private static final int CAMERA_REQUEST_CODE = 1;
    private static final int RESULT_REQUEST_CODE = 2;



这是点击事件所执行的方法:

<span style="font-size:18px;">@butterknife.OnClick({R.id.tv1, R.id.tv2})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv1:
                /**
                 * 点击照相
                 */
                Intent intentFromCapture = new Intent(
                        MediaStore.ACTION_IMAGE_CAPTURE);
                // 判断存储卡是否可以用,可用进行存储
                intentFromCapture.putExtra(
                        MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(new File(Environment
                                .getExternalStorageDirectory(),
                                IMAGE_FILE_NAME)));

                startActivityForResult(intentFromCapture,
                        CAMERA_REQUEST_CODE);
                break;
            case R.id.tv2:
                /**
                 * 点击相册
                 */
                Intent intent1 = new Intent(Intent.ACTION_GET_CONTENT);
                intent1.addCategory(Intent.CATEGORY_OPENABLE);
                intent1.setType("image/*");
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
                    startActivityForResult(intent1, SELECT_PIC_KITKAT);
                } else {
                    startActivityForResult(intent1, IMAGE_REQUEST_CODE);
                }
                break;
        }
    }</span>


这是onActivityResult中实现的:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case 1:
            if (resultCode == 2) {

            }
            break;
    }
    // 结果码不等于取消时候
    if (resultCode != this.RESULT_CANCELED) {
        switch (requestCode) {
            case IMAGE_REQUEST_CODE:
                startPhotoZoom(data.getData());
                break;
            case SELECT_PIC_KITKAT:
                //图库
                if(data!=null)
                    bitmapFactory(data.getData());
                break;
            case CAMERA_REQUEST_CODE:
                //照相机
                String sdStatus = Environment.getExternalStorageState();
                // 检测sd是否可用
                if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) {
                    Toast.makeText(this,"内存卡异常,请检查内存卡插入是否正确",Toast.LENGTH_SHORT).show();
                    return;
                }
                File tempFile = new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME);
                startPhotoZoom(Uri.fromFile(tempFile));
                break;
            case RESULT_REQUEST_CODE:
                setImageToView(data);
                break;
        }
    }
}



其他相关的方法:

<span style="font-size:18px;">/**
     * 裁剪图片方法实现
     *
     * @param uri
     */
    public void startPhotoZoom(Uri uri) {
        if (uri == null) {
            Log.e("TAG", "The uri is not exist.");
            return;
        }
        Intent intent = new Intent("com.android.camera.action.CROP");
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            String url = getPath(this.getApplication(), uri);
            intent.setDataAndType(Uri.fromFile(new File(url)), "image/*");
        } else {
            intent.setDataAndType(uri, "image/*");
        }

        // 设置裁剪
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 300);
        intent.putExtra("outputY", 300);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, RESULT_REQUEST_CODE);
    }

    /**
     * 图库的照片选择过后加载到ImageView
     * @param uri
     */
    private void bitmapFactory(Uri uri){
        Log.e("----","uri:"+uri.toString());

        String filepath= getPath(this,uri);
        if(!TextUtils.isEmpty(filepath)){
            filepath="file:///"+filepath;
            ImageLoader.getInstance().displayImage(filepath,iv);
        }
    }

    /**
     * 保存照片并设置照片给对应的View
     * @param data
     */
    private void setImageToView(Intent data) {
        Bundle extras = data.getExtras();
        if (extras != null) {
            Bitmap photo = extras.getParcelable("data");
            String path=saveBitmap(photo);
            setPicture(path);
//            iv.setImageBitmap(BitmapFactory.decodeFile(path));
        }
    }

    /**
     * 给控件设置图片
     * @param path
     */
    public void setPicture(String path){
        path="file:///"+path;
        ImageLoader.getInstance().displayImage(path,iv);
    }

    /**
     * 创建保存图片的文件夹
     */
    public void createFile(){
        String path=Environment.getExternalStorageDirectory()+"/myphoto/";
        File f=new File(path);
        if(!f.exists()){
            f.mkdir();
        }
    }

    /**
     * 保存照片
     * @param mBitmap
     * @return
     */
    public String saveBitmap(Bitmap mBitmap) {
        String sdStatus = Environment.getExternalStorageState();
        if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
            Toast.makeText(this,"内存卡异常,请检查内存卡插入是否正确",Toast.LENGTH_SHORT).show();
            return "";
        }
        String path=System.currentTimeMillis()+".jpg";
        File f = new File(Environment.getExternalStorageDirectory()+"/myphoto/",path);
        createFile();
        try {
            FileOutputStream fOut = null;
            fOut = new FileOutputStream(f);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
            fOut.flush();
            fOut.close();
            return f.getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    //Ps:原本uri返回的是file:///...,android4.4返回的是content://,所以这里要注意一下
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public String getPath(final Context context, final Uri uri) {
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];
                Uri contentUri = null;

                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    public String getDataColumn(Context context, Uri uri, String selection,
                                String[] selectionArgs) {
        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }</span>


这样我们就可以根据照相和相册选择来显示不同路径的图片了,在Demo中我们图片的显示加载用了ImageLoader,因为这个不是我们这一次的重点所以代码就不贴出来了,需要了解的朋友自己去查一查相关的博客吧,在Demo中我们可能用到的权限如下:

<span style="font-size:18px;"><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!--往sdcard中写入数据的权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <!--在sdcard中创建/删除文件的权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
    <uses-permission android:name="android.permission.CAMERA"></uses-permission></span>




---------------END!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值