android 拍照及从相册选择组件

单独封装到一个 activity 中便于更好的复用

拍照或从相册选择成功后使用 EventBus 发出广播回传图片路径,和调用者充分解耦合

根据传入参数支持裁剪和不裁剪两种模式

/**
* <pre>
* 拍照及从相册选择弹出 activity
* 成功后会发送 TakePhotoOutputEvent 事件,返回图片路径
* </pre>
*/
public class TakePhotoPopupActivity extends Activity {
public static final int REQUEST_CODE_CAMERA = 110;
public static final int REQUEST_CODE_ALBUM = 111;
public static final int REQUEST_CODE_CROP = 112; @ViewInject(R.id.takephoto_popup_layout)
private RelativeLayout outContainer;
@ViewInject(R.id.take_photo)
private TextView takePhoto;
@ViewInject(R.id.select_from_album)
private TextView openAlbum;
@ViewInject(R.id.cancel_photo)
private TextView cancel; private String photoFileSavePath;
private String croppedFileSavePath;
private boolean isCrop; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_takephoto_popup);
ViewUtils.inject(this); Intent intent = getIntent();
if (intent != null) {
photoFileSavePath = intent.getStringExtra("photoFileSavePath");
croppedFileSavePath = intent.getStringExtra("croppedFileSavePath");
isCrop = intent.getBooleanExtra("isCrop", false);
}
} @OnClick({ R.id.take_photo, R.id.select_from_album, R.id.cancel_photo, R.id.takephoto_popup_layout })
public void buttonOnclick(View v) {
switch (v.getId()) {
case R.id.take_photo:
openCamera(photoFileSavePath);
break;
case R.id.select_from_album:
openAlbum();
break;
case R.id.cancel_photo:
finish();
break;
case R.id.takephoto_popup_layout:
finish();
break;
}
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); try {
if (requestCode == REQUEST_CODE_CAMERA && resultCode == Activity.RESULT_OK) { // 相机
if (isCrop) {
// 裁剪
cropImage(photoFileSavePath, croppedFileSavePath);
} else {
// 不裁剪
EventBus.getDefault().post(new TakePhotoOutputEvent(requestCode, resultCode, photoFileSavePath));
finish();
}
} else if (requestCode == REQUEST_CODE_ALBUM && resultCode == Activity.RESULT_OK) { // 相册
try {
// 得到图片路径
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picPath = cursor.getString(columnIndex);
cursor.close(); if (isCrop) {
cropImage(picPath, croppedFileSavePath);
} else {
EventBus.getDefault().post(new TakePhotoOutputEvent(requestCode, resultCode, picPath));
finish();
}
} catch (Exception e) { }
} else if (requestCode == REQUEST_CODE_CROP && resultCode == Activity.RESULT_OK) { // 裁剪回来
EventBus.getDefault().post(new TakePhotoOutputEvent(requestCode, resultCode, croppedFileSavePath));
finish();
}
} catch (Exception e) {
e.printStackTrace();
}
} public void openAlbum() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, REQUEST_CODE_ALBUM);
} /**
* 裁剪相册照片
*
*/
public void cropImage(String originFilePath, String croppedFilePath) {
File originFile = new File(originFilePath);
if (originFile == null || !originFile.exists()) {
return;
} try {
if (croppedFilePath == null) {
croppedFilePath = getExternalFilesDir(null) + "/" + "tmpcropped.png";
this.croppedFileSavePath = croppedFilePath;
} Uri originUri = Uri.fromFile(new File(originFilePath));
Uri croppedFileUri = Uri.fromFile(new File(croppedFilePath));
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(originUri, "image/*");
intent.putExtra("crop", true);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 120);
intent.putExtra("outputY", 120);
intent.putExtra("return-data", true);
intent.putExtra("output", croppedFileUri);
startActivityForResult(intent, REQUEST_CODE_CROP);
} catch (Exception e) {
e.printStackTrace();
}
} private void openCamera(String filePath) {
try {
if (filePath == null) {
filePath = getExternalFilesDir(null) + "/" + "tmpcamera.png";
this.photoFileSavePath = filePath;
} Uri uri = Uri.fromFile(new File(filePath));
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, REQUEST_CODE_CAMERA);
} catch (Exception e) {
e.printStackTrace();
}
}
}

demo github: https://github.com/lesliebeijing/AndroidPickPhotoComponent

android 拍照和从相册选择组件的更多相关文章

  1. Android 拍照或者从相册获取图片的实现

    我们常常会用到上传头像,或者发帖子的时候选择本地图片上传的功能.这个很常见 今天因为app的需求我研究了下.现在分享下. 其实不论是通过拍照还是从相册选取都会用到Intent 这是系统提供给我们用来调 ...

  2. 浅谈Android中拍照、从相册选择图片并截图相关知识点

    前言 我们在Android开发中经常会需要使用相机或者从相册中选取图片的情况,今天就把这里面相关的知识点总结下,方便以后开发的时候使用. 1.相机拍照并可自定义截图功能 我们先来看如何使用Intent ...

  3. android --拍照,从相册获取图片,兼容高版本,兼容小米手机

    前几天做项目中选择图片的过程中遇到高版本和小米手机出现无法选择和崩溃的问题,现在记录下来,后面出现同类问题,也好查找 1,定义常量: private static final int TAKE_PIC ...

  4. vue+uniapp实现美颜拍照录像,相册选择 | 录像限制时长,美颜拍照录像

    一.插件简介 Zhimi-BeautyCamera(智密 - 美颜相机图册插件)是一个支持美颜录像,美颜拍照,选择图视频功能,带录像参数时长限制的uniapp原生插件.平台支持:Android.IOS ...

  5. ng-cordova 手机拍照或从相册选择图片

    1.需求描述 实现一个调用摄像头拍照,或者直接打开本地图库选择照片,然后替换App中图片的功能 2.准备 1) 安装ng-cordova 进入到ionic工程目录,使用bower工具安装, bower ...

  6. Android 拍照或从相册取图片并裁剪

    在Android中,Intent触发Camera程序,拍好照片后,将会返回数据,但是考虑到内存问题,Camera不会将全尺寸的图像返回给调用的Activity,一般情况下,有可能返回的是缩略图,比如1 ...

  7. Android 拍照、从相册获取及裁剪的相关实现

    首先这些功能都是通过Intent去启动系统的服务去实现的,所以自然就有相应的Action.相关Actiong如下: 拍照——MediaStore.ACTION_IMAGE_CAPTURE (" ...

  8. Android拍照和从相册获取照片

    1.从相册获取照片 private void openAlumb() { //mRxPermissions:三方权限库 mRxPermissions .request(Manifest.permiss ...

  9. 在微信移动端input file拍照或从相册选择照片后会自动刷新页面退回到一开始网站进入的页面

    <input type="file" accept="image/*"/> 调用打开摄像头后,聚焦后拍照,点击确认,这时页面会出现刷新动作,然后回退 ...

随机推荐

  1. 安装Python-Windows

    安装Python-Windows 在开始Python编程前,需要先安装Python环境.Python安装包可以到Python的官网下载,官网地址是https://www.python.org/,如果想 ...

  2. 疑难杂症--已停止运行DBCC造成阻塞

    场景数据库因非法断电导致出现分配页上不一致,运行完DBCC CHECKDB后出现以下错误: 表错误: 表 't_pc_id' (ID 277576027).数据行在索引 'last_login_dat ...

  3. 查看iptables状态-重启

    iptables 所在目录 /etc/sysconfig/iptables service iptables status 查看iptables状态 service iptables restart ...

  4. Django集成TinyMCE(admin后台+前台)

    Django版本1.11,操作系统windows 7,在pycharm的terminal中使用pip install django-tinymce下载tinymce(前提是装的python里有pip功 ...

  5. js计算机样式window.getComputedStyle(ele,null)2

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. “全栈2019”Java第五十八章:多态中方法返回类型可以是子类类型

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. Elasticsearch NEST使用指南:映射和分析

    NEST提供了多种映射方法,这里介绍下通过Attribute自定义映射. 一.简单实现 1.定义业务需要的POCO,并指定需要的Attribute [ElasticsearchType(Name = ...

  8. Extjs在form展示后台单个对象的属性

    目的:写一个按钮事件,点击时弹出一个win窗体,里面镶嵌form表单,并且展示后台单个对象的属性 先来后台: public void find(){ String clientId = request ...

  9. 海思hi35xx 开发学习(2):系统控制

    应用程序启动 MPP 业务前,必须完成 MPP 系统初始化工作.同理,应用程序退出MPP 业务后,也要完成 MPP 系统去初始化工作,释放资源. 视频缓存池 一组大小相同.物理地址连续的缓存块组成一个 ...

  10. MYSQL ERROR 1049 (42000): Unknown database

    https://www.cnblogs.com/hedgehog105/p/10196566.html lower_case_table_names=2