因为今天写一个案例需要用到打开手机自带图库这个功能,就在网上找了一下,结果发现网上的代码不全,运行出错,就想起了书中的代码,代码来自于第一行代码第八章
布局文件中只有一个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(); } }