0

我正在制作一个简单的应用程序,它将在活动中打开后置摄像头并显示实时预览。我正在处理来自 Android 开发者网站的代码。logcat 检测到我的相机,但活动开始并崩溃到调试模式,我没有预览。在崩溃进入调试模式时,它停在这一行mPreview = new CameraPreview(this, mCamera);

在清单文件中,我有以下权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

我在只有后置摄像头的 Sony Xperia Tipo 双手机上进行测试。注意:我不想使用意图打开相机,我只需要在活动中进行实时预览。

我在发布之前搜索了很多。任何帮助将不胜感激...谢谢

这是我的 logcat 在调试器中恢复挂起的线程后显示的内容:

10-31 04:47:06.262: I/QualcommCamera(6916): Qint android::get_camera_info(int, camera_info*): E
10-31 04:47:06.262: W/CameraService(6916): CameraService::connect: (pid 18358) pre-create object.
10-31 04:47:06.262: I/QualcommCamera(6916): Qint android::camera_device_open(const hw_module_t*, const char*, hw_device_t**): E
10-31 04:47:06.262: E/QualcommCameraHardware(6916): HAL_openCameraHardware: camera_count = 1
10-31 04:47:06.262: I/QualcommCameraHardware(6916): openCameraHardware: call createInstance
10-31 04:47:06.262: I/QualcommCameraHardware(6916): openCameraHardware:Valid camera ID 0
10-31 04:47:06.262: I/QualcommCameraHardware(6916): HAL_openCameraHardware: HAL_currentSnapshotMode = 4 HAL_currentCameraMode = 1
10-31 04:47:06.262: I/QualcommCameraHardware(6916): createInstance: E
10-31 04:47:06.262: I/QualcommCameraHardware(6916): QualcommCameraHardware constructor E
10-31 04:47:06.272: I/QualcommCameraHardware(6916): QualcommCameraHardware: recordframes = 7e40b0
10-31 04:47:06.272: I/QualcommCameraHardware(6916): constructor EX
10-31 04:47:06.272: I/QualcommCameraHardware(6916): startCamera E
10-31 04:47:06.272: I/QualcommCameraHardware(6916):  openCamera : E
10-31 04:47:06.362: I/QualcommCameraHardware(6916): openCamera : X
10-31 04:47:06.362: I/QualcommCameraHardware(6916): startCamera X
10-31 04:47:06.362: I/QualcommCameraHardware(6916): initDefaultParameters E
10-31 04:47:06.582: I/QualcommCameraHardware(6916): Maximum zoom value is 61
10-31 04:47:06.592: I/QualcommCameraHardware(6916): initDefaultParameters X
10-31 04:47:06.592: I/QualcommCameraHardware(6916): createInstance: X
10-31 04:47:06.592: W/CameraService(6916): CameraService::connect: (pid 18358) new hardware.
10-31 04:47:06.592: I/QualcommCamera(6916): Qvoid android::set_callbacks(camera_device*, void (*)(int32_t, int32_t, int32_t, void*), void (*)(int32_t, const camera_memory_t*, unsigned int, camera_frame_metadata_t*, void*), void (*)(int64_t, int32_t, const camera_memory_t*, unsigned int, void*), camera_memory_t* (*)(int, size_t, unsigned int, void*), void*): E
10-31 04:47:06.592: I/QualcommCamera(6916): cam_nt_cb =0x0,cam_dt_cb=0x0,cam_dt_timestamp_cb=0x0
10-31 04:47:06.602: W/CameraService(6916): Client::Client: (pid 18358) setCallbacks() done.
10-31 04:47:06.602: W/CameraService(6916): Client::Client: (pid 18358) enableMsgType() done.
10-31 04:47:06.602: W/CameraService(6916): Client::Client: (pid 18358) setCameraBusy() done.
10-31 04:47:06.602: W/CameraService(6916): Loading CameraService sounds: /system/media/audio/ui/camera_click.ogg
10-31 04:47:06.702: W/CameraService(6916): Loading CameraService sounds: /system/media/audio/ui/VideoRecord.ogg
10-31 04:47:06.802: W/CameraService(6916): Client::Client: (pid 18358) loadSound() done.
10-31 04:47:06.802: W/CameraService(6916): CameraService::connect: (pid 18358) new client .
10-31 04:47:12.592: E/CAM_FD(6916): ...config thread select timeout...
10-31 04:47:18.602: E/CAM_FD(6916): ...config thread select timeout...
10-31 04:47:24.612: E/CAM_FD(6916): ...config thread select timeout...
10-31 04:47:30.612: E/CAM_FD(6916): ...config thread select timeout...
10-31 04:47:36.622: E/CAM_FD(6916): ...config thread select timeout...
10-31 04:47:38.322: I/QualcommCamera(6916): Qint android::preview_enabled(camera_device*): E
10-31 04:47:38.322: I/QualcommCameraHardware(6916):  : mCameraRunning : 0 mPreviewWindow = 0
10-31 04:47:38.322: I/QualcommCamera(6916): Qint android::preview_enabled(camera_device*): E
10-31 04:47:38.322: I/QualcommCameraHardware(6916):  : mCameraRunning : 0 mPreviewWindow = 0
10-31 04:47:38.322: I/QualcommCamera(6916): Qint android::set_preview_window(camera_device*, preview_stream_ops*): E window = 0x7fa688
10-31 04:47:38.322: I/QualcommCameraHardware(6916):  setPreviewWindow: E 
10-31 04:47:38.322: I/QualcommCameraHardware(6916):  setPreviewWindow : X 
10-31 04:47:38.322: I/QualcommCamera(6916): Qint android::start_preview(camera_device*): E
10-31 04:47:38.322: I/QualcommCameraHardware(6916): startPreview E
10-31 04:47:38.322: I/QualcommCameraHardware(6916): g_InitDefaultParam = 0.
10-31 04:47:38.342: I/QualcommCameraHardware(6916): setParameters: X
10-31 04:47:38.342: I/QualcommCameraHardware(6916):  getBuffersAndStartPreview : E 
10-31 04:47:38.372: I/QualcommCameraHardware(6916): in startPreviewInternal : E
10-31 04:47:38.372: I/QualcommCameraHardware(6916): bool android::QualcommCameraHardware::initPreview() Got preview dimension as 640 x 480 
10-31 04:47:38.372: I/mm-camera(6916): __func__ Setting camfram_exit to 0
10-31 04:47:38.372: I/mm-camera(6916): Waiting for frame thread to start ! 
10-31 04:47:38.372: I/QualcommCameraHardware(6916): frame_thread E
10-31 04:47:38.372: I/mm-camera(6916): cam_frame() is ready, call pthread_cond_signal
10-31 04:47:38.382: I/mm-camera(6916): Wait over, frame thread ready !!!! 
10-31 04:47:38.382: I/QualcommCameraHardware(6916): initPreview X: 1
10-31 04:47:38.382: I/mm-camera(6916): cam_frame() is ready, call pthread_cond_signal done
10-31 04:47:38.382: I/QualcommCameraHardware(6916): preview_thread E
10-31 04:47:38.462: I/QualcommCameraHardware(6916): startPreviewInternal: mVfeEnabled = 1 
10-31 04:47:38.462: I/QualcommCameraHardware(6916): startPreviewInternal X
10-31 04:47:38.462: I/QualcommCameraHardware(6916):  getBuffersAndStartPreview : X 
10-31 04:47:38.462: I/QualcommCameraHardware(6916): startPreview X
10-31 04:47:38.462: I/QualcommCamera(6916): Qint android::start_preview(camera_device*): X
10-31 04:47:38.462: I/QualcommCamera(6916): Qvoid android::disable_msg_type(camera_device*, int32_t): E
10-31 04:47:38.462: I/QualcommCamera(6916): Qvoid android::disable_msg_type(camera_device*, int32_t): E
10-31 04:47:38.462: I/QualcommCamera(6916): Qvoid android::stop_preview(camera_device*): E
10-31 04:47:38.462: I/QualcommCameraHardware(6916): stopPreview: E
10-31 04:47:38.462: I/QualcommCameraHardware(6916): stopPreviewInternal E: 1
10-31 04:47:38.462: I/QualcommCameraHardware(6916): cancelAutoFocusInternal E
10-31 04:47:38.462: I/QualcommCameraHardware(6916): cancelAutoFocusInternal X: 0
10-31 04:47:38.552: I/QualcommCameraHardware(6916): stopPreviewInternal: mVfeEnabled = 0 
10-31 04:47:38.552: I/QualcommCameraHardware(6916): stopPreviewInternal: J_mCameraRunning = 0
10-31 04:47:38.552: I/QualcommCameraHardware(6916): stopPreviewInternal: before calling deinitpre mPreviewInitialized = 1
10-31 04:47:38.552: I/QualcommCameraHardware(6916): deinitPreview E
10-31 04:47:38.552: I/QualcommCameraHardware(6916): deinitPreview X
10-31 04:47:38.552: I/QualcommCameraHardware(6916): stopPreviewInternal: waiting for old frame thread to complete.
10-31 04:47:38.552: I/QualcommCameraHardware(6916): runframethread: waiting for preview  thread to complete.
10-31 04:47:38.552: I/QualcommCameraHardware(6916): preview_thread X
10-31 04:47:38.552: I/QualcommCameraHardware(6916): initPreview: old preview thread completed.
10-31 04:47:38.572: I/QualcommCameraHardware(6916): stopPreviewInternal: old frame thread completed.
10-31 04:47:38.572: I/QualcommCameraHardware(6916): stopPreviewInternal X: 0
10-31 04:47:38.572: I/QualcommCameraHardware(6916): stopPreview: X
10-31 04:47:38.572: I/QualcommCamera(6916): Qint android::preview_enabled(camera_device*): E
10-31 04:47:38.572: I/QualcommCameraHardware(6916):  : mCameraRunning : 0 mPreviewWindow = 7fa688
10-31 04:47:38.572: I/QualcommCamera(6916): Qint android::set_preview_window(camera_device*, preview_stream_ops*): E window = 0x7fa688
10-31 04:47:38.572: I/QualcommCameraHardware(6916):  setPreviewWindow: E 
10-31 04:47:38.572: I/QualcommCameraHardware(6916):  setPreviewWindow : X 
10-31 04:47:38.572: I/QualcommCamera(6916): Qint android::start_preview(camera_device*): E
10-31 04:47:38.572: I/QualcommCameraHardware(6916): startPreview E
10-31 04:47:38.572: I/QualcommCameraHardware(6916): g_InitDefaultParam = 1.
10-31 04:47:38.572: I/QualcommCameraHardware(6916):  getBuffersAndStartPreview : E 
10-31 04:47:38.582: I/QualcommCameraHardware(6916): frame_thread X
10-31 04:47:38.622: I/QualcommCameraHardware(6916): in startPreviewInternal : E
10-31 04:47:38.622: I/QualcommCameraHardware(6916): bool android::QualcommCameraHardware::initPreview() Got preview dimension as 640 x 480 
10-31 04:47:38.622: I/mm-camera(6916): __func__ Setting camfram_exit to 0
10-31 04:47:38.622: I/mm-camera(6916): Waiting for frame thread to start ! 
10-31 04:47:38.632: I/QualcommCameraHardware(6916): frame_thread E
10-31 04:47:38.632: I/mm-camera(6916): cam_frame() is ready, call pthread_cond_signal
10-31 04:47:38.632: I/mm-camera(6916): Wait over, frame thread ready !!!! 
10-31 04:47:38.632: I/QualcommCameraHardware(6916): initPreview X: 1
10-31 04:47:38.632: I/mm-camera(6916): cam_frame() is ready, call pthread_cond_signal done
10-31 04:47:38.632: I/QualcommCameraHardware(6916): preview_thread E
10-31 04:47:38.712: I/QualcommCameraHardware(6916): startPreviewInternal: mVfeEnabled = 1 
10-31 04:47:38.712: I/QualcommCameraHardware(6916): startPreviewInternal X
10-31 04:47:38.712: I/QualcommCameraHardware(6916):  getBuffersAndStartPreview : X 
10-31 04:47:38.712: I/QualcommCameraHardware(6916): startPreview X
10-31 04:47:38.712: I/QualcommCamera(6916): Qint android::start_preview(camera_device*): X

主要活动:

package com.example.cameraappdemo;

import android.hardware.Camera; 
import android.os.Bundle;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.Toast;


public class MainActivity extends Activity {

private Camera mCamera;
private CameraPreview mPreview;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //checks for back Camera
    if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {

        Toast.makeText(this, "back Camera Found", Toast.LENGTH_LONG).show();
        // Create an instance of Camera
        mCamera = getCameraInstance();

    }    

    // Create our Preview view and set it as the content of our activity.
    mPreview = new CameraPreview(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mPreview);      

}

public static Camera getCameraInstance(){
    Camera c = null;

    try {
        c = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
        Log.d("cam", "Camera is not available - in use or does not exist");
    }
    return c; // returns null if camera is unavailable
}

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();

    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
    }

};

}

使用 SurfaceView 的 CameraPreview 类:

package com.example.cameraappdemo;

import java.io.IOException;

import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/** A basic Camera preview class */
@SuppressLint("ViewConstructor")
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;

public CameraPreview(Context context, Camera camera) {
    super(context);
    mCamera = camera;

    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    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) {
    // The Surface has been created, now tell the camera where to draw the preview.

    try {

       mCamera.setPreviewDisplay(holder);

       mCamera.startPreview();

    } catch (IOException e) {
        Log.d("TAG", "Error setting camera preview: ");
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // empty. Take care of releasing the Camera preview in your activity.
}

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.

    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
    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();

    } catch (Exception e){
        Log.d("TAG", "Error starting camera preview: " + e.getMessage());
    }
}
}
4

1 回答 1

1

我弄清楚了问题所在。我不得不在 Resume() 上调用 CameraPreview 类的引用,因为 UI 需要一些时间来加载,因此最好在另一个线程中调用该对象。

这就是我所做的:

package com.example.cameraappdemo;

import android.hardware.Camera; 
import android.os.Bundle;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.Toast;


public class MainActivity extends Activity {

private Camera mCamera;
private CameraPreview mPreview;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    //checks for back Camera
    if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {

        Toast.makeText(this, "back Camera Found", Toast.LENGTH_LONG).show();
                        // Create an instance of Camera
        mCamera = getCameraInstance();

    }                                           

}

public static Camera getCameraInstance(){
    Camera c = null;

    try {
        c = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
        Log.d("cam", "Camera is not available - in use or does not exist");
    }
    return c; // returns null if camera is unavailable
}

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();

}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();

// Create our Preview view and set it as the content of our activity.   
    mPreview = new CameraPreview(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mPreview);

}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();

    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
    }       

}

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();

    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
    }

};

}
于 2013-10-31T14:50:18.130 回答