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. ssm集合的配置

    web.xml <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quo ...

  2. CentOS下安装PHP的AMQP扩展方法和步骤

    AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.基于此协议的客户端 ...

  3. java-设计模式汇总整理

    最近,对各种模式做了一个整理,便于后续自用. 1.工厂模式 总结:很好理解,一个接口,2个类实现这个接口,那么可以用“接口 变量=new 接口实现类”的方式调用不同的实现类,调用方式直接使用接口的方法 ...

  4. wpf Route Event Code Snippet

    将下面内容保存为snippet后缀文件,通过vs的代码片段管理工具导入即可,快捷键请按需修改: <?xml version="1.0" encoding="utf- ...

  5. HTML5 开发APP 第一章

    当今天下,移动端基本上是安卓和苹果的天下,基本上没微软什么事,作为微软忠实的支持者,也要顺势而变. 但安卓和IOS  开发是两个完全不同的世界,有没有一种技术,开发完以后可以运行在任意终端呢,答案是有 ...

  6. 理解图像Garbor和HOG特征的提取方法及实例应用

    前言:今天接触到了这两个特征,看了课本和博客后很蒙蔽,没有理解这两个特征,本篇博客的目的是只是参考其他的博客总结这两个特征,如果未来能研究和工作领域是这方面的话再回来自己研学,如有错误也欢迎指出. G ...

  7. How to mount a remote directory in Linux using sshfs

    Q. I have access rights to one of the remote server through SSH protocol and there is no File share ...

  8. 【线程】结果缓存实现(future与concurrenthashmap)

    Computable<A,V>接口中生命了一个函数Computable,其输入类型为A,输出类型为V,在ExpensiveFunction中实现的Computable,需要很长时间来计算结 ...

  9. nginx如何设置禁止访问文件或文件夹

    目标: 1. 根目录 webroot: 2. 设置目标文件 /webroot/proj/deny.txt 不能访问: 做法: 1. 设置 nginx.conf ,添加一个“location”段落: 2 ...

  10. MySQL使用UNIQUE实现数据不重复插入

    unique列在一个UNIQUE键上插入包含重复值的记录时,我们可以控制MySQL如何处理这种情况:使用IGNORE关键字或者ON DUPLICATE KEY UPDATE子句跳过INSERT.中断操 ...