@flyouting
2014-03-19T11:08:14.000000Z
字数 4535
阅读 5137
这是基于Android Studio及Fragment的相机开发的第一章,如果你还没准备好,先去github上拉一下我的一个示例工程。本章主要包含“SimpleCameraIntentFragment.”
在我们开始之前,我想花点时间讨论设备性能和重要的检查,这些都是我们应该发布一个使用相机的应用之前考虑的。
记住,市场上有很多Android设备能够运行你的应用,因此重要的是要做一些检查,以确保设备能够执行您想要执行的操作。
<uses-feature android:name="android.hardware.camera" android:required="true"/>
Context context = getActivity();
PackageManager packageManager = context.getPackageManager();
if(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA) == false){
Toast.makeText(getActivity(), "This device does not have a camera.", Toast.LENGTH_SHORT) .show();
return;
}
在一些Android设备您可能还需要考虑下前后摄像头。您可以使用包管理器检查相机功能,代码如下:
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)
常用的检查:
打开实例程序,我们会看到
当你选择 “take photo”按钮,一个外部相机程序会被调起,结果会显示在主窗口,在一个小窗口会显示缩略图。
打开SimpleCameraIntentFragment.java 你会发现如下方法:
/**
* Start the camera by dispatching a camera intent.
*/
protected void dispatchTakePictureIntent() {
// Check if there is a camera.
Context context = getActivity();
PackageManager packageManager = context.getPackageManager();
if (packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA) == false) {
Toast.makeText(getActivity(), "This device does not have a camera.", Toast.LENGTH_SHORT)
.show();
return;
}
// Camera exists? Then proceed...
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
CameraActivity activity = (CameraActivity) getActivity();
if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) {
// Create the File where the photo should go.
// If you don't do this, you may get a crash in some devices.
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Toast toast = Toast.makeText(activity, "There was a problem saving the photo...",
Toast.LENGTH_SHORT);
toast.show();
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri fileUri = Uri.fromFile(photoFile);
activity.setCapturedImageURI(fileUri);
activity.setCurrentPhotoPath(fileUri.getPath());
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, activity.getCapturedImageURI());
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
我没有执行一个全面的相机硬件检查,只是执行了一个后置摄像头检查,如果设备之存在一个前置摄像头,那这个检查就会失败,
接下来就是接收和保存图片了,基本代码都是这样子:
/**
* The activity returns with the photo.
*
* @param requestCode
* @param resultCode
* @param data
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
addPhotoToGallery();
CameraActivity activity = (CameraActivity) getActivity();
// Show the full sized image.
setFullImageFromFilePath(activity.getCurrentPhotoPath(), mImageView);
setFullImageFromFilePath(activity.getCurrentPhotoPath(), mThumbnailImageView);
} else {
Toast.makeText(getActivity(), "Image Capture Failed", Toast.LENGTH_SHORT).show();
}
}
注意看如下代码:
Uri fileUri = Uri.fromFile(photoFile);
activity.setCapturedImageURI(fileUri);
activity.setCurrentPhotoPath(fileUri.getPath());
记住,由于我们在一个Fragment里使用了相机,有一些额外的步骤可以跳过,以保证所有功能都正常。
在某些Android设备(例如,一些三星设备),您可能需要将从Intent传回的相机图像保存到一个文件中。当应用程序返回到前台时,该文件将不再是可用的,并由此可能会导致崩溃且没有异常抛出。
为了防止这种事故,我已经创建了一个特别的Activity:“CameraActivity”自动保存和恢复你所需要保存和读取的相机文件和Uri数据,过程安全。
接下里看一看CameraActivity,我就不罗列所有的代码了,但是在这个Activity里你可以看到保存了相机文件和Uri数据,并在onResume里恢复数据。
// Storage for camera image URI components
private final static String CAPTURED_PHOTO_PATH_KEY = "mCurrentPhotoPath";
private final static String CAPTURED_PHOTO_URI_KEY = "mCapturedImageURI";
// Required for camera operations in order to save the image file on resume.
private String mCurrentPhotoPath = null;
private Uri mCapturedImageURI = null;
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
if (mCurrentPhotoPath != null) {
savedInstanceState.putString(CAPTURED_PHOTO_PATH_KEY, mCurrentPhotoPath);
}
if (mCapturedImageURI != null) {
savedInstanceState.putString(CAPTURED_PHOTO_URI_KEY, mCapturedImageURI.toString());
}
super.onSaveInstanceState(savedInstanceState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.containsKey(CAPTURED_PHOTO_PATH_KEY)) {
mCurrentPhotoPath = savedInstanceState.getString(CAPTURED_PHOTO_PATH_KEY);
}
if (savedInstanceState.containsKey(CAPTURED_PHOTO_URI_KEY)) {
mCapturedImageURI = Uri.parse(savedInstanceState.getString(CAPTURED_PHOTO_URI_KEY));
}
super.onRestoreInstanceState(savedInstanceState);
}
实际上我在这里做的是存储然后回调必要的路径信息,然后Android设备就得到了文件的引用并通过一个Intent去保存,没有这些代码,相机应用会在onResume时崩溃。
这就是我所要说的安全的在Fragment里使用相机Intent。大家可以自由发挥写出自己的调用相机的代码。
翻译:@flyouting
时间:2014/03/19
源地址