<span style="font-size:18px;">import java.io.IOException;
import java.util.List;
import android.annotation.TargetApi;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
public class CrimeCameraFragment extends Fragment {
private static final String TAG="CrimeCameraFragment";
private Camera mCamera;
private SurfaceView mSurfaceView;
private Size getBestSupportedSize(List<Size> sizes,int width,int height){
Size bestSize=sizes.get(0);
int largestArea=bestSize.width*bestSize.height;
for(Size s:sizes){
int area=s.width*s.height;
if(area>largestArea){
bestSize=s;
largestArea=area;
}
}
return bestSize;
}
@SuppressWarnings("deprecation")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,Bundle savedInstanceState){
<span style="color:#ff0000;">Log.d(TAG,"onCreateView() calling...");</span>
View v=inflater.inflate(R.layout.fragment_crime_camera, parent,false);
Button takePictureButton=(Button)v.findViewById(R.id.crime_camera_takePictureButton);
takePictureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
getActivity().finish();
}
});
mSurfaceView=(SurfaceView)v.findViewById(R.id.crime_camera_surfaceView);
SurfaceHolder holder=mSurfaceView.getHolder();
//setType() and SURFACE_TYPE_PUSH_BUFFERS are both deprecated
//but are required for Camera preview to work on pre-3.0 devices.
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if(mCamera!=null){
mCamera.stopPreview();
<span style="color:#ff0000;">Log.d(TAG,"holder.surfaceDestroyed() called");</span>
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try{
if(mCamera!=null){
mCamera.setPreviewDisplay(holder);
<span style="color:#ff0000;">Log.d(TAG,"holder.surfaceCreated() called");</span>
}
}catch(IOException e){
<span style="color:#ff0000;">Log.e(TAG,"Error setting up preview display",e);</span>
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(mCamera==null) {
<span style="color:#ff0000;">Log.d(TAG,"calling surfaceChanged,mCamera==null");</span>
return;
}
//The surface has changed size;update the camera preivew size
Camera.Parameters parameters=mCamera.getParameters();
// Size s=null; //To be reset in the next section
//get the best supportedsize
Size s=getBestSupportedSize(parameters.getSupportedPreviewSizes(),width,height);
parameters.setPreviewSize(s.width, s.height);
mCamera.setParameters(parameters);
try{
mCamera.startPreview();
<span style="color:#ff0000;">Log.d(TAG,"mCamera.startPreview() called");</span>
}catch(Exception e){
<span style="color:#ff0000;">Log.e(TAG,"Could not start preview",e);</span>
mCamera.release();
mCamera=null;
}
}
});
<span style="color:#ff0000;">Log.d(TAG,"leaving onCreateView()");</span>
return v;
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@Override
public void onResume(){
super.onResume();
<span style="color:#ff0000;">Log.d(TAG,"onResume() calling");</span>
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.GINGERBREAD){
mCamera=Camera.open(0);
<span style="color:#ff0000;">Log.d(TAG,"Camera.open(0) called");</span>
}else{
mCamera=Camera.open();
Log.d(TAG,"Camera.open() called");
}
}
@Override
public void onPause(){
super.onPause();
if(mCamera!=null){
mCamera.release();
mCamera=null;
<span style="color:#ff0000;">Log.d(TAG,"onPaused() called");</span>
}
}
}</span>
启动Camera的Fragment代码如上所示,在关键处调用了Lod.d( TAG, String )函数,用以追踪代码执行流程,在Logcat中捕获的Log信息如下图:
由Logcat可以看出,在调用完 onCreateView()后,函数系统才调用onResume()函数,在onResume()函数中代开摄像头,调用了代码:
<span style="font-size:18px;">mCamera=Camera.open(0);
Log.d(TAG,"Camera.open(0) called");</span>
然后才相继调用SurfaceView的Holder添加的回调函数 surfaceCreated(SurfaceHolder holder) 和 surfaceChanged(Surfaceholder holder , int format ,int width , int height)。
当从SurfaceView返回时,调用 onPause()函数,在onPause()函数中释放摄像头资源。
最后才调用了 surfaceDestroyed(SurfaceHolder holder),而此时 mCamera资源已经被释放了。