Android相机第二次拍摄失败
Posted
技术标签:
【中文标题】Android相机第二次拍摄失败【英文标题】:Android Camera fail for second shot 【发布时间】:2015-01-03 17:39:09 【问题描述】:我正在尝试用我的应用程序拍摄两张照片,第一张照片没有问题,但拍摄另一张照片给我 NullPointerException。
以下代码是我的相机活动。 最近两天我试图解决这个问题,但到目前为止还没有运气。
编辑:相机到底在哪里失败了?当用户拍照时,我向他们展示另一个活动中的预览。如果用户想要拍摄另一张照片并单击“拍摄另一张”按钮。 Activity 返回到 TakePicture 类。这是用户拍摄多张照片时的主要问题。
第二次拍摄时还会弹出两次displayGuide()方法
感谢任何帮助。
public class TakePicture extends Activity
private SurfaceView mySurfaceView;
private SurfaceHolder holder;
private Camera myCamera;
private int orient;
@Override
public void onCreate(Bundle b)
super.onCreate(b);
b = getIntent().getExtras();
orient = b.getInt("orient");
// Switch to Screen orientation based on BARCODE
switch (orient)
case 3 :
case 4 :
case 5 :
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
default :
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_fullscreen);
myCamera = getCameraInstance();
mySurfaceView = (SurfaceView) findViewById(R.id.surface_view);
holder = mySurfaceView.getHolder();
holder.addCallback(mSurfaceListener);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
@Override
protected void onResume()
if (myCamera == null)
myCamera = getCameraInstance();
super.onResume();
@Override
public void onPause()
super.onPause();
releaseCamera();
private void releaseCamera()
if (myCamera != null)
myCamera.setPreviewCallback(null);
myCamera.release();
myCamera = null;
private static Camera getCameraInstance()
Camera c = null;
try
c = Camera.open();
catch(Exception e)
new ErrLog(e.toString());
return c;
private final ShutterCallback shutterCallback = new ShutterCallback()
public void onShutter()
AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mgr.playSoundEffect(AudioManager.FLAG_PLAY_SOUND);
;
private SurfaceHolder.Callback mSurfaceListener = new SurfaceHolder.Callback()
public void surfaceCreated(SurfaceHolder holder)
//myCamera = Camera.open();
try
myCamera.setPreviewDisplay(holder);
catch (Exception e)
new ErrLog(e.toString());
public void surfaceDestroyed(SurfaceHolder holder)
//myCamera.release();
//myCamera = null;
@SuppressLint("InlinedApi")
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
myCamera.stopPreview();
Parameters mParam = myCamera.getParameters();
List<Size> getPictureSize = mParam.getSupportedPictureSizes();
Size getPicSize = getPictureSize.get(5);
mParam.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
mParam.setPictureSize(getPicSize.width, getPicSize.height);
mParam.setRotation(fixPictureOrientation());
myCamera.setParameters(mParam);
Display display = getWindowManager().getDefaultDisplay();
if (display.getRotation() == Surface.ROTATION_0)
myCamera.setDisplayOrientation(90);
else if (display.getRotation() == Surface.ROTATION_270)
myCamera.setDisplayOrientation(180);
// Display guide
displayGuide();
;
private int fixPictureOrientation()
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation)
case Surface.ROTATION_0 :
degrees = 0;
break; // Natural orientation
case Surface.ROTATION_90 :
degrees = 90;
break; // Landscape left
case Surface.ROTATION_180 :
degrees = 180;
break;// Upside down
case Surface.ROTATION_270 :
degrees = 270;
break;// Landscape right
int rotate = (info.orientation - degrees + 360) % 360;
return rotate;
private PictureCallback mPictureListener = new PictureCallback()
@Override
public void onPictureTaken(byte[] data, Camera camera)
String fileName = "sample_" + (System.currentTimeMillis() / 1000) + ".jpg";
try
File file = new File(PATH + "/" + fileName);
FileOutputStream out = new FileOutputStream(file);
out.write(data);
if (out != null)
out.close();
catch (Exception e)
new ErrLog(e.toString());
// Refreshing SD card
new UpdateSDCard().mediaScan(TakePicture.this, PATH);
// Stop Preview
myCamera.stopPreview();
Intent i = new Intent(TakePicture.this, PreviewPictureActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("orient", orient);
startActivity(i);
;
public void takePicture(View v)
if(myCamera != null)
myCamera.takePicture(shutterCallback, null, mPictureListener);
public void cancelActivity(View v)
Intent i = new Intent(TakePicture.this, MenuActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
TakePicture.this.finish();
private void displayGuide()
GetScreenSize size = new GetScreenSize();
final Dialog dialog = new Dialog(TakePicture.this);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.guide_layout_picture);
dialog.setCanceledOnTouchOutside(false);
dialog.setCancelable(false);
ImageView close = (ImageView) dialog.findViewById(R.id.imageView1);
close.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
dialog.dismiss();
if(myCamera == null)
myCamera = Camera.open();
myCamera.startPreview();
);
dialog.show();
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
Window window = dialog.getWindow();
lp.copyFrom(window.getAttributes());
// This makes the dialog take up the full width
lp.width = (int) (size.getScreenW() * 0.8F);
lp.height = (int) (size.getScreenH() * 0.7F);
window.setAttributes(lp);
这是输出日志
11-07 11:14:28.998:E/AndroidRuntime(1502):致命异常:主要 11-07 11:14:28.998: E/AndroidRuntime(1502): java.lang.RuntimeException: 无法连接到相机服务 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 android.hardware.Camera.native_setup(Native Method) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 android.hardware.Camera.(Camera.java:371) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 android.hardware.Camera.open(Camera.java:344) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 main_app.TakePicture$4.onClick(TakePicture.java:236) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 android.view.View.performClick(View.java:4203) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 android.view.View$PerformClick.run(View.java:17189) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 android.os.Handler.handleCallback(Handler.java:615) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 android.os.Handler.dispatchMessage(Handler.java:92) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 android.os.Looper.loop(Looper.java:137) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 android.app.ActivityThread.main(ActivityThread.java:4961) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 java.lang.reflect.Method.invokeNative(Native Method) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 java.lang.reflect.Method.invoke(Method.java:511) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004) 11-07 11:14:28.998: E/AndroidRuntime(1502): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771) 11-07 11:14:28.998: E/AndroidRuntime(1502): at dalvik.system.NativeStart.main(Native Method)
【问题讨论】:
你能添加你的日志吗? 日志添加到原帖中 你检查过那些错误吗:***.com/q/23904459/1343997 【参考方案1】:好的,伙计们。我想我发现了问题。问题是 myCamera = getCameraInstance(); onCreate 方法中的行,所以我删除了该行并且相机不再失败。希望这对其他人有帮助。
【讨论】:
是的,你不需要那行,因为你在 onResume 之后实例化了它。【参考方案2】:我没有看到你的代码崩溃的确切位置,并且日志没有给出确切的行。
显然,当您重新执行此活动时,它会崩溃,因此您应该尝试在调试模式下逐步执行此操作,以查看哪一行是问题所在。
在您的 Activity.onPause() 处添加一个断点,以检查您是否通过以及在您显示图片预览时相机是否释放良好。然后检查 Activity.onCreate() 的开头是否通过(通常不应该直接点击 onResume())并在 onResume() 中执行相同操作。
通常你应该得到更多的提示。
【讨论】:
亲爱的文森特。 APP 崩溃只有三星 S4 设备的其余部分工作正常。我已经检查了您提供的链接。问题是,当我调试 APP 时,我发现 APP 运行了两次 onCreate 方法,我不知道为什么。在我的三星 S4 设备上的崩溃案例中。一旦该类运行 onCreate 方法,Camera 不为空,并且第二次执行 onCreate 方法时,Camera 变为空。【参考方案3】:您可以使用errorcallback方法。相机重新创建。
ErrorCallback CEC = new ErrorCallback()
public void onError(int error, Camera camera)
Log.d("CameraDemo", "camera error detected");
if(error == Camera.CAMERA_ERROR_SERVER_DIED)
Log.d("CameraDemo", "attempting to reinstantiate new camera");
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release(); //written in documentation...
camera = null;
camera = Camera.open();
;
【讨论】:
以上是关于Android相机第二次拍摄失败的主要内容,如果未能解决你的问题,请参考以下文章
如何使用Android中的Camera2 API在不预览的情况下拍摄多张照片?