你的位置:首页 > 操作系统

[操作系统]Android从相册获取图片


应用中经常会有去相册获取图片的需求,每次总是会忘,现在这做个记录,以便以后查阅。

从应用去相册获取图片主要有以下几个步骤:

1、设置intent调用系统相册

2、进入相册选取图片,如果相册没有满意的图片,可以使用相机照相获取,最后返回数据到应用

3、应用获取图片后,调用裁剪程序对图片进行裁剪

4、返回裁剪的图片并显示出来

 

一、设置intent调用系统相册,并进入相册选取图片

/** * 调用相册 */private void goAlbums() {    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);    intent.addCategory(Intent.CATEGORY_OPENABLE);    intent.setType("image/*");    startActivityForResult(intent, SELECT_PIC); }

通过以上设置进入相册,返回的图片数据交由Activity的onActivityResult方法处理,请求码是SELECT_PIC,请求码为int型,可以随意设置

获取到返回的图片之后,下面便进入裁剪的步骤了

 

二、调用裁剪程序对图片进行裁剪

/**   * 裁剪大图   * @param context   * @param uri   */  private void clipperBigPic(Context context, Uri uri) {    if (null == uri) {      return;    }    Intent intent = new Intent("com.android.camera.action.CROP");    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {      String url = PhotoClipperUtil.getPath(context, uri);      intent.setDataAndType(Uri.fromFile(new File(url)), "image/*");    }    //发送裁剪命令    intent.putExtra("crop", true);    //X方向上的比例    intent.putExtra("aspectX", 1);    //Y方向上的比例    intent.putExtra("aspectY", 1);    //裁剪区的宽    intent.putExtra("outputX", 124);    //裁剪区的高    intent.putExtra("outputY", 124);    //是否保留比例    intent.putExtra("scale", true);    //返回数据    intent.putExtra("return-data", true);    //输出图片格式    intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());    //裁剪图片保存位置    intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());    startActivityForResult(intent, SELECT_CLIPPER_PIC);  }

上面代码中的Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT,是因为KITKAT以上版本中返回的data数据和KITKAT以下版本的data数据可能不同,需要单独处理。

下面的代码便是正常处理,设置裁剪的参数,请求的数据同样交由onActivityResult处理

getTempUri为设置临时图片存储目录,代码如下:

private Uri getTempUri() {    return Uri.fromFile(getTempFile());  }  /**   * 临时图片保存路径   * @return   */  private File getTempFile() {    File file = new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME);    try {      file.createNewFile();    } catch (IOException e) {      e.printStackTrace();    }    return file;  }

上面代码中中的IMAGE_FILE_NAME需要自己指定

上面代码中的PhotoClipperUtil类代码如下:

package tmg.gotoalarm;import android.annotation.SuppressLint;import android.content.ContentUris;import android.content.Context;import android.database.Cursor;import android.net.Uri;import android.os.Build;import android.os.Environment;import android.provider.DocumentsContract;import android.provider.MediaStore;public class PhotoClipperUtil {  @SuppressLint("NewApi")  public static 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;  }  /**   * Get the value of the data column for this Uri. This is useful for   * MediaStore Uris, and other file-based ContentProviders.   *   * @param context The context.   * @param uri The Uri to query.   * @param selection (Optional) Filter used in the query.   * @param selectionArgs (Optional) Selection arguments used in the query.   * @return The value of the _data column, which is typically a file path.   */  public static 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;  }  /**   * @param uri The Uri to check.   * @return Whether the Uri authority is ExternalStorageProvider.   */  public static boolean isExternalStorageDocument(Uri uri) {    return "com.android.externalstorage.documents".equals(uri.getAuthority());  }  /**   * @param uri The Uri to check.   * @return Whether the Uri authority is DownloadsProvider.   */  public static boolean isDownloadsDocument(Uri uri) {    return "com.android.providers.downloads.documents".equals(uri.getAuthority());  }  /**   * @param uri The Uri to check.   * @return Whether the Uri authority is MediaProvider.   */  public static boolean isMediaDocument(Uri uri) {    return "com.android.providers.media.documents".equals(uri.getAuthority());  }  /**   * @param uri The Uri to check.   * @return Whether the Uri authority is Google Photos.   */  public static boolean isGooglePhotosUri(Uri uri) {    return "com.google.android.apps.photos.content".equals(uri.getAuthority());  }}

总的获取相册图片的流程如下:

mGoAlarmIv.setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        //调用系统相册,进入相册获取图片        goAlbums();      }    });  

进入相册后,应用的中转工作交由onActivityResult处理

@Override  protected void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);    if (data == null) {      return;    }    switch (requestCode) {      case SELECT_PIC:        //获取图片后裁剪图片        clipperBigPic(this, data.getData());        break;      case SELECT_CLIPPER_PIC:        //获取图片后保存图片到本地,是否需要保存看情况而定        saveBitmap(data);        //显示图片        showImage(mGoAlarmIv);        break;    }  }

保存图片的代码如下:

/**   * 保存图片   * @param data   */  private void saveBitmap(Intent data) {    Bundle bundle = data.getExtras();    if (bundle != null) {      Bitmap bitmap = bundle.getParcelable("data");      File file = new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME);      try {        file.createNewFile();        FileOutputStream fileOutputStream = new FileOutputStream(file);        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);        fileOutputStream.flush();        fileOutputStream.close();      } catch (FileNotFoundException e) {        e.printStackTrace();      } catch (IOException e) {        e.printStackTrace();      }    }  }

OK,以上便是第三方应用调用相册获取图片的整个流程。