为了专注技术开发,与开发中的经验总结,我赖坤奇决定从今天开始分享Java、Android开发过程中的一点经验,算记录开发过程中历程,方便以后回顾,也希望遇到大牛多加指点。共同进步。
这篇文章实现的是如何使用Android来实现应用内打开相册、打开照相机拍照并按要求裁剪保存的干货,分享给各位。
首先,需要在Manifest文件目录中添加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.CAMERA" />
需要用到写、读SD卡,打开照相机等权限。
在MainActivity的布局xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="拍照"
android:onClick="onCapture"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="从相册获取"
android:onClick="onChoose"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/iv"/>
</LinearLayout>
在Android系统中,多媒体库是通过MediaScanner去扫描磁盘文件,对元信息的处理,并通过MediaProvider保存到MediaStore中。下图为MediaScannerr 框架:
媒体文件可以存储在手机终端的内存中,也可以存储在SD卡中,Android平台中称手机终端内存为内部存储空间,称SD卡为外部存储空间。针对内部和外部存储空间中的媒体文件信息是分开管理的,各自有独立的数据库管理。因此在扫描媒体文件时,要明确指明扫描的媒体文件是位于内部存储空间还是外部存储空间。外部存储空间和内部存储空间对应的卷标为”external”和”internal”。
学习过ContentProvider,对于图像(以及音频和视频)的标准内容提供器是MediaStore,MediaStore类是Android平台的多媒体数据库,它包含了音频,视频,图片等所有多媒体文件信息。本文将重点介绍如何管理和获取音频信息,视频和图片等信息的获取与管理与音频类似。
废话不多说,直接上MainActivity的代码实现:
在activity中声明控件与定义常量请求码等成员变量。
private ImageView miv;
/** 拍照后保存图片的路径*/
File mFile;
//定义requestCode
static final int ACTION_CAPTURE=1;
static final int ACTION_CHOOSE=2;
static final int ACTION_CROP=3;
在onCreate中初始化控件,并未两个Button控件添加点击事件。设置意图action为MediaStore.ACTION_IMAGE_CAPTURE,同时设置输出流,拍照保存位置,文件位置为外部sd卡图片存放目录,名称为系统当前时间毫秒值,即给意图附加值
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mFile));
最后使用startActivityForResult()方法发送意图,打开拍照的activity。
打开相册activity同样如下:
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"
具体代码为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
miv = (ImageView) findViewById(R.id.iv);
}
/**
* 拍照按钮的点击事件响应
* @param view
*/
public void onCapture(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
mFile= new File(dir, System.currentTimeMillis() + "");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mFile));
startActivityForResult(intent,ACTION_CAPTURE);
}
/**
* 相册选取按钮的点击事件响应
* @param view
*/
public void onChoose(View view) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, ACTION_CHOOSE);
}
在Activity中复写onActivityResult(int requestCode, int resultCode, Intent data)方法,对拍照,相册的intent中对数据进行处理。根据requestCode进行分类处理,并使用安卓系统自带裁剪activity对托片进行处理。具体代码如下:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (RESULT_OK != resultCode) {
return;
}
switch (requestCode) {
case ACTION_CAPTURE:
Log.i("main","拍照完毕,结果保存在:"+mFile.getAbsolutePath());
//启动系统裁剪的Activity
startCropActivity(Uri.fromFile(mFile),200,200,ACTION_CROP);
break;
case ACTION_CHOOSE:
Log.i("main","相册选取完毕");
//启动系统裁剪的Activity
startCropActivity(data.getData(),200,200,ACTION_CROP);
break;
case ACTION_CROP:
showPhoto(data);
break;
}
}
裁剪的方法实现,设置intent的action为com.android.camera.action.CROP,根据系统预定好的key值为intent设定value,传递给系统自带裁剪活动。
private void startCropActivity(Uri uri, int outputX, int outputY, int requestCode) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("outputX",outputX);
intent.putExtra("outputY", outputY);
//保存裁剪的结果
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
//设置是否返回数据
intent.putExtra("return-data", true);
//设置保存图片的类型
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent,requestCode);
}
把裁剪后返回的intent中获取data进行imageView的展示,方法如下:
private void showPhoto(Intent data) {
Bundle extras = data.getExtras();
Bitmap bitmap = extras.getParcelable("data");
miv.setImageBitmap(bitmap);
}
好了,安卓开发程序猿小赖,第一次展示开发的经验干货送上,希望对各位开发有点帮助!!
可加本人QQ:781548819,方便交流。我会持续不断的吧自己安卓开发中的一些东西分享出来,也方便自己的成长。谢谢!!~~