这两天看了下官方关于camera的api,然后了解到可以通过调用系统的Camera和自定义相机两种方式。现在我来介绍简单的,也是菜鸟选手轻松入门的这种。通过调用自带的相机拍照并获取图片,设定到imageview上。
通过官方API的介绍,调用系统的相机,我们需要下面几个步骤。
1 传入对应的intent的Action, ACTION_IMAGE_CAPTURE
2 设定图片存放的位置,也默认的位置,但是一般都自己设定下。intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
3 通过startActivityForResult和onActivityResult来启动相机和监视相机的完成。
下面贴上代码:
public class MainActivity extends Activity {
private static final int PICTURE=100; //常量,请求访问的标志
private TextView tv;
private ImageView iv;
private Uri uri;//Uri对象,这里传入的位置,第二个参数是Uri的类型
private File file2;//文件的路径
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
iv = (ImageView) findViewById(R.id.iv);
//点击TextView 然后打开相机
tv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//相机的action
String path = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"ABC";//建立一个指定目录
File file = new File(path);
if(!file.exists()){//判断文件夹是否存在,不存在,就创建
file.mkdirs();
}
file2 = new File(file,System.currentTimeMillis()+".jpg");//建立文件的存放路径
uri = Uri.fromFile(file2);//将File类型转换为Uri类型
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);//设定图片的存放路径
startActivityForResult(intent, PICTURE);
}
});
}
//如果相机拍摄完成 或者取消都会调用这个方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==PICTURE){
if(getIntent()==null){//这里 不判断方法名上面的data,这里是null,暂时不知道为什么。
return;
}
try {
InputStream is = new FileInputStream(file2.getPath());//获取路径的io输入流
Bitmap pic = BitmapFactory.decodeStream(is);//转换成bitmap对象
iv.setImageBitmap(pic);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
布局文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >
<TextView
android:id="@+id/tv"
android:textSize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<ImageView
android:id="@+id/iv"
android:layout_width="300dp"
android:layout_height="300dp"
android:scaleType="fitXY"
/>
</LinearLayout>
这里因为是调用系统的相机,并不需要mainfest里面加入权限什么的,如果是我们自己的相机,根据api的说明一般需要以下几个:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.CAMERA"/>
调用相机的相关都在代码中详细注释了。可以参考。另外,官方提到现在这个推荐使用camera2这个新的api,后面会针对自定义和camera2继续学习并写下心得。
昨天用的是毫米值取设定的文件名,看起来怪怪的,现在使用年月日-时分秒 去设定,
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "IMG_" + timeStamp ;
file2 = new File(file,imageFileName+".jpg");
1 刚才无意中看到大神说了我们上面提到的问题 “不过因为当传入文件路径的的情况下,data返回参数是null值”。当我们不传入路径时,在onActivityResult方法中可以通过返回的data拿到拍摄的图片,Bitmap bmp = (Bitmap)data.getExtras().get("data");然后拿到缩放图片的数据
Log.d("Test", "bmp width:" + bmp.getWidth() + ", height:" + bmp.getHeight());
2 我们设定图片还可以用setImageURI(uri)没错还有这个方法,我也惊呆了,官方想的果然很周到,这样不需要转换了。