2012-06-06 23 views
0

我正在使用相機應用程序,需要在相機視圖前面有圖像。所以基本上需要在表面視圖的頂部有一個表面視圖。未能連接到具有兩個曲面視角的相機服務

當我嘗試運行應用程序,我得到以下錯誤: 了java.lang.RuntimeException:無法連接到相機服務

PictureDemo.java

package com.commonsware.android.picture; 

import java.io.File; 
import java.io.FileOutputStream; 

import com.commonsware.android.picture.R; 
import android.app.Activity; 
import android.graphics.ImageFormat; 
import android.hardware.Camera; 
import android.os.AsyncTask; 
import android.os.Build; 
import android.os.Bundle; 
import android.os.Environment; 
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.widget.Toast; 

public class PictureDemo extends Activity { 
    private SurfaceView preview=null; 
    private SurfaceHolder previewHolder=null; 
    private Camera camera=null; 
    private boolean inPreview=false; 
    private boolean cameraConfigured=false; 

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

    preview=(SurfaceView)findViewById(R.id.preview); 
    previewHolder=preview.getHolder(); 
    previewHolder.addCallback(surfaceCallback); 
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

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

    // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { 
    // Camera.CameraInfo info=new Camera.CameraInfo(); 
    // for (int i=0; i < Camera.getNumberOfCameras(); i++) { 
    //  Camera.getCameraInfo(i, info); 

    //  if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
    //  camera=Camera.open(i); 
    //  } 
    // } 
    // } 

    if (camera == null) { 
     camera=Camera.open(); 
    } 

    startPreview(); 
    } 

    @Override 
    public void onPause() { 
    if (inPreview) { 
     camera.stopPreview(); 
    } 

    camera.release(); 
    camera=null; 
    inPreview=false; 

    super.onPause(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
    new MenuInflater(this).inflate(R.menu.options, menu); 

    return(super.onCreateOptionsMenu(menu)); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
    if (item.getItemId() == R.id.camera) { 
     if (inPreview) { 
     camera.takePicture(null, null, photoCallback); 
     inPreview=false; 
     } 
    } 

    return(super.onOptionsItemSelected(item)); 
    } 

    private Camera.Size getBestPreviewSize(int width, int height, 
             Camera.Parameters parameters) { 
    Camera.Size result=null; 

    for (Camera.Size size : parameters.getSupportedPreviewSizes()) { 
     if (size.width <= width && size.height <= height) { 
     if (result == null) { 
      result=size; 
     } 
     else { 
      int resultArea=result.width * result.height; 
      int newArea=size.width * size.height; 

      if (newArea > resultArea) { 
      result=size; 
      } 
     } 
     } 
    } 

    return(result); 
    } 

    private Camera.Size getSmallestPictureSize(Camera.Parameters parameters) { 
    Camera.Size result=null; 

    for (Camera.Size size : parameters.getSupportedPictureSizes()) { 
     if (result == null) { 
     result=size; 
     } 
     else { 
     int resultArea=result.width * result.height; 
     int newArea=size.width * size.height; 

     if (newArea < resultArea) { 
      result=size; 
     } 
     } 
    } 

    return(result); 
    } 

    private void initPreview(int width, int height) { 
    if (camera != null && previewHolder.getSurface() != null) { 
     try { 
     camera.setPreviewDisplay(previewHolder); 
     } 
     catch (Throwable t) { 
     Log.e("PreviewDemo-surfaceCallback", 
       "Exception in setPreviewDisplay()", t); 
     Toast.makeText(PictureDemo.this, t.getMessage(), 
         Toast.LENGTH_LONG).show(); 
     } 

     if (!cameraConfigured) { 
     Camera.Parameters parameters=camera.getParameters(); 
     Camera.Size size=getBestPreviewSize(width, height, parameters); 
     Camera.Size pictureSize=getSmallestPictureSize(parameters); 

     if (size != null && pictureSize != null) { 
      parameters.setPreviewSize(size.width, size.height); 
      parameters.setPictureSize(pictureSize.width, 
            pictureSize.height); 
      parameters.setPictureFormat(ImageFormat.JPEG); 
      camera.setParameters(parameters); 
      cameraConfigured=true; 
     } 
     } 
    } 
    } 

    private void startPreview() { 
    if (cameraConfigured && camera != null) { 
     camera.startPreview(); 
     inPreview=true; 
    } 
    } 

    SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() { 
    public void surfaceCreated(SurfaceHolder holder) { 
     // no-op -- wait until surfaceChanged() 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, 
           int width, int height) { 
     initPreview(width, height); 
     startPreview(); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     // no-op 
    } 
    }; 

    Camera.PictureCallback photoCallback=new Camera.PictureCallback() { 
    public void onPictureTaken(byte[] data, Camera camera) { 
     new SavePhotoTask().execute(data); 
     camera.startPreview(); 
     inPreview=true; 
    } 
    }; 

    class SavePhotoTask extends AsyncTask<byte[], String, String> { 
    @Override 
    protected String doInBackground(byte[]... jpeg) { 
     File photo= 
      new File(Environment.getExternalStorageDirectory(), 
        "/photo.jpg"); 

     if (photo.exists()) { 
     photo.delete(); 
     } 

     try { 
     FileOutputStream fos=new FileOutputStream(photo.getPath()); 

     fos.write(jpeg[0]); 
     fos.close(); 
     } 
     catch (java.io.IOException e) { 
     Log.e("PictureDemo", "Exception in photoCallback", e); 
     } 

     return(null); 
    } 
    } 
} 

MySurfaceView.java

package com.commonsware.android.picture; 

import java.io.IOException; 
import java.nio.Buffer; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.hardware.Camera; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceHolder.Callback; 
import android.view.SurfaceView; 

public class MySurfaceView extends SurfaceView implements Callback, 
    Camera.PreviewCallback { 

    private SurfaceHolder mHolder; 

    private Camera mCamera; 
    private boolean isPreviewRunning = false; 
    private byte [] rgbbuffer = new byte[256 * 256]; 
    private int [] rgbints = new int[256 * 256]; 

    protected final Paint rectanglePaint = new Paint(); 

    public MySurfaceView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
     rectanglePaint.setARGB(100, 200, 0, 0); 
     rectanglePaint.setStyle(Paint.Style.FILL); 
     rectanglePaint.setStrokeWidth(2); 

     mHolder = getHolder(); 
     mHolder.addCallback(this); 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawRect(new Rect((int) Math.random() * 100, 
      (int) Math.random() * 100, 200, 200), rectanglePaint); 
     Log.w(this.getClass().getName(), "On Draw Called"); 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     synchronized (this) { 
      this.setWillNotDraw(false); // This allows us to make our own draw 
            // calls to this canvas 

      mCamera = Camera.open(); 

      Camera.Parameters p = mCamera.getParameters(); 
      p.setPreviewSize(240, 160); 
      mCamera.setParameters(p); 


      //try { mCamera.setPreviewDisplay(holder); } catch (IOException e) 
      // { Log.e("Camera", "mCamera.setPreviewDisplay(holder);"); } 

      mCamera.startPreview(); 
      mCamera.setPreviewCallback(this); 

     } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     synchronized (this) { 
      try { 
       if (mCamera != null) { 
        mCamera.stopPreview(); 
        isPreviewRunning = false; 
        mCamera.release(); 
       } 
      } catch (Exception e) { 
       Log.e("Camera", e.getMessage()); 
      } 
     } 
    } 

    public void onPreviewFrame(byte[] data, Camera camera) { 
     Log.d("Camera", "Got a camera frame"); 

     Canvas c = null; 

     if(mHolder == null){ 
      return; 
     } 

     try { 
      synchronized (mHolder) { 
       c = mHolder.lockCanvas(null); 

       // Do your drawing here 
       // So this data value you're getting back is formatted in YUV format and you can't do much 
       // with it until you convert it to rgb 
       int bwCounter=0; 
       int yuvsCounter=0; 
       for (int y=0;y<160;y++) { 
        System.arraycopy(data, yuvsCounter, rgbbuffer, bwCounter, 240); 
        yuvsCounter=yuvsCounter+240; 
        bwCounter=bwCounter+256; 
       } 

       for(int i = 0; i < rgbints.length; i++){ 
        rgbints[i] = (int)rgbbuffer[i]; 
       } 

       //decodeYUV(rgbbuffer, data, 100, 100); 
       c.drawBitmap(rgbints, 0, 256, 0, 0, 256, 256, false, new Paint()); 

       Log.d("SOMETHING", "Got Bitmap"); 

      } 
     } finally { 
      // do this in a finally so that if an exception is thrown 
      // during the above, we don't leave the Surface in an 
      // inconsistent state 
      if (c != null) { 
       mHolder.unlockCanvasAndPost(c); 
      } 
     } 
    } 
} 

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> 
<manifest android:versionCode="1" 
      android:versionName="1.0" 
      package="com.commonsware.android.picture" 
      xmlns:android="http://schemas.android.com/apk/res/android"> 

    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="11"/> 
    <supports-screens android:largeScreens="false" 
        android:normalScreens="true" 
        android:smallScreens="false" android:xlargeScreens="true"/> 
    <uses-feature android:name="android.hardware.camera" /> 
    <uses-feature android:name="android.hardware.camera.front" 
       android:required="false" /> 
    <uses-permission android:name="android.permission.CAMERA" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

    <application android:icon="@drawable/cw" 
       android:label="@string/app_name"> 
    <activity android:configChanges="keyboardHidden|orientation" 
       android:label="@string/app_name" 
       android:name=".PictureDemo" 
       android:screenOrientation="landscape"> 

     <intent-filter> 
     <action android:name="android.intent.action.MAIN" /> 
     <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter>  
    </activity> 


    </application> 
</manifest> 

main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_height="match_parent" 
     android:layout_width="match_parent"> 
    <android.view.SurfaceView 
      android:id="@+id/preview" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 
     </android.view.SurfaceView> 
    <com.commonsware.android.picture.MySurfaceView 
      android:id="@+id/surface_camera" 
      android:layout_width="fill_parent" android:layout_height="10dip" 
      android:layout_weight="1"> 
     </com.commonsware.android.picture.MySurfaceView> 
</RelativeLayout> 

任何人都得到一個解決方案嗎?

回答

1

問題是我認爲Camera是一個共享的globl資源,只能在任何給定的時間連接一次。具體來說,從Camera.open調用文檔:

Your application should only have one Camera object active at a time for a particular hardware camera.

相關問題