您好我正在使用自定义相机。我从git使用了CameraPreview类。一切正常,但问题是当我从活动A打开相机时,打开相机需要4秒钟。我没有收到任何错误。但getCameraInstance方法调用需要很长时间才能打开相机。打开相机时如何减少4秒延迟?我对如何减少去TakePhotoFragment的延迟毫无头绪。请帮我解决问题
这是CameraPreview:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private Context mContext;
private Camera camera;
private SurfaceHolder surfaceHolder;
public List<Camera.Size> mSupportedPreviewSizes;
public Camera.Size mPreviewSize;
private static final String TAG = "CameraPreview";
public CameraPreview(Context context, Camera camera) {
super(context);
mContext = context;
this.camera = camera;
mSupportedPreviewSizes = camera.getParameters().getSupportedPreviewSizes();
for (Camera.Size str : mSupportedPreviewSizes)
Log.e(TAG, str.width + "/" + str.height);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
this.camera.setPreviewDisplay(surfaceHolder);
Camera.Parameters params = this.camera.getParameters();
List<Camera.Size> sizes = params.getSupportedPictureSizes();
Camera.Size mSize = null;
List<Camera.Size> psizes = params.getSupportedPreviewSizes();
Camera.Size pSize = null;
Collections.sort(sizes, new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size t1, Camera.Size t2) {
return t1.width >= t2.width ? -1 : 1;
}
});
Collections.sort(psizes, new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size t1, Camera.Size t2) {
return t1.width >= t2.width ? -1 : 1;
}
});
for (Camera.Size size :
sizes) {
if (size.width <= 1920) {
mSize = size;
break;
}
}
// for (Camera.Size size :
// psizes) {
// if (size.width == mSize.width) {
// pSize = size;
// break;
// }
// }
// if (pSize==null){
for (Camera.Size size :
psizes) {
if (size.width <= 1920) {
pSize = size;
break;
}
}
// }
Log.i("CAMERA", "Available resolution: " + mSize.width + " " + mSize.height);
Log.i("CAMERA", "Available resolution2: " + pSize.width + " " + pSize.height);
params.setPictureSize(mSize.width, mSize.height);
params.setPreviewSize(pSize.width, pSize.height);
this.camera.setParameters(params);
this.camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged => w=" + w + ", h=" + 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.
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.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
camera.setParameters(parameters);
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
this.camera.stopPreview();
this.camera.release();
getHolder().removeCallback(this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
float ratio;
if (mPreviewSize.height >= mPreviewSize.width)
ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
else
ratio = (float) mPreviewSize.width / (float) mPreviewSize.height;
// One of these methods should be used, second method squishes preview slightly
setMeasuredDimension(width, (int) (width * ratio));
// setMeasuredDimension((int) (width * ratio), height);
}
public Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) h / w;
if (sizes == null)
return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
double ratio = (double) size.height / size.width;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
}
在CameraFragment中:
public class TakePhotoFragment extends Fragment {
private Button camera;
private Button gallery;
private Camera mCamera;
private CameraPreview mCameraPreview;
private FrameLayout preview;
public static TakePhotoFragment newInstance() {
return new TakePhotoFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.rr_take_photo, container, false);
camera = (Button) view.findViewById(R.id.button_capture);
gallery = (Button) view.findViewById(R.id.gallery);
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(getActivity(), mCamera);
preview = (FrameLayout) view.findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* Intent intent = new Intent(getActivity(), PhotoActivity.class);
startActivity(intent);
getActivity().finish();*/
mCamera.takePicture(null, null, mPicture);
}
});
//this takes long time to open
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
Log.e("pictureFile",pictureFile.getAbsolutePath());
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
SharedPreferencesHelper.setStringItem("gallery_item", pictureFile.getAbsolutePath());
Intent intent = new Intent(getActivity(), PhotoActivity.class);
startActivity(intent);
getActivity().finish();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
};
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
Log.e("mediaFile",mediaStorageDir.getPath());
return mediaFile;
}