Android中相机使用基础,使用系统自带的相机App。
相机使用基础之 调用系统中的相机应用
通过Intent直接调用系统相机
直接调用系统的相机应用,只需要在Intent对象中传入相应的参数即可,总体来说需要以下三步:
1. Compose a Camera Intent
MediaStore.ACTION_IMAGE_CAPTURE
拍照;
MediaStore.ACTION_VIDEO_CAPTURE录像。
2. Start the Camera Intent
使用startActivityForResult()方法,并传入上面的intent对象。
之后,系统自带的相机应用就会启动,用户就可以用它来拍照或者录像。
3. Receive the Intent Result
用onActivityResult()
接收传回的图像,当用户拍完照片或者录像,或者取消后,系统都会调用这个函数。
关于接收图像
如果不设置接收图像的部分,拍照完毕后将会返回到原来的activity,相片会自动存储在拍照应用的默认存储位置。
为了接收图像,需要做以下几个工作:
1.指定图像的存储位置,一般图像都是存储在外部存储设备,即SD卡上。
你可以考虑的标准的位置有以下两个:
Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES
)
如果你的应用被卸载了,这个路径下的文件是会保留的。
为了区分,你可以在这个路径下为你的应用创建一个子文件夹。
Context.getExternalFilesDir
(Environment.DIRECTORY_PICTURES
)
这个方法返回的路径是和你的应用相关的一个存储图像和视频的方法。
如果应用被卸载,这个路径下的东西全都会被删除。
这个路径没有什么安全性限制,别的应用也可以自由访问里面的文件。
2.为了接收intent的结果,需要覆写activity中的 onActivityResult()
方法。
Intent data不为null,照片存在系统默认的图片存储路径下。
MediaStore.EXTRA_OUTPUT作为关键字。
Intent data为null。
程序实例
附上程序代码,其中视频存储的返回结果部分没有写代码,视频拍摄后会存入系统应用的默认位置。
系统自带相机应用测试
package com.example.hellocamera;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
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.Toast;
public class HelloCameraActivity extends Activity
{
private static final String LOG_TAG = "HelloCamera";
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
private Button takePicBtn = null;
private Button takeVideoBtn = null;
private ImageView imageView = null;
private Uri fileUri;
@Override
public void onCreate(Bundle savedInstanceState)
{
Log.d(LOG_TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello_camera);
takePicBtn = (Button) findViewById(R.id.buttonPicture);
takePicBtn.setOnClickListener(takePiClickListener);
takeVideoBtn = (Button) findViewById(R.id.buttonVideo);
takeVideoBtn.setOnClickListener(takeVideoClickListener);
imageView = (ImageView) findViewById(R.id.imageView1);
}
private final OnClickListener takePiClickListener = new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Log.d(LOG_TAG, "Take Picture Button Click");
// 利用系统自带的相机应用:拍照
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// create a file to save the image
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
// 此处这句intent的值设置关系到后面的onActivityResult中会进入那个分支,即关系到data是否为null,如果此处指定,则后来的data为null
// set the image file name
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
};
private final OnClickListener takeVideoClickListener = new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Log.d(LOG_TAG, "Take Video Button Click");
// 摄像
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
// create a file to save the video
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
// set the image file name
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// set the video image quality to high
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
}
};
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type)
{
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type)
{
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = null;
try
{
// This location works best if you want the created images to be
// shared
// between applications and persist after your app has been
// uninstalled.
mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraApp");
Log.d(LOG_TAG, "Successfully created mediaStorageDir: "
+ mediaStorageDir);
}
catch (Exception e)
{
e.printStackTrace();
Log.d(LOG_TAG, "Error in Creating mediaStorageDir: "
+ mediaStorageDir);
}
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists())
{
if (!mediaStorageDir.mkdirs())
{
// 在SD卡上创建文件夹需要权限:
// <uses-permission
// android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Log.d(LOG_TAG,
"failed to create directory, check if you have the WRITE_EXTERNAL_STORAGE permission");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE)
{
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
}
else if (type == MEDIA_TYPE_VIDEO)
{
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
}
else
{
return null;
}
return mediaFile;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
Log.d(LOG_TAG, "onActivityResult: requestCode: " + requestCode
+ ", resultCode: " + requestCode + ", data: " + data);
// 如果是拍照
if (CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE == requestCode)
{
Log.d(LOG_TAG, "CAPTURE_IMAGE");
if (RESULT_OK == resultCode)
{
Log.d(LOG_TAG, "RESULT_OK");
// Check if the result includes a thumbnail Bitmap
if (data != null)
{
// 没有指定特定存储路径的时候
Log.d(LOG_TAG,
"data is NOT null, file on default position.");
// 指定了存储路径的时候(intent.putExtra(MediaStore.EXTRA_OUTPUT,fileUri);)
// Image captured and saved to fileUri specified in the
// Intent
Toast.makeText(this, "Image saved to:\n" + data.getData(),
Toast.LENGTH_LONG).show();
if (data.hasExtra("data"))
{
Bitmap thumbnail = data.getParcelableExtra("data");
imageView.setImageBitmap(thumbnail);
}
}
else
{
Log.d(LOG_TAG,
"data IS null, file saved on target position.");
// If there is no thumbnail image data, the image
// will have been stored in the target output URI.
// Resize the full image to fit in out image view.
int width = imageView.getWidth();
int height = imageView.getHeight();
BitmapFactory.Options factoryOptions = new BitmapFactory.Options();
factoryOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileUri.getPath(), factoryOptions);
int imageWidth = factoryOptions.outWidth;
int imageHeight = factoryOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(imageWidth / width, imageHeight
/ height);
// Decode the image file into a Bitmap sized to fill the
// View
factoryOptions.inJustDecodeBounds = false;
factoryOptions.inSampleSize = scaleFactor;
factoryOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
factoryOptions);
imageView.setImageBitmap(bitmap);
}
}
else if (resultCode == RESULT_CANCELED)
{
// User cancelled the image capture
}
else
{
// Image capture failed, advise user
}
}
// 如果是录像
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE)
{
Log.d(LOG_TAG, "CAPTURE_VIDEO");
if (resultCode == RESULT_OK)
{
}
else if (resultCode == RESULT_CANCELED)
{
// User cancelled the video capture
}
else
{
// Video capture failed, advise user
}
}
}
}
程序运行截图,拍照之后返回:
参考资料
Reference: Camera:http://developer.android.com/reference/android/hardware/Camera.html
API Guides: Camera: http://developer.android.com/guide/topics/media/camera.html
作者: 圣骑士Wind
Github: https://github.com/mengdd