2011-03-11 61 views
1

我開發了一個android2.3項目,從ApiDemos複製示例代碼「CameraPreview」,並在我的evo 4g手機上運行它,後面的攝像頭是正確的,當切換到前置攝像頭時,屏幕是「綠色屏幕」有什麼問題?訪問前置攝像頭「綠色屏幕」?

CameraPreview

// ---------------------------------------------------------------------- 

import java.io.IOException; 
import java.util.List; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.Context; 
import android.hardware.Camera; 
import android.hardware.Camera.CameraInfo; 
import android.hardware.Camera.Size; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.Window; 
import android.view.WindowManager; 

public class CameraPreview extends Activity 
{ 
    private Preview mPreview; 
    Camera   mCamera; 
    int    numberOfCameras; 
    int    cameraCurrentlyLocked; 

    // The first rear facing camera 
    int    defaultCameraId; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     // Hide the window title. 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     // Create a RelativeLayout container that will hold a SurfaceView, 
     // and set it as the content of our activity. 
     mPreview = new Preview(this); 
     setContentView(mPreview); 

     // Find the total number of cameras available 
     numberOfCameras = Camera.getNumberOfCameras(); 

     // Find the ID of the default camera 
     CameraInfo cameraInfo = new CameraInfo(); 
     for (int i = 0; i < numberOfCameras; i++) 
     { 
      Camera.getCameraInfo(i, cameraInfo); 
      if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) 
      { 
       defaultCameraId = i; 
      } 
     } 
    } 

    @Override 
    protected void onResume() 
    { 
     super.onResume(); 

     // Open the default i.e. the first rear facing camera. 
     mCamera = Camera.open(); 
     cameraCurrentlyLocked = defaultCameraId; 
     mPreview.setCamera(mCamera); 
    } 

    @Override 
    protected void onPause() 
    { 
     super.onPause(); 

     // Because the Camera object is a shared resource, it's very 
     // important to release it when the activity is paused. 
     if (mCamera != null) 
     { 
      mPreview.setCamera(null); 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) 
    { 

     // Inflate our menu which can gather user input for switching camera 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.camera_menu, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) 
    { 
     // Handle item selection 
     switch (item.getItemId()) 
     { 
      case R.id.switch_cam: 
       // check for availability of multiple cameras 
       if (numberOfCameras == 1) 
       { 
        AlertDialog.Builder builder = new AlertDialog.Builder(this); 
        builder.setMessage(this.getString(R.string.camera_alert)).setNeutralButton("Close", null); 
        AlertDialog alert = builder.create(); 
        alert.show(); 
        return true; 
       } 

       // OK, we have multiple cameras. 
       // Release this camera -> cameraCurrentlyLocked 
       if (mCamera != null) 
       { 
        mCamera.stopPreview(); 
        mPreview.setCamera(null); 
        mCamera.release(); 
        mCamera = null; 
       } 

       // Acquire the next camera and request Preview to reconfigure 
       // parameters. 
       mCamera = Camera.open((cameraCurrentlyLocked + 1) 
         % numberOfCameras); 
       cameraCurrentlyLocked = (cameraCurrentlyLocked + 1) 
         % numberOfCameras; 
       mPreview.switchCamera(mCamera); 

       // Start the preview 
       mCamera.startPreview(); 
       return true; 
      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 
} 

// ---------------------------------------------------------------------- 

/** 
* A simple wrapper around a Camera and a SurfaceView that renders a centered 
* preview of the Camera to the surface. We need to center the SurfaceView 
* because not all devices have cameras that support preview sizes at the same 
* aspect ratio as the device's display. 
*/ 
class Preview extends ViewGroup implements SurfaceHolder.Callback 
{ 
    private final String TAG = "Preview"; 

    SurfaceView    mSurfaceView; 
    SurfaceHolder   mHolder; 
    Size     mPreviewSize; 
    List<Size>    mSupportedPreviewSizes; 
    Camera     mCamera; 

    Preview(Context context) 
    { 
     super(context); 

     mSurfaceView = new SurfaceView(context); 
     addView(mSurfaceView); 

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

    public void setCamera(Camera camera) 
    { 
     mCamera = camera; 
     if (mCamera != null) 
     { 
      mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
      requestLayout(); 
     } 
    } 

    public void switchCamera(Camera camera) 
    { 
     setCamera(camera); 
     try 
     { 
      camera.setPreviewDisplay(mHolder); 
     } 
     catch (IOException exception) 
     { 
      Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); 
     } 
     Camera.Parameters parameters = camera.getParameters(); 
     parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
     requestLayout(); 

     camera.setParameters(parameters); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    { 
     // We purposely disregard child measurements because act as a 
     // wrapper to a SurfaceView that centers the camera preview instead 
     // of stretching it. 
     final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
     final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
     setMeasuredDimension(width, height); 

     if (mSupportedPreviewSizes != null) 
     { 
      mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); 
     } 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) 
    { 
     if (changed && getChildCount() > 0) 
     { 
      final View child = getChildAt(0); 

      final int width = r - l; 
      final int height = b - t; 

      int previewWidth = width; 
      int previewHeight = height; 
      if (mPreviewSize != null) 
      { 
       previewWidth = mPreviewSize.width; 
       previewHeight = mPreviewSize.height; 
      } 

      // Center the child SurfaceView within the parent. 
      if (width * previewHeight > height * previewWidth) 
      { 
       final int scaledChildWidth = previewWidth * height 
         /previewHeight; 
       child.layout((width - scaledChildWidth)/2, 0, (width + scaledChildWidth)/2, height); 
      } else 
      { 
       final int scaledChildHeight = previewHeight * width 
         /previewWidth; 
       child.layout(0, (height - scaledChildHeight)/2, width, (height + scaledChildHeight)/2); 
      } 
     } 
    } 

    public void surfaceCreated(SurfaceHolder holder) 
    { 
     // The Surface has been created, acquire the camera and tell it where 
     // to draw. 
     try 
     { 
      if (mCamera != null) 
      { 
       mCamera.setPreviewDisplay(holder); 
      } 
     } catch (IOException exception) 
     { 
      Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); 
     } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) 
    { 
     // Surface will be destroyed when we return, so stop the preview. 
     if (mCamera != null) 
     { 
      mCamera.stopPreview(); 
     } 
    } 

    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) 
    { 
     final double ASPECT_TOLERANCE = 0.1; 
     double targetRatio = (double) w/h; 
     if (sizes == null) 
      return null; 

     Size optimalSize = null; 
     double minDiff = Double.MAX_VALUE; 

     int targetHeight = h; 

     // Try to find an size match aspect ratio and size 
     for (Size size : sizes) 
     { 
      double ratio = (double) size.width/size.height; 
      if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) 
       continue; 
      if (Math.abs(size.height - targetHeight) < minDiff) 
      { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 

     // Cannot find the one match the aspect ratio, ignore the requirement 
     if (optimalSize == null) 
     { 
      minDiff = Double.MAX_VALUE; 
      for (Size size : sizes) 
      { 
       if (Math.abs(size.height - targetHeight) < minDiff) 
       { 
        optimalSize = size; 
        minDiff = Math.abs(size.height - targetHeight); 
       } 
      } 
     } 
     return optimalSize; 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) 
    { 
     // Now that the size is known, set up the camera parameters and begin 
     // the preview. 
     Camera.Parameters parameters = mCamera.getParameters(); 
     parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
     requestLayout(); 

     mCamera.setParameters(parameters); 
     mCamera.startPreview(); 
    } 

} 


AndroidManifest.xml 

    <?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="com.kiterive.magicmirror" 
     android:versionCode="1" 
     android:versionName="1.0"> 
    <uses-sdk android:minSdkVersion="9" /> 
    <!-- We will request access to the camera, saying we require a camera 
     of some sort but not one with autofocus capability. --> 
    <uses-permission android:name="android.permission.CAMERA" /> 
    <uses-feature android:name="android.hardware.camera" /> 
    <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" /> 

    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
     <activity android:name=".MagicMirrorActivity" 
        android:label="@string/app_name" 
        android:screenOrientation="landscape"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

    </application> 
</manifest> 

回答

0

的EVO 4G(在寫的)運行Android 2.2,它缺乏爲2.3前置攝像頭的API支持。我很驚訝你的代碼示例運行時沒有觸發你調用的2.3 API調用的異常。

0

這很可能是設備問題,驅動程序或其他問題。 嘗試在另一臺設備上測試它。 還要確保設備運行的是Android 2.3或更高版本,低於此值不受支持。