在做Android图片上传功能的时候,获取图片的途径一般都有两种:拍照、从相册选择。

一、拍照

调用相机拍照有两种方法:

  1. 直接返回图片。
  2. 在调用相机的时候,传入uri,拍照后通过该uri来获取图片。

1.直接返回图片

private int TAKE_SMALL_PHOTO_REQUEST=0;//全局变量Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PHOTO_REQUEST);

  就是通过Intent发出隐式意图,制定action为MediaStore.ACTION_IMAGE_CAPTURE,来调用系统的相机。并返回相机拍的图片。在onActivityResult方法里接收。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_CANCELED) {Toast.makeText(context, "拍照取消!", Toast.LENGTH_LONG).show();return;}if (resultCode == RESULT_OK) {switch (requestCode) {case TAKE_PHOTO_REQUEST:// 拍照返回结果Bitmap  photo = data.getParcelableExtra("data");// 按需求处理photo   break;}}}

  返回的图片以bitmap的格式存放在data的key值是“date”中。取出后可进行相应的操作,比如显示、保存、上传。但是,要注意的是这是返回的bitmap是被系统用默认压缩方式压缩过的图片。那么要想获取原图或用自己的压缩方式处理怎么办呢?就要用到方法二了。

2.在调用相机的时候,传入uri,拍照后通过该uri来获取图片

//全局变量
private int TAKE_BIG_PHOTO_REQUEST=1;
private Uri imageUri;imageUri = createImageUri(context);//创建存储图片的uri,该方法见下边的讲解
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_BIG_PHOTO_REQUEST);@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_CANCELED) {deleteUri(imageUri, null, null);// 拍照取消,删除不用的文件Toast.makeText(context, "拍照取消!", Toast.LENGTH_LONG).show();return;}if (resultCode == RESULT_OK) {switch (requestCode) {case TAKE_BIG_PHOTO_REQUEST:// 直接使用之前新建的图片uri,来操作图片// 按需求处理photo,比如显示   iv.setImageURI(imageUri);break;}}}

  这种方法是向Intent中添加一条图片的uri数据,这时拍照完成后,系统会将图片存在这个uri中,在onActivityResult中,就可以直接使用这个uri操作图片了。隐式意图“MediaStore.ACTION_IMAGE_CAPTURE”和关键字“MediaStore.EXTRA_OUTPUT”也可以分别用“android.media.action.IMAGE_CAPTURE”和“output”代替。都是一个意思,只不过是不同的表示方法。
  删除文件方法deleteUri(imageUri, null, null),参考我的一篇博客[Android 根据Uri删除文件](http://blog.csdn.net/mamr227/article/details/77683729)里的两种删除方法,文章的最后有一个综合方法,不同的方法为了兼容下边创建存储图片、获取uri的两种不同的方法。
创建存储图片、获取uri

1. 方法一

private Uri createImageUri(Context context){Uri uri = null;if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){String name = String.valueOf(System.currentTimeMillis());ContentValues contentValues = new ContentValues();contentValues.put(MediaStore.Images.Media.TITLE, name);contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, name + ".jpeg");contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);}return uri;
}

  创建文件和获取uri同时进行。
  首先将图片的文件信息保存在ContentValues 中,在通过ContentResolver类的insert方法来创建图片文件,并获取uri。该uri是以“content://”开头的,因此,可以用在Android 7.0以上版本。
  优点:简单。
  缺点:只能进行外部存储,存放图片的默认文件夹Pictures。原因是:
    insert方法创建时只有两种存储方式:
         1.EXTERNAL_CONTENT_URI,就是现在用的。
         2.INTERNAL_CONTENT_URI,指向的是内部存储的根目录,而我们是访问不了的,会报错。
  不熟悉外部存储和内部存储的小伙伴可以参考我的一篇博客Android内部存储与外部存储解析 希望对你有所帮助。
  从原因的分析看,这种方法只能存在手机有外部存储的时候可以用,不过现在手机基本上都实现了SD内置本身就可以外部存储,不用担心这个。但是如果开发需求需要,存放在指定的文件夹怎么办,那看方法二了。

2.方法二

 private Uri createImageUri(Context context,String myPath) {//创建文件String state = Environment.getExternalStorageState();File rootDir = state.equals(Environment.MEDIA_MOUNTED) ? Environment.getExternalStorageDirectory() : context.getCacheDir();File folderDir = new File(rootDir.getAbsolutePath() + myPath);//myPath是图片存放的自定义的路径if (!folderDir.exists() && folderDir.mkdirs()) {}String fileName = System.currentTimeMillis() + ".JPEG";File tmpFile = new File(folderDir, fileName);// 调用parUri方法转成urireturn parUri(tmpFile);}/*** 生成uri* @param cameraFile* @return*/private Uri parUri(File cameraFile) {Uri imageUri;String authority = context.getPackageName() + ".provider";if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {//通过FileProvider创建一个content类型的UriimageUri = FileProvider.getUriForFile(this, authority, cameraFile);} else {imageUri = Uri.fromFile(cameraFile);}return imageUri;}

  这种方法是我要实现一个图片选择器的时候,看到LuckSiege开源框架里的一个方法,也引发了我对FileProvider类的学习,之后对FileProvider进行总结。
创建文件和获取uri分两步:

  1. rootDir是外部存储的根目录,第二个参数可以自定义路径,比如“/photoTest/”;当不能进行外部存储的时候,调用getCacheDir()放在应用的cache目录下。
  2. 转成Uri,Uri.fromFile(cameraFile)方法,传化成Uri以file://开头,这时如果想调用系统剪裁或与其他应用进行通信,在Android 7.0以上就会报错闪退。就要在SDK版本大于24时,用FileProvider.getUriForFile(this, authority, cameraFile)方法,转化成Uri以content://开头,来适用Android7.0以上。如上边的方法parUri(File cameraFile)。FileProvider使用时需要配置一些东西,网上有很多讲解,文章末尾有一个包含有配置demo可以下载。
      这样就完美又灵活的实现了创建图片文件。

二、从相册获取

调用系统相册

Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, TAKE_ALBUM_REQUEST);@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);MLog.e("resultCode" + resultCode);if (resultCode == RESULT_CANCELED) {ToastUtil.showMessage(mContext, "取消设置图片!");}if (resultCode == RESULT_OK) {switch (requestCode) {case TAKE_ALBUM_REQUEST:Uri uri = data.getData();// 获取选择图片的uri// 对uri进行处理break;}
}

  调用系统图片很简单,不过一般系统图片会非常大,直接显示的时候,会报OOM。需要先进行压缩或剪裁的处理。在压缩或剪裁之前注意创建一个新的文件,处理后保存在新的文件里,否则就会处理后的图就会覆盖原图片,并且有些手机覆盖原图的时候会报错。

通过拍照、相册获取图片demo

Android 拍照、从相册选择图片相关推荐

  1. android拍照所需的权限,eclipse --- Android拍照,相册选择图片以及Android6.0权限管理...

    [实例简介] eclipse --- Android拍照,相册选择图片以及Android6.0权限管理 [实例截图] [核心代码] camreainandroidm └── camreainandro ...

  2. Android 拍照和相册选择

    前几天一直在想写一个简单干净的关于Android 拍照和相册选择的dome,直到今天才有时间去写,下面是图片介绍,资源代码会有上传!供初学者学习指教(代码是Android studio) 1.控件 0 ...

  3. android相册路径地址,Android拍照和相册获取图片路径

    /** *调用系统相机 */ public voidstartCamera() { Intent intent =newIntent(MediaStore.ACTION_IMAGE_CAPTURE); ...

  4. android从本地相册选择图片uri三星手机适配问题

    转载地址:http://blog.csdn.net/CathyChen0910/article/details/62456438 启动系统相册intent Intent intentFromGalle ...

  5. 学习笔记之Android调用系统相册选择图片

    文章目录 前言 使用步骤 小结 参考资料 前言 在相册里选择图片上传也是很常见的功能了例如微信朋友圈等等.但是他们是自定义的选择器,可以选择多张图片并修改.这里我们讲一个最简单的:调用系统的相册选择一 ...

  6. MUI+HTML5+Plus 拍照或者相册选择图片并上传服务器

    引入文件 css:mui.min.css.app.css.iconfont.css.feedback-page.css.font-awesome.min.css js:jquery.js.common ...

  7. android+代码调用+相册+小米,Android调用系统相册选择图片,支持小米4云相册

    用小米4调用系统相册选择照片时,如果云相册功能开启的话.云相册中的图片也会显示在选择列表中.经过测试,选择到云相册中的图片的话,uri的scheme是file,而不再试content.本文支持云相册的 ...

  8. android 调用相册功能吗,Android调用系统相册选择图片,支持小米4云相册

    用小米4调用系统相册选择照片时,如果云相册功能开启的话.云相册中的图片也会显示在选择列表中.经过测试,选择到云相册中的图片的话,uri的scheme是file,而不再试content.本文支持云相册的 ...

  9. 探索HTML5 Plus 拍照或者相册选择图片上传过程

    起因:webApp中需要一个拍摄照片并上传服务器的功能 由于我正好使用Hbuilder在做webApp,所以自然想到了使用h5+中的调用摄像头功能 从此开始了踩坑之旅... 1.手机连接电脑问题   ...

  10. 点击图片跳转android,android 跳转相册选择图片并返回展示

    1.点击事件跳转 private void selectImage() { Intent intent = new Intent(); intent.setType("image/*&quo ...

最新文章

  1. 优酷智能档在大型直播场景下的技术实践
  2. python replace函数用法_Python实现的从右到左字符串替换方法示例
  3. python在excel中的应用-Python利用pandas处理Excel数据的应用详解
  4. Sql server 获得某一部门下的所有子部门。根据子部门获得它的上级部门。
  5. python发送文件到钉钉群_iOS python 自动化打包,并在钉钉群里发通知
  6. 接口测试工具postman安装及使用
  7. Linux crontab的使用方式,sh脚本的编写,sh脚本自动启动tomcat服务器,sh监控系统运行情况
  8. 【C语言】控制台窗口图形界面编程(五):文本移动
  9. 您请求的报表需要更多信息...
  10. oracle执行计划的概念,SQL语句性能调整之ORACLE的执行计划
  11. 修改服务器的共享内存大小,服务器共享内存大小能改么
  12. 夸计算机老师的成语,夸赞老师的成语
  13. python settings模块导入不了_Django:无法导入“模块”。检查模块AppConfig.name是否正确 - python...
  14. Android WebView使用基础
  15. Jsp基本指令和动作
  16. Gradle之SourceSet
  17. Android开发:申请小米开发者账号步骤
  18. 7代cpu能装虚拟xp系统吗_【精选】减少DCS系统故障的实例与措施
  19. 自驾游app开发的前景和优势
  20. 达梦数据库(DM8)的安装教程

热门文章

  1. 第18课:模型部署上线的几种服务发布方式
  2. linux生成免密码登录
  3. elasticsearch 的滚动(scroll)
  4. vue-cli 上手
  5. MariaDB 10.3 主主半同步复制
  6. 面试题:谈谈你对hibernate的理解
  7. 线性表的链式存储结构(C语言版)
  8. mac osx安装mysql5.7.9
  9. 将windows系统装到USB存储设备
  10. 成为人上人,而不是人上人永远的崇拜者