Android调用手机自带图库选择图片

因为今天写一个案例需要用到打开手机自带图库这个功能,就在网上找了一下,结果发现网上的代码不全,运行出错,就想起了书中的代码,代码来自于第一行代码第八章

布局文件中只有一个button和ImageView,其中button用于打开手机自带图库选择图片,imageview用于显示选中的图片。

布局文件如下所示:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.sun.bluetooth.PicActivity">
    <ImageView
        android:id="@+id/iv_pic"
        android:src="@mipmap/pic"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:scaleType="centerCrop"/>
    <Button
        android:layout_marginTop="16dp"
        android:id="@+id/btu_select"
        android:text="选取系统相册照片"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>
</LinearLayout>

接着实例化控件,在button的点击事件监听中用于打开系统相册,因为相册中的照片都是存储在sd卡上的,所以需要早Manifest文件中添加sd卡的权限,sd卡的权限属于危险权限所以需要进行运行时处理,如下所示:

添加权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

button的点击事件和运行时权限处理:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_pic);
    mButton = (Button) findViewById(R.id.btu_select);
    mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (ContextCompat.checkSelfPermission(PicActivity.this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(PicActivity.this, new
                        String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            } else {
                //打开系统相册
                openAlbum();
            }
        }
    });
    mImageView = (ImageView) findViewById(R.id.iv_pic);
}

private void openAlbum() {
    Intent intent = new Intent("android.intent.action.GET_CONTENT");
    intent.setType("image/*");
    startActivityForResult(intent, REQUEST_SYSTEM_PIC);//打开系统相册

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                openAlbum();
            } else {
                Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
            }
            break;
        default:
    }
}

当选择完图片后会回到onActivityResult方法中,在该方法中来处理图片。处理图片时,由于Android版本从4.4开始,选取相册中的图片返回的不再是真实的uri,而是封装过的uri,因此需要进行版本判断从而选择合适的处理方式,代码如下所示:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_SYSTEM_PIC && resultCode == RESULT_OK && null != data) {
        if (Build.VERSION.SDK_INT >= 19) {
            handleImageOnKitkat(data);
        } else {
            handleImageBeforeKitkat(data);
        }
    }
}

@TargetApi(19)
private void handleImageOnKitkat(Intent data) {
    String imagePath = null;
    Uri uri = data.getData();
    if (DocumentsContract.isDocumentUri(this, uri)) {
        //如果是document类型的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);
        } 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);
        }
    } 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 handleImageBeforeKitkat(Intent data) {
    Uri uri = data.getData();
    String imagePath = getImagePath(uri, null);
    displayImage(imagePath);

}

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;
}

private void displayImage(String imagePath) {
    if (imagePath != null) {
        Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
        mImageView.setImageBitmap(bitmap);
    } else {
        Toast.makeText(this, "failed to get image", Toast.LENGTH_SHORT).show();
    }
}

猜你喜欢

转载自blog.csdn.net/yao_94/article/details/79447359
今日推荐