Android如何实现拍照或者选取本地图片
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍Android如何实现拍照或者选取本地图片,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体内容如下总体流程从selectPhotoActivity中启动图册或
千家信息网最后更新 2026年11月01日Android如何实现拍照或者选取本地图片
这篇文章主要介绍Android如何实现拍照或者选取本地图片,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
具体内容如下
总体流程

从selectPhotoActivity中启动图册或者相机,再根据获取的uri进行裁剪,返回uri,再对这个uri执行一系列操纵。
从相册选取图片
private void pickPhoto() { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO); }使用隐式intent启动相机。
拍照获取图片
private void takePhoto() { // 执行拍照前,应该先判断SD卡是否存在 String SDState = Environment.getExternalStorageState(); if (SDState.equals(Environment.MEDIA_MOUNTED)) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// "android.media.action.IMAGE_CAPTURE" File path = Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM); File file = new File(path, IMAGE_FILE_NAME); takePhoto = Uri.fromFile(file); intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, takePhoto); startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO); } else { Toast.makeText(getApplicationContext(), "内存卡不存在", Toast.LENGTH_SHORT).show(); } }值得注意的一点是,intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, takePhoto)中,设置了拍完照照片的存放路径takePhoto,在此情况下,部分机型的onActivityResult()中不会返回数据,即data.getData()为空,因为可以根据存放路径即可获取拍照图片。
裁剪图片
public void startPhotoZoom(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // 设置裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 340); intent.putExtra("outputY", 340); //将URI指向相应的file:///… intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); // 不返回图片文件 intent.putExtra("return-data", false); startActivityForResult(intent, RESULT_REQUEST_CODE); }裁剪方法调用android自带的裁剪库,部分深度定制的机型,如魅族,可能不存在该库,那么就需要自定义或者使用开源裁剪库。
返回的数据的处理
protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != Activity.RESULT_OK) { Log.e("TAG","ActivityResult resultCode error"); return; } switch (requestCode){ case SELECT_PIC_BY_PICK_PHOTO: Uri uri = data.getData(); if (!TextUtils.isEmpty(uri.getAuthority())) { //查询选择图片 Cursor cursor = getContentResolver().query( uri, new String[] { MediaStore.Images.Media.DATA }, null, null, null); //返回 没找到选择图片 if (null == cursor) { return; } //光标移动至开头 获取图片路径 cursor.moveToFirst(); picPath = cursor.getString(cursor .getColumnIndex(MediaStore.Images.Media.DATA)); Log.d("图片路径啊啊啊啊啊啊",picPath); } break; case SELECT_PIC_BY_TACK_PHOTO: //裁剪图片 startPhotoZoom(takePhoto); break; case RESULT_REQUEST_CODE : if (data != null) { Log.d("图片路径",data.getData().toString()); picPath = getPathByUri4kitkat(getApplicationContext(),data.getData()); Log.d("图片路径啊啊啊啊啊啊",picPath); } break; } if(requestCode != SELECT_PIC_BY_TACK_PHOTO) { lastIntent.putExtra(KEY_PHOTO_PATH, picPath); setResult(Activity.RESULT_OK, lastIntent); finish(); } super.onActivityResult(requestCode, resultCode, data); }因为在本activity中可能启动三个新的activity,即拍照activity,相册activity,裁剪activity。需要注意,拍完照的图片需要经过裁剪,即,只有从相册选取和裁剪返回的数据可以setRuselt(),故需要添加一个if语句加以判别。
根据Uri获取真实路径
还是因为机型适配的问题,以下提供两种方法,大家自己尝试:
方法一
public static String getRealPathFromURI(final Context context, final Uri uri ) { if ( null == uri ) return null; final String scheme = uri.getScheme(); String data = null; if ( scheme == null ) data = uri.getPath(); else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) { data = uri.getPath(); } else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) { Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null ); if ( null != cursor ) { if ( cursor.moveToFirst() ) { int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA ); if ( index > -1 ) { data = cursor.getString( index ); } } cursor.close(); } } return data; }方法二
@SuppressLint("NewApi") public static String getPathByUri4kitkat(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { if (isExternalStorageDocument(uri)) {// ExternalStorageProvider 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]; } } else if (isDownloadsDocument(uri)) {// DownloadsProvider 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); } else if (isMediaDocument(uri)) {// MediaProvider 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); } } else if ("content".equalsIgnoreCase(uri.getScheme())) {// MediaStore // (and // general) return getDataColumn(context, uri, null, null); } else if ("file".equalsIgnoreCase(uri.getScheme())) {// File 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 column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_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()); }整体代码
public class selectPhotoActivity extends Activity implements View.OnClickListener{ /** 使用照相机拍照获取图片 */ public static final int SELECT_PIC_BY_TACK_PHOTO = 1; /** 使用相册中的图片 */ public static final int SELECT_PIC_BY_PICK_PHOTO = 2; /** 裁剪图片 */ private static final int RESULT_REQUEST_CODE = 3; /** 开启相机 */ private Button btn_take_photo; /** 开启图册 */ private Button btn_pick_photo; /** 取消 */ private Button btn_cancel; /** 图片名称 */ private static final String IMAGE_FILE_NAME = "image.jpg"; /** 获取到的图片路径 */ private String picPath; //保存裁剪后的图像 private Bitmap photo; private Intent lastIntent; private Uri takePhoto; /** 从Intent获取图片路径的KEY */ public static final String KEY_PHOTO_PATH = "photo_path"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_select_photo); btn_take_photo = (Button) findViewById(R.id.btn_take_photo); btn_pick_photo = (Button) findViewById(R.id.btn_pick_photo); btn_cancel = (Button) findViewById(R.id.btn_cancel); lastIntent = getIntent(); btn_take_photo.setOnClickListener(this); btn_pick_photo.setOnClickListener(this); btn_cancel.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_take_photo : // 开启相机 takePhoto(); break; case R.id.btn_pick_photo : // 开启图册 pickPhoto(); break; case R.id.btn_cancel : // 取消操作 this.finish(); break; default : break; } } /** * 拍照获取图片 */ private void takePhoto() { // 执行拍照前,应该先判断SD卡是否存在 String SDState = Environment.getExternalStorageState(); if (SDState.equals(Environment.MEDIA_MOUNTED)) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// "android.media.action.IMAGE_CAPTURE" File path = Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM); File file = new File(path, IMAGE_FILE_NAME); takePhoto = Uri.fromFile(file); intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, takePhoto); startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO); } else { Toast.makeText(getApplicationContext(), "内存卡不存在", Toast.LENGTH_SHORT).show(); } } /*** * 从相册中取图片 */ private void pickPhoto() { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO); } @Override public boolean onTouchEvent(MotionEvent event) { finish(); return super.onTouchEvent(event); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != Activity.RESULT_OK) { Log.e("TAG","ActivityResult resultCode error"); return; } switch (requestCode){ case SELECT_PIC_BY_PICK_PHOTO: Uri uri = data.getData(); if (!TextUtils.isEmpty(uri.getAuthority())) { //查询选择图片 Cursor cursor = getContentResolver().query( uri, new String[] { MediaStore.Images.Media.DATA }, null, null, null); //返回 没找到选择图片 if (null == cursor) { return; } //光标移动至开头 获取图片路径 cursor.moveToFirst(); picPath = cursor.getString(cursor .getColumnIndex(MediaStore.Images.Media.DATA)); Log.d("图片路径啊啊啊啊啊啊",picPath); } break; case SELECT_PIC_BY_TACK_PHOTO: //裁剪图片 startPhotoZoom(takePhoto); break; case RESULT_REQUEST_CODE : if (data != null) { Log.d("图片路径",data.getData().toString()); picPath = getPathByUri4kitkat(getApplicationContext(),data.getData()); Log.d("图片路径啊啊啊啊啊啊",picPath); } break; } if(requestCode != SELECT_PIC_BY_TACK_PHOTO) { lastIntent.putExtra(KEY_PHOTO_PATH, picPath); setResult(Activity.RESULT_OK, lastIntent); finish(); } super.onActivityResult(requestCode, resultCode, data); } /** * 裁剪图片方法实现 * * @param uri */ public void startPhotoZoom(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // 设置裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 340); intent.putExtra("outputY", 340); //将URI指向相应的file:///… intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); // 不返回图片文件 intent.putExtra("return-data", false); startActivityForResult(intent, RESULT_REQUEST_CODE); } //Android 4.4后通过Uri获取路径以及文件名一种方法 public static String getRealPathFromURI(final Context context, final Uri uri ) { if ( null == uri ) return null; final String scheme = uri.getScheme(); String data = null; if ( scheme == null ) data = uri.getPath(); else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) { data = uri.getPath(); } else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) { Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null ); if ( null != cursor ) { if ( cursor.moveToFirst() ) { int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA ); if ( index > -1 ) { data = cursor.getString( index ); } } cursor.close(); } } return data; } // 专为Android4.4设计的从Uri获取文件绝对路径,以前的方法已不好使 @SuppressLint("NewApi") public static String getPathByUri4kitkat(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { if (isExternalStorageDocument(uri)) {// ExternalStorageProvider 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]; } } else if (isDownloadsDocument(uri)) {// DownloadsProvider 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); } else if (isMediaDocument(uri)) {// MediaProvider 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); } } else if ("content".equalsIgnoreCase(uri.getScheme())) {// MediaStore // (and // general) return getDataColumn(context, uri, null, null); } else if ("file".equalsIgnoreCase(uri.getScheme())) {// File 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 column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_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()); }}以上是"Android如何实现拍照或者选取本地图片"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!
图片
路径
方法
相册
文件
相机
选择
内容
图册
数据
机型
光标
内存
内存卡
开头
指向
比例
篇文章
部分
查询
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
伟宏互联网科技
河南云网互联网络科技有限公司
高科技与互联网
浩特互联网科技
互联网科技上市公司
睿民互联网科技
互联网科技美容
美国互联网前沿科技
互联网实体化科技化
互联网系的金融科技公司
茂名市互联网科技产业园
互联网科技创新的路径
世界互联网领先科技成果获奖
互联网科技圈年度人物
南通创西澳互联网科技有限公司
半导体是互联网高科技吗
有人说阿里系是互联网科技企业
科技互联网公司两年变化
华人运通互联网科技公司
互联网大会出现的黑科技
什么是科技互联网
科技与互联网
互联网电商科技
广州宏创互联网科技
银优互联网科技有限公司
玖二柒互联网科技公司待遇
天速互联网络科技有限公司
互联网科技热点资讯
浙南科技城互联网大厦招聘
广州全民伙伴互联网科技有限公司