在Android中,经常会需要启动相机和启动相册两个功能,之前学习迷迷糊糊,现在重新学习有一些心得,记录下来。
在这里首先说明一些东西:
内容提供者中 getContentResolver()中可以理解为系统提供的所有内容,像是一个大的数据库,其中的查询方法可以查询手机中所有的内容,而具体是什么内容,也就是URI来决定的,URI分为两个部分,前面的部分是应用的名称,这里可以理解为具体的数据库名字,后面的参数是表名,在后面是一些查询条件。
- 1 启动相机:
启动相机的话很简单,代码如下:
Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file=new File(getExternalCacheDir(),"test.jpg");
uri =Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);
startActivityForResult(intent,1);
为Intent添加一个隐式意图,字符串MediaStore.ACTION_IMAGE_CAPTURE,这里需要讲一下,在Android中所有的多媒体信息都保存在MediaStore这个类中,它还有4个子类,分别为MediaStore.File,MediaStore.Images,MediaStore.Audio,MediaStore.Video,对应这文件,图片,音频,视频。在这其中,MediaStore还有一些字符串:
1. ACTION_IMAGE_CAPTURE:标准的调用摄像头,来获取抓拍图片。
2. ACTION_VIDEO_CAPTURE:标准的调用摄像头,来获取视频。
3. INTENT_ACTION_MUSIC_PLAYER:启动音乐播放器。
4. INTENT_ACTION_VIDEO_CAMERA:以摄像机的方式启动camera
5. EXTRA_OUTPUT:用来定义一个指定的路径,用来保存image或是video
这些是在多媒体中常用到的一些字符串。
另外,在Android高版本中,文件操作都要在getExternalCacheDir()下,这个是文件关联目录,在Android6.0以后读写SD卡都是危险的权限,必须动态申请才可以使用,而这个文件关联目录不需要动态申请即可使用,它的目录是/sdcard/Android/data/< package name>/cache ,然后intent中填入数据,第一个键为EXTRA_OUTPUT:用来定义一个指定的路径,用来保存image或是video ,第二个值是uri,这个uri需要用uri.fromfile(),参数为我们创建的file来创建uri,然后使用startActivityForResult这个方法来打开相机
打开相机拍照以后,会回调onActivityResult这个方法:
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
}
这里面有三个参数,第一个参数是请求码,第二个参数为结果码,第三个参数就是之前我们启动其他应用程序/Activity后,返回来的intent,其中包含了一些我们所需要的各种参数或者数据。
要得到我们之前拍摄的照片有两种方法,第一种获得缩略图,即不清晰的图片:
switch (requestCode) {
case 1: {
if(resultCode==RESULT_OK){
Bundle bundle = data.getExtras();
Bitmap bitmap= (Bitmap) bundle.get("data");
img.setImageBitmap(bitmap);
}
break;
}
这里我们需要判断结果码是否是OK,如果是OK的话才能进行下一步,然后我们从intent中得到bundle,bundle中存储了刚才拍摄的缩略图,键名为data,然后直接设置就可以了。
还有一种是存储在文件中,我们从文件中获得图像,这里如果知道图像地址可以直接用file来获得图像,但是这次不用这种方式,而是用:
switch (requestCode) {
case 1: {
if(resultCode==RESULT_OK){
try {
Bitmap bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
img.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
因为我们有了uri,可以通过内容提供者中获得输入流的方式得到文件对象。关于这个内容提供者,在android中加入了文件内容提供者,这里不再赘述。这就是启动相机并且获得图像的所有过程。
- 2 启动相册
启动相册也是使用intent的隐式意图:
public void call() {
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 2);
}
第一个参数为action,第二个参数为URI,也可以使用intent.setdata()方法设置。这样就启动了相册。在onActivityResult方法中,代码如下:
case 2:{
if(resultCode==RESULT_OK&&data!=null){
//所有的结果都在data返回的数据中,此处是返回的表名,也就是下面要查询的表名
Uri uri1 = data.getData();
//此处是列名,列名是固定的
String filepathcolunm[]={MediaStore.Images.Media.DATA};
//此处查询是查不同的表中相同的列名,得到相应的地址,得到结果集以后通过结果集查询列名所在的索引,
// 我猜测是一张表中只有一个照片,然后移动到第一个,通过索引得到相片真实地址
Cursor cursor = getContentResolver().query(uri1, filepathcolunm, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filepathcolunm[0]);
//此处得到相片的真实地址
String imgpath=cursor.getString(columnIndex);
img.setImageBitmap(BitmapFactory.decodeFile(imgpath));
cursor.close();
}
}
至此,启动相机和启动相册选择图片都已经完毕。总结一下:
- 启动相机:
1 构造File对象,用于保存拍摄的照片
2 构造Intent,隐式意图启动相机
3 通过URI.Fromfile方法得到uri,设置intent.putExtra
4 启动相机
5 再回调方法中使用内容提供者的方法,传入uri获得bitmap对象
6 设置图像 - 启动相册
1 构造Intent,隐式意图启动相册
2 在回调方法中得到选择图片的uri,也就是表名
3 通过内容提供者查询uri和列名,得到结果集
4 将结果集移动到第一行,查询列名所对应的索引,通过索引查询图片的真实路径
最后,发现很多不足,很多字符串不明白意思,并没有完全理解uri的意思,通过此节,明白许多。