atom feed3 messages in com.googlegroups.android-developers[android-developers] Camera Preview o...
FromSent OnAttachments
BobalotJul 6, 2008 9:21 am 
BobalotJul 6, 2008 10:08 am 
code_android_festival_wayJul 8, 2008 8:42 am 
Subject:[android-developers] Camera Preview onto SurfaceView using xml
From:Bobalot (boba@gmail.com)
Date:Jul 6, 2008 9:21:46 am
List:com.googlegroups.android-developers

hi, im trying to make a simple camera app, by extending the CameraPreview class in the api demos, anyway im trying to cast the preview onto a surfaceview that i have defined in my layout xml file. but everytime i do this i get a null pointer exception, and i cant for the life of me figure out how to make this work.

if anyone has any info or sample code i would be very gratefull. this is what i have so far, the Preview class is what i took from the CameraPreview.java

------------------------------------------------------------------------------------------------ package bob.CameraAlbum;

import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.hardware.CameraDevice; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.TabHost; import android.widget.TabHost.TabSpec;

public class Camera extends Activity { private TabHost myTabHost; private Preview mPreview;

@Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); //SurfaceHolder mHolder; // Hide the window title. // requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.tabs); mPreview = new Preview(this);

this.myTabHost = (TabHost)this.findViewById(R.id.tabhost); this.myTabHost.setup();

TabSpec ts1 = myTabHost.newTabSpec("TAB1"); ts1.setIndicator("Take Photo", getResources().getDrawable(R.drawable.cameraphoto)); ts1.setContent(R.id.grid_set_menu_page1); this.myTabHost.addTab(ts1);

TabSpec ts2 = myTabHost.newTabSpec("TAB2"); ts2.setIndicator("Album", getResources().getDrawable(R.drawable.driveharddisk)); ts2.setContent(R.id.grid_set_menu_page2); this.myTabHost.addTab(ts2);

TabSpec ts3 = myTabHost.newTabSpec("TAB3"); ts3.setIndicator("Upload", getResources().getDrawable(R.drawable.networkwireless)); ts3.setContent(R.id.grid_set_menu_page3); this.myTabHost.addTab(ts3);

this.myTabHost.setCurrentTab(0);

//mPreview = (Preview) findViewById(R.id.photo_surface);

}

@Override protected void onResume() { // Because the CameraDevice object is not a shared resource, // it's very important to release it when the activity is paused. super.onResume(); mPreview.resume(); }

@Override protected void onPause() { // Start Preview again when we resume. super.onPause(); mPreview.pause(); }

}

class Preview extends SurfaceView implements SurfaceHolder.Callback { SurfaceHolder mHolder; private PreviewThread mPreviewThread; private boolean mHasSurface; SurfaceView Sview; Preview(Context context) { super(context);

// Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. Sview=(SurfaceView) findViewById(R.id.photo_surface); mHolder = Sview.getHolder();

mHolder.addCallback(this); mHasSurface = false;

// In this example, we hardcode the size of the preview. In a real // application this should be more dynamic. This guarantees that // the uderlying surface will never change size. mHolder.setFixedSize(320, 240); }

public void resume() { // We do the actual acquisition in a separate thread. Create it now. if (mPreviewThread == null) { mPreviewThread = new PreviewThread(); // If we already have a surface, just start the thread now too. if (mHasSurface == true) { mPreviewThread.start(); } } }

public void pause() { // Stop Preview. if (mPreviewThread != null) { mPreviewThread.requestExitAndWait(); mPreviewThread = null; } }

public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, start our main acquisition thread. mHasSurface = true; if (mPreviewThread != null) { mPreviewThread.start(); } }

public void surfaceDestroyed(SurfaceHolder holder) { // Surface will be destroyed when we return. Stop the preview. mHasSurface = false; pause(); }

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // Surface size or format has changed. This should not happen in this // example. }

//

----------------------------------------------------------------------

class PreviewThread extends Thread { private boolean mDone;

PreviewThread() { super(); mDone = false; }

@Override public void run() { // We first open the CameraDevice and configure it. CameraDevice camera = CameraDevice.open(); if (camera != null) { CameraDevice.CaptureParams param = new CameraDevice.CaptureParams(); param.type = 1; // preview param.srcWidth = 1280; param.srcHeight = 960; param.leftPixel = 0; param.topPixel = 0; param.outputWidth = 320; param.outputHeight = 240; param.dataFormat = 2; // RGB_565 camera.setCaptureParams(param); }

// This is our main acquisition thread's loop, we go until // asked to quit. SurfaceHolder holder = mHolder; while (!mDone) { // Lock the surface, this returns a Canvas that can // be used to render into. Canvas canvas = holder.lockCanvas();

// Capture directly into the Surface if (camera != null) { camera.capture(canvas); }

// And finally unlock and post the surface. holder.unlockCanvasAndPost(canvas); }

// Make sure to release the CameraDevice if (camera != null) { camera.close(); } }

public void requestExitAndWait() { // don't call this from PreviewThread thread or it a guaranteed // deadlock! mDone = true; try { join(); } catch (InterruptedException ex) { } } } }

-------------------------------------------------------------------------------------