Android 调用相机与图库的简单封装
为了更好的复用,我将对相机或图库的调用封装成一个工具类,可于Fragment和Activity中直接调用,直接上代码,如下:
CamearUtils.java
package user package name; import android.app.Activity; import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.support.v4.app.Fragment; import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * @outher 孙磊磊 * create at 2016/1/4 9:44 * description 获取图片辅助类 */ public class CamearUtils { /** * 上下文环境 */ private Fragment mFragment; /** * 上下文环境 */ private Activity mActivity; /** * 回调监听 */ private CallBackDataListener mListener; /** * 图片存储文件夹,例如: "img"、"app/img" */ private String mFolder; /** * 是否裁剪 */ private boolean isScreenshot = false; private int mAspectX; private int mAspectY; private int mOutputX; private int mOutputY; private static final int REQUEST_CODE_CAMEAR = 0xF1; private static final int REQUEST_CODE_GALLERY = 0xF2; private static final int REQUEST_CODE_SCREENSHOT = 0xF3; private File mCameraFile; /** * @outher 孙磊磊 * create at 2016/1/4 13:34 * description 如果在Fragment中调用请使用该构造方法 */ public CamearUtils(Fragment fragment, String folder) { if (folder == null || folder.trim().length() == 0) { folder = "img";//如果不设置图片路径,给予默认值 } this.mFragment = fragment; this.mFolder = folder; } /** * @outher 孙磊磊 * create at 2016/1/4 13:34 * description 如果是在Activity中使用请调用该方法 */ public CamearUtils(Activity activity, String folder) { if (folder == null || folder.trim().length() == 0) { folder = "img";//如果不设置图片路径,给予默认值 } this.mActivity = activity; this.mFolder = folder; } /** * @outher 孙磊磊 * create at 2016/1/4 9:53 * description 调用相机 */ public void goCamear() { if (!getSDCardisExist()) {//检查是否存在SD卡 Toast.makeText(getContext(), "请检查SD卡", Toast.LENGTH_SHORT) .show(); return; } mCameraFile = new File(getSDPath() + "/" + mFolder + "/" + System.currentTimeMillis() + ".jpg");//返回图片的路径 mCameraFile.getParentFile().mkdirs(); startActivityForResult( new Intent(MediaStore.ACTION_IMAGE_CAPTURE).putExtra( MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCameraFile)), REQUEST_CODE_CAMEAR); } /** * @outher 孙磊磊 * create at 2016/1/4 9:53 * description 调用相册 */ public void goGallery() { Intent intent; if (Build.VERSION.SDK_INT < 19) { intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); } else { intent = new Intent( Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); } startActivityForResult(intent, REQUEST_CODE_GALLERY); } /** * @outher 孙磊磊 * create at 2016/1/4 9:54 * description 截图 */ public void goScreenshot(Uri uri) { mCameraFile = new File(getSDPath() + "/" + mFolder + "/" + System.currentTimeMillis() + ".jpg"); Intent intent = new Intent("com.android.camera.action.CROP"); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { intent.setDataAndType(uri, "image/*"); } else { intent.setDataAndType(uri, "image/*"); } // 设置裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", mAspectX); intent.putExtra("aspectY", mAspectY); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", mOutputX); intent.putExtra("outputY", mOutputY); intent.putExtra("return-data", true); startActivityForResult(intent, REQUEST_CODE_SCREENSHOT); } /** * @outher 孙磊磊 * create at 2016/1/4 9:55 * description 处理返回值 */ public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { if (requestCode == REQUEST_CODE_CAMEAR) { if (mCameraFile != null && mCameraFile.exists()) { if (isScreenshot) { goScreenshot(Uri.fromFile(mCameraFile)); } else { if (mListener != null) mListener.CallBack(mCameraFile.getPath()); } mCameraFile = null; } } else if (requestCode == REQUEST_CODE_GALLERY) { if (data != null) { Uri selectedImage = data.getData(); if (selectedImage != null) { //处理本地图片 if (isScreenshot) { goScreenshot(selectedImage); } else { if (mListener != null) mListener.CallBack(getImageAbsolutePath(getContext(), selectedImage)); } } } } else if (requestCode == REQUEST_CODE_SCREENSHOT) { //处理裁剪图片 Bundle extras = data.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable("data"); String path = getSDPath() + "/" + mFolder + "/" + System.currentTimeMillis() + ".jpg"; if (saveBitmap(photo, path)) { if (mListener != null) { mListener.CallBack(path); } else { Toast.makeText(getContext(), "保存图片失败!", Toast.LENGTH_SHORT).show(); } } } } } } /** * @outher 孙磊磊 * create at 2016/1/4 13:40 * description 将bitmap保存到指定路径 */ public boolean saveBitmap(Bitmap bitmap, String path) { File f = new File(path); try { f.createNewFile(); FileOutputStream fOut = null; fOut = new FileOutputStream(f); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut); fOut.flush(); fOut.close(); return true; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; } /** * @outher 孙磊磊 * create at 2016/1/4 10:09 * description 获取sd卡根目录 */ public String getSDPath() { File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState() .equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在 if (sdCardExist) { sdDir = Environment.getExternalStorageDirectory();//获取跟目录 } return sdDir.toString(); } /** * @outher 孙磊磊 * create at 2016/1/4 10:11 * description 判断SDCard是否存在并且可写 */ public boolean getSDCardisExist() { if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { return true; } else { return false; } } /** * @outher 孙磊磊 * create at 2016/1/4 13:41 * description 设置是否剪裁,如果设置剪裁,aspectX,aspectY 为设置长宽比例,width,height为剪裁宽高 */ public void setScreenshot(boolean isScreenshot,int aspectX,int aspectY,int width,int height) { this.isScreenshot = isScreenshot; this.mAspectX=aspectX; this.mAspectY=aspectY; this.mOutputX=width; this.mOutputY=height; } /** * @outher 孙磊磊 * create at 2016/1/4 9:53 * description 设置监听 */ public void setListener(CallBackDataListener listener) { this.mListener = listener; } /** * @outher 孙磊磊 * create at 2016/1/4 9:53 * description 监听回调 */ public interface CallBackDataListener { public void CallBack(String imgPath); } /** * @outher 孙磊磊 * create at 2016/1/4 13:41 * description 获取上下文环境 */ private Context getContext() { if (mActivity == null) { return mFragment.getContext(); } else { return mActivity; } } /** * @outher 孙磊磊 * create at 2016/1/4 13:42 * description 跳转Activity */ private void startActivityForResult(Intent intent, int request) { if (mActivity == null) { mFragment.startActivityForResult(intent, request); } else { mActivity.startActivityForResult(intent, request); } } /** * ************************************************************************************************* * 以下内容来自于谷歌搜索 * ************************************************************************************************* * */ /** * @outher 孙磊磊 * create at 2015/12/31 15:09 * description 根据文件的Uri获取文件的绝对路径 */ public static String getImageAbsolutePath(Context context, Uri imageUri) { if (context == null || imageUri == null) return null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, imageUri)) { if (isExternalStorageDocument(imageUri)) { String docId = DocumentsContract.getDocumentId(imageUri); String[] split = docId.split(":"); String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } else if (isDownloadsDocument(imageUri)) { String id = DocumentsContract.getDocumentId(imageUri); Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } else if (isMediaDocument(imageUri)) { String docId = DocumentsContract.getDocumentId(imageUri); String[] split = docId.split(":"); 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; } String selection = MediaStore.Images.Media._ID + "=?"; String[] selectionArgs = new String[]{split[1]}; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(imageUri.getScheme())) { // Return the remote address if (isGooglePhotosUri(imageUri)) return imageUri.getLastPathSegment(); return getDataColumn(context, imageUri, null, null); } // File else if ("file".equalsIgnoreCase(imageUri.getScheme())) { return imageUri.getPath(); } return null; } public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; String column = MediaStore.Images.Media.DATA; String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { 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()); } }
在下面对其使用加以说明:
首先对其进行初始化:
接着要在onActivityResult中调用<span style="white-space:pre"> </span>camearUtils = new CamearUtils(this, "img"); camearUtils.setScreenshot(true,1,1,200,200);//设置裁剪 camearUtils.setListener(new CamearUtils.CallBackDataListener() { @Override public void CallBack(String imgPath) { //在这里处理之后的图片均存放在SD卡中,这里回调返回所需图片的文件路径 } });
然后就可以直接使用了,如下public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); camearUtils.onActivityResult(requestCode, resultCode, data); }
private void showSelectHeadImg() { final AlertDialog dialog = new AlertDialog.Builder(getContext()).create(); dialog.show(); dialog.setCanceledOnTouchOutside(false); Window win = dialog.getWindow(); win.setBackgroundDrawable(new ColorDrawable(0X00000000)); win.setGravity(Gravity.BOTTOM); dialog.setContentView(R.layout.dg_mine_select_headimg); win.findViewById(R.id.bt_goCamera).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { camearUtils.goCamear();//从相机获取 dialog.cancel(); dialog.dismiss(); } }); win.findViewById(R.id.bt_goLoc).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { camearUtils.goGallery();//从图库获取 dialog.cancel(); dialog.dismiss(); } }); win.findViewById(R.id.bt_Cancel).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.cancel(); dialog.dismiss(); } }); }
附带布局文件:
dg_mine_select_headimg.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_gravity="bottom" android:padding="16dp"> <Button android:id="@+id/bt_goCamera" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/round_orange" android:gravity="center" android:padding="8dp" android:text="拍照" android:textColor="@color/white" android:textSize="16dp" /> <Button android:id="@+id/bt_goLoc" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/round_orange" android:padding="8dp" android:text="选择本地图片" android:textColor="@color/white" android:layout_marginTop="10dp" android:textSize="16dp" /> <Button android:id="@+id/bt_Cancel" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/round_gray" android:padding="8dp" android:text="取消" android:textColor="@color/white" android:layout_marginTop="16dp" android:textSize="16dp" /> </LinearLayout>