我正在制作Instagram应用程序,其中有不同的屏幕用于捕获图像和记录图像。我的问题是,当我用两个片段运行我的应用程序时,我的应用程序崩溃留下错误:
FATAL EXCEPTION: main
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.native_setup(Native Method)
at android.hardware.Camera.<init>(Camera.java:428)
at android.hardware.Camera.open(Camera.java:389)
at textileapp.ebizz.com.myapplication.VideoFragment.onCreateView(VideoFragment.java:55)
但是当我用一个片段运行我的应用程序时,无论是相机屏幕还是录像机屏幕,那么它运行正常。但两个片段在一起app崩溃。任何一个人都可以提供帮助。 我的代码:
相机碎片
import android.hardware.Camera;
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.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class CameraFragment extends Fragment implements View.OnClickListener, SurfaceHolder.Callback {
private View rootView;
private Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Camera.PictureCallback rawCallback;
Camera.ShutterCallback shutterCallback;
Camera.PictureCallback jpegCallback;
LinearLayout capture;
private int mId = 0;
ImageView change_camera, flash_icon;
private String mFlashMode="Camera.Parameters.FLASH_MODE_ON";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_camera, container, false);
defineIds(rootView);
handleClick();
change_camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Camera.getNumberOfCameras() >= 2) {
releaseCamera();
chooseCamera();
}
}
});
flash_icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mFlashMode.equalsIgnoreCase(Camera.Parameters.FLASH_MODE_AUTO)) {
mFlashMode = Camera.Parameters.FLASH_MODE_ON;
} else if (mFlashMode.equalsIgnoreCase(Camera.Parameters.FLASH_MODE_ON)) {
mFlashMode = Camera.Parameters.FLASH_MODE_OFF;
} else if (mFlashMode.equalsIgnoreCase(Camera.Parameters.FLASH_MODE_OFF)) {
mFlashMode = Camera.Parameters.FLASH_MODE_AUTO;
}
}
});
return rootView;
}
private void releaseCamera() {
// stop and release camera
if (camera != null) {
camera.release();
camera = null;
}
}
public void chooseCamera() {
//if the camera preview is the front
if (mId == 1) {
camera = Camera.open(0);
refreshCamera();
mId=0;
} else if (mId == 0) {
camera = Camera.open(1);
camera.setDisplayOrientation(90);
refreshCamera();
mId=1;
}
}
private void defineIds(View view) {
capture = (LinearLayout) view.findViewById(R.id.capture);
change_camera= (ImageView) view.findViewById(R.id.change_camera);
flash_icon= (ImageView) view.findViewById(R.id.flash_icon);
surfaceView = (SurfaceView) view.findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
jpegCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Toast.makeText(getActivity(), "Picture Saved", Toast.LENGTH_LONG).show();
refreshCamera();
}
};
}
public void captureImage(View v) throws IOException {
//take the picture
camera.takePicture(null, null, jpegCallback);
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
}
}
private void handleClick() {
capture.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.capture:
try {
captureImage(v);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// open the camera
camera = Camera.open(0);
} catch (RuntimeException e) {
// check for exceptions
System.err.println(e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
// modify parameter
param.setPreviewSize(352, 288);
camera.setParameters(param);
try {
// The Surface has been created, now tell the camera where to draw
// the preview.
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
// check for exceptions
System.err.println(e);
return;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
refreshCamera();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// stop preview and release camera
camera.stopPreview();
camera.release();
camera = null;
}
public void onDestroy(){
super.onDestroy();
camera.release();
}
}
视频片段
public class VideoFragment extends Fragment {
private Camera mCamera;
private CameraPreview mPreview;
private MediaRecorder mediaRecorder;
private ImageView record_image_button, change_camera;
private Context myContext;
private LinearLayout cameraPreview;
private boolean cameraFront = false;
private View rootView;
/* @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_video, container, false);
// getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
myContext = getActivity();
initialize();
if (!hasCamera(myContext)) {
Toast toast = Toast.makeText(myContext, "Sorry, your phone does not have a camera!", Toast.LENGTH_LONG);
toast.show();
}
if (mCamera == null) {
// if the front facing camera does not exist
if (findFrontFacingCamera() < 0) {
Toast.makeText(getActivity(), "No front facing camera found.", Toast.LENGTH_LONG).show();
change_camera.setVisibility(View.GONE);
}
mCamera = Camera.open(findBackFacingCamera());
mPreview.refreshCamera(mCamera);
}
return rootView;
}
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
cameraFront = true;
break;
}
}
return cameraId;
}
private int findBackFacingCamera() {
int cameraId = -1;
// Search for the back facing camera
// get the number of cameras
int numberOfCameras = Camera.getNumberOfCameras();
// for every camera check
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
cameraFront = false;
break;
}
}
return cameraId;
}
public void initialize() {
cameraPreview = (LinearLayout)rootView. findViewById(R.id.camera_preview);
mPreview = new CameraPreview(myContext, mCamera);
cameraPreview.addView(mPreview);
record_image_button = (ImageView) rootView. findViewById(R.id.record_image_button);
record_image_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Hold down the button to record video", Toast.LENGTH_LONG).show();
}
});
record_image_button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN ) {
Log.e("CLCIKEVENT", String.valueOf(event));
if (!prepareMediaRecorder()) {
Toast.makeText(getActivity(), "Fail in prepareMediaRecorder()!\n - Ended -", Toast.LENGTH_LONG).show();
// finish();
}
// work on UiThread for better performance
getActivity().runOnUiThread(new Runnable() {
public void run() {
// If there are stories, add them to the table
try {
mediaRecorder.start();
} catch (final Exception ex) {
// Log.i("---","Exception in thread");
}
}
});
recording = true;
} else if (event.getAction() == MotionEvent.ACTION_UP||
event.getAction() == MotionEvent.ACTION_CANCEL) {
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
Toast.makeText(getActivity(), "Video captured!", Toast.LENGTH_LONG).show();
recording = false;
}
return false;
}
});
change_camera = (ImageView) rootView. findViewById(R.id.change_camera);
change_camera.setOnClickListener(switchCameraListener);
}
View.OnClickListener switchCameraListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// get the number of cameras
if (!recording) {
int camerasNumber = Camera.getNumberOfCameras();
if (camerasNumber > 1) {
// release the old camera instance
// switch camera, from the front and the back and vice versa
releaseCamera();
chooseCamera();
} else {
Toast toast = Toast.makeText(myContext, "Sorry, your phone has only one camera!", Toast.LENGTH_LONG);
toast.show();
}
}
}
};
public void chooseCamera() {
// if the camera preview is the front
if (cameraFront) {
int cameraId = findBackFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
// set a picture callback
// refresh the preview
mCamera = Camera.open(cameraId);
// mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
} else {
int cameraId = findFrontFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
// set a picture callback
// refresh the preview
mCamera = Camera.open(cameraId);
// mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
}
}
@Override
public void onPause() {
super.onPause();
// when on Pause, release camera in order to be used from other
// applications
releaseCamera();
}
private boolean hasCamera(Context context) {
// check if the device has camera
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
boolean recording = false;
View.OnClickListener captrureListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (recording) {
// stop recording and release camera
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
Toast.makeText(getActivity(), "Video captured!", Toast.LENGTH_LONG).show();
recording = false;
} else {
if (!prepareMediaRecorder()) {
Toast.makeText(getActivity(), "Fail in prepareMediaRecorder()!\n - Ended -", Toast.LENGTH_LONG).show();
// finish();
}
// work on UiThread for better performance
getActivity().runOnUiThread(new Runnable() {
public void run() {
// If there are stories, add them to the table
try {
mediaRecorder.start();
} catch (final Exception ex) {
// Log.i("---","Exception in thread");
}
}
});
recording = true;
}
}
};
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
private boolean prepareMediaRecorder() {
mediaRecorder = new MediaRecorder();
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
mediaRecorder.setMaxDuration(600000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(50000000); // Set max file size 50M
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
private void releaseCamera() {
// stop and release camera
if (mCamera != null) {
mCamera.release();
mCamera = null;
}}
用于视频录制的相机预览
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
// create the surface and start camera preview
if (mCamera == null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) {
Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void refreshCamera(Camera camera) {
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
setCamera(camera);
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
refreshCamera(mCamera);
}
public void setCamera(Camera camera) {
//method to set a camera instance
mCamera = camera;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
// mCamera.release();
}
任何帮助将不胜感激。 如果有人得到那么请帮助我。