最近有一个需求,是类似于手机相机的功能,拍照,多次拍照(调用系统相机只能进行一次拍照),拍照页面显示一个拍照后的缩略图,点击缩略图后进行拍过的照片的筛选(有单选和多选的问题),以及后续操作(设计相关业务),本篇博客是在搜索后,进行相关测试后才写的,已备后用。
先上效果图:测试的手机三种,分别是魅族,小米和华为。
魅族(1920*1080):
小米(1280*720):
华为(1280*720):
直接上代码:
布局文件activity_pickpic.xml
TestOpenPhoneActivity.Java文件:
package com.jkinfo.runtimetest;
import java.io.IOException;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class TestOpenPhoneActivity extends Activity {
private Button btnPhone;
private ImageView imageView;
private static final String IMAGE_UNSPECIFIED = "image/*";
private final int IMAGE_CODE = 0; // 这里的IMAGE_CODE是自己任意定义的
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pickpic);
btnPhone = (Button) findViewById(R.id.btnPhone);
imageView = (ImageView) findViewById(R.id.imageView);
tv = (TextView) findViewById(R.id.img_path);
btnPhone.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
setImage1(); // 魅族显示风格:最新,照片,图库;华为:包含有相片的一组目录,
// 小米:选择要使用的应用,最后没有结果
// setImage(); //魅族显示风格:图库,文件选择(图片文件) ;华为:最近的照片 小米:选择要使用的应用,最后没有结果
}
});
}
private void setImage1() {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);
startActivityForResult(intent, IMAGE_CODE);
}
private void setImage() {
// TODO Auto-generated method stub
// 使用intent调用系统提供的相册功能,使用startActivityForResult是为了获取用户选择的图片
Intent getAlbum = new Intent(Intent.ACTION_GET_CONTENT);
getAlbum.setType(IMAGE_UNSPECIFIED);
startActivityForResult(getAlbum, IMAGE_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
Bitmap bm = null;
// 外界的程序访问ContentProvider所提供数据 可以通过ContentResolver接口
ContentResolver resolver = getContentResolver();
if (requestCode == IMAGE_CODE) {
try {
Uri originalUri = data.getData(); // 获得图片的uri
bm = MediaStore.Images.Media.getBitmap(resolver, originalUri);
imageView.setImageBitmap(ThumbnailUtils.extractThumbnail(bm, 100, 100)); //使用系统的一个工具类,参数列表为 Bitmap Width,Height 这里使用压缩后显示,否则在华为手机上ImageView 没有显示
// 显得到bitmap图片
// imageView.setImageBitmap(bm);
String[] proj = { MediaStore.Images.Media.DATA };
// 好像是android多媒体数据库的封装接口,具体的看Android文档
Cursor cursor = managedQuery(originalUri, proj, null, null, null);
// 按我个人理解 这个是获得用户选择的图片的索引值
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
// 将光标移至开头 ,这个很重要,不小心很容易引起越界
cursor.moveToFirst();
// 最后根据索引值获取图片路径
String path = cursor.getString(column_index);
tv.setText(path);
} catch (IOException e) {
Log.e("TAG-->Error", e.toString());
}
finally {
return;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
代码中的关键代码已经加有注释,不再过多解释。
说明: 设置了压缩显示的图片是100*100,在高分辨屏幕上看相对于低分辨率屏幕的看起来有点小,在小米上完全没有效果。
吐槽点:需求是一样的,但是实际的效果确实五花八门,这或许就是安卓开发中的痛点和要踩的坑。不过要放平心态,涨姿势长见识了,长经验了····
总结:1.获取缩略图这一点,饶了很大的弯路,后来发现,Android 官方API里面就有ThumbnailUtils工具类。
2.对多媒体的掌握和认识还不是很熟悉。大家可以看下我最后的参考资料。
感谢网络上的无私分享奉献者!
参考资料:
0.Android图形系统之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的联系
1.Android学习笔记进阶20之得到图片的缩略图
2.Android自定义相机拍照、图片裁剪的实现
3.Android 高仿微信 获取最近刚刚拍照的缩略图 功能实现
4.【Android】自定义相机的实现(支持连续拍照、前后摄像头切换、连续对焦)
再次感谢博主作者!