我正在Android上制作一个相机示例,目前只需要拍照并将其保存在设备的(内部)内存中。 拍完照片后,屏幕在最后点击的图片上保持冻结,我必须退出应用程序并再次打开它以拍摄另一张照片。 这是我的代码:
MainActivity.java:
package com.example.camera;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.Surface;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends Activity
{
private Camera mCamera;
private ShowCamera showCamera;
public Camera isCameraAvailable()
{
Camera camera=null;
Log.d("isCameraAvailable","Camera object set to null.");
try
{
camera = Camera.open();
Log.d("isCameraAvailable","Camera opened.");
}
catch (Exception e)
{
Log.d("isCameraAvailable",e.toString());
}
return camera;
}
private static File getOutputMediaFile()
{
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"com.example.camera");
if (!mediaStorageDir.exists())
{
if (!mediaStorageDir.mkdirs())
{
Log.d("getOutputMediaFile","Failed to create directory.");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator+ "IMG_" + timeStamp + ".jpg");
Log.d("getOutputMediaFile","Filename created.");
return mediaFile;
}
private PictureCallback capturedIt = new PictureCallback()
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
File pictureFile = getOutputMediaFile();
if (pictureFile == null)
{
Log.d("onPictureTaken","pictureFile=null");
return;
}
try
{
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
Log.d("onPictureTaken","File written.");
fos.close();
Log.d("onPictureTaken","File closed.");
Toast.makeText(MainActivity.this,pictureFile.toString()+" saved!", Toast.LENGTH_LONG).show();
return;
}
catch (FileNotFoundException e)
{
Log.e("onPictureTaken",e.toString());
}
catch (IOException e)
{
Log.d("onPictureTaken",e.toString());
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCamera = isCameraAvailable();
setCameraDisplayOrientation(this,0,mCamera);
Log.d("onCreate","Camera instance taken.");
showCamera = new ShowCamera(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.flCameraPreview);
preview.addView(showCamera);
Log.d("onCreate","Camera view in initialized");
preview.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
mCamera.takePicture(null, null, capturedIt);
Log.d("onClick","Button Clicked.");
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
public static void setCameraDisplayOrientation(Activity activity,int cameraId, android.hardware.Camera camera)
{
android.hardware.Camera.CameraInfo info=new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId,info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
{
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360;
}
else
{
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
}
ShowCamera.java:
package com.example.camera;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder holdMe;
private Camera mCamera;
public ShowCamera(Context context,Camera camera)
{
super(context);
this.mCamera = camera;
this.holdMe = getHolder();
this.holdMe.addCallback(this);
this.holdMe.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format,int width, int height)
{
try
{
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}
catch (Exception e)
{
Log.d("surfaceChanged",e.toString());
}
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
try
{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch (IOException e)
{
Log.e("surfaceCreated",e.toString());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder)
{
mCamera.stopPreview();
mCamera.release();
}
}
拍摄照片并将其保存到内存后,如果再次单击该屏幕,应用程序将崩溃。
答案 0 :(得分:0)
你在surfaceDestroyed中有stopPreview。但当它回来时。你必须在onResume中重启相机。缺少
public void onResume()
{
mCamera = getCameraInstance(); // i have created this i
// static method here
//mCamera.setPreviewCallback(previewCallback);//it depends on you need
try
{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
}
catch (IOException ioexception)
{
Log.e("MyCamera",
(new StringBuilder()).append("PreviewDisplay Error => ")
.append(ioexception.getMessage()).toString());
}
}
和
public static Camera getCameraInstance()
{
Camera camera1;
try
{
if (android.os.Build.VERSION.SDK_INT >= 9)
{
return Camera.open(cameraId);
}
camera1 = Camera.open();
}
catch (Exception exception)
{
Log.e("NightVision",
(new StringBuilder()).append("ErrorCameraInit: ")
.append(exception.getMessage()).toString());
return null;
}
return camera1;
}