相机预览没有重新启动?

Posted

技术标签:

【中文标题】相机预览没有重新启动?【英文标题】:camera preview is not restarting? 【发布时间】:2012-06-10 09:47:11 【问题描述】:

我正在研究 android 中的相机代码以拍照并将其保存在手机上。它从手机摄像头拍摄照片并将其保存在存储卡上。唯一的问题是拍照后相机预览没有重新启动。

我想不出解决办法。代码如下。需要建议。 . . 我的项目中有两个类。 . .

摄影活动课程

public class CameraActivity extends Activity 


  private static final String TAG = "CameraDemo";
  Preview preview; 
  Button buttonClick; 

  public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    preview = new Preview(this); 
    ((FrameLayout) findViewById(R.id.preview)).addView(preview); 

    buttonClick = (Button) findViewById(R.id.buttonClick);
    buttonClick.setOnClickListener(new OnClickListener() 
      public void onClick(View v)  
        preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);    
      
    );

    Log.d(TAG, "onCreate'd");
  

  // Called when shutter is opened
  ShutterCallback shutterCallback = new ShutterCallback()  
    public void onShutter() 
      Log.d(TAG, "onShutter'd");
    
  ;

  // Handles data for raw picture
  PictureCallback rawCallback = new PictureCallback() 
    public void onPictureTaken(byte[] data, Camera camera) 
      Log.d(TAG, "onPictureTaken - raw");
    
  ;

  // Handles data for jpeg picture
  PictureCallback jpegCallback = new PictureCallback()  
    public void onPictureTaken(byte[] data, Camera camera) 
      FileOutputStream outStream = null;
      try 
        // Write to SD Card
        outStream = new FileOutputStream(String.format("/sdcard/DCIM/queries.jpg",
            System.currentTimeMillis()));
        outStream.write(data);
        outStream.close();
        Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
       catch (FileNotFoundException e)  
        e.printStackTrace();
       catch (IOException e) 
        e.printStackTrace();
       finally 
      
      Log.d(TAG, "onPictureTaken - jpeg");

    
  ;


预览课

class Preview extends SurfaceView implements SurfaceHolder.Callback 
  private static final String TAG = "Preview";

  SurfaceHolder mHolder;  // <2>
  public Camera camera; // <3>

  Preview(Context context) 
    super(context);

    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    mHolder = getHolder();  // <4>
    mHolder.addCallback(this);  // <5>
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // <6>

  

  // Called once the holder is ready
  public void surfaceCreated(SurfaceHolder holder)   // <7>
    // The Surface has been created, acquire the camera and tell it where
    // to draw.
    camera = Camera.open(); // <8>
    try 


        Camera.Parameters parameters = camera.getParameters();
        parameters.set("orientation", "landscape");
        camera.setParameters(parameters);
        camera.setPreviewDisplay(holder);  

        camera.setPreviewCallback(new PreviewCallback()  
        // Called for each frame previewed
        public void onPreviewFrame(byte[] data, Camera camera)   
          Log.d(TAG, "onPreviewFrame called at: " + System.currentTimeMillis());
          Preview.this.invalidate();  
        
      );
     catch (IOException e)  
      e.printStackTrace();
    

  

  // Called when the holder is destroyed
  public void surfaceDestroyed(SurfaceHolder holder)  
    //Log.d(TAG,"Stopping preview in SurfaceDestroyed().");
    camera.setPreviewCallback(null);
    camera.stopPreview();
    camera.release();
    camera = null;           
  

  // Called when holder has changed
  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)  
    camera.startPreview();
  


【问题讨论】:

【参考方案1】:

The article about Camera from Android API Guide 也有同样的问题。拍照后我可以通过添加以下两个内容来恢复预览:

1) 在AndroidManifest.xml文件中添加外部存储权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2) 调用camera.startPreview() 再次开始预览。在您的代码中:

...
Log.d(TAG, "onPictureTaken - jpeg");
camera.startPreview();
....

我相信你也能以同样的方式让你的工作。

【讨论】:

【参考方案2】:

在 onPictureTaken 中再次启动 CAMERAACTIVITY,如下所示:

// Handles data for jpeg picture
  PictureCallback jpegCallback = new PictureCallback()  
    public void onPictureTaken(byte[] data, Camera camera) 
      FileOutputStream outStream = null;
      try 
        // Write to SD Card
        outStream = new FileOutputStream(String.format("/sdcard/DCIM/queries.jpg",
            System.currentTimeMillis()));
        outStream.write(data);
        outStream.close();
        Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
       catch (FileNotFoundException e)  
        e.printStackTrace();
       catch (IOException e) 
        e.printStackTrace();
       finally 
        camera.release();
        camera = null;
        startActivity(new Intent(CAMERAACTIVITY.this, CAMERAACTIVITY.class));
        finish();
      
      Log.d(TAG, "onPictureTaken - jpeg");

    
  ;

如果你愿意,你也可以使用 Thread.sleep(2000);这样,捕获的图像将显示 2 秒钟,然后再次启动相机活动。

【讨论】:

【参考方案3】:

添加 线程.睡眠(2000); camera.startPreview();

以便相机将拍摄的图像显示 2 秒并重新启动相机。

【讨论】:

以上是关于相机预览没有重新启动?的主要内容,如果未能解决你的问题,请参考以下文章

UIImagePickerController 显示黑色预览屏幕

调整大小后 GLSurfaceView 相机预览被打乱

我的应用程序启动时如何在没有预览的情况下从相机拍照?

使用相机功能时,Flutter 应用程序崩溃并从启动画面重新启动

启动相机意图时未调用 onActivityResult?

Android 相机启动预览失败