Wrox Programmer Forums
Go Back   Wrox Programmer Forums > Mobile Development > BOOK: Professional Android 2 Application Development
BOOK: Professional Android 2 Application Development
This is the forum to discuss the Wrox book Professional Android 2 Application Development, 2nd Edition by Reto Meier; ISBN: 978-0-470-56552-0
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Professional Android 2 Application Development section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
Old July 26th, 2012, 06:54 AM
Registered User
Join Date: Jun 2012
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default Listing 15-23: Surface View skeleton implementation


I am trying to implement a Surface View to draw information on a camera preview. I am using this listing as a guide. I am confused though as I can't work out when the resume() method is called. A call to this is needed to initialise the thread, but I can't work out where to call it without it crashing my application. Without this call, mySurfaceViewThread is always null.

Can anyone please help, or direct me to a good augmented reality example?

This is my code.

package com.example.augmentedreality;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.RectF;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

public class CustomCameraView extends SurfaceView implements SurfaceHolder.Callback {

private Camera camera;
private SurfaceHolder previewHolder;
protected float bearing;
private MySurfaceViewThread mySurfaceViewThread;
private boolean hasSurface;

private Paint textPaint;

float[] aValues = new float[3];
float[] mValues = new float[3];

Context context;

public static SensorManager sensorManager;

public CustomCameraView(Context context) {

this.context = context;

// Create a new SurfaceHolder and assign this class as its callback.
previewHolder = getHolder();
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_P USH_BUFFERS);
hasSurface = false;

toast("added callback");

textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

sensorManager = (SensorManager)context.getSystemService(Context.SE NSOR_SERVICE);

Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELER OMETER);
Sensor magField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETI C_FIELD);

sensorManager.registerListener(sensorEventListener , accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(sensorEventListener , magField, SensorManager.SENSOR_DELAY_FASTEST);


public void resume() {
// Create and start the graphics update thread.
if (mySurfaceViewThread == null) {
mySurfaceViewThread = new MySurfaceViewThread();
if (hasSurface == true) {
toast("thread started");


public void pause() {
// Kill the graphics update thread
if (mySurfaceViewThread != null) {
mySurfaceViewThread = null;

public void surfaceCreated(SurfaceHolder holder) {
toast("surface created");
hasSurface = true;

if (mySurfaceViewThread != null) {
toast("thread started");

hasSurface = true;
catch (Throwable e) {


public void surfaceDestroyed(SurfaceHolder holder) {
toast("surface destroyed");
hasSurface = false;
camera = null;

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
toast("surface changed");
Parameters params = camera.getParameters();
params.setPreviewSize(width, height);
if (mySurfaceViewThread != null) mySurfaceViewThread.onWindowResize(width, height);

class MySurfaceViewThread extends Thread {
private boolean done;

MySurfaceViewThread() {
toast("thread initialised");
done = false;


public void run() {
SurfaceHolder surfaceHolder = previewHolder;

int height = getMeasuredHeight();
int width = getMeasuredWidth();
int px = width / 2;
int py = height / 2;
Point center = new Point(px, py);
int radius = Math.min(px, py) - 2;

RectF boundingBox = new RectF( center.x - radius,
center.y - radius,
center.x + radius,
center.y + radius);

// Repeat the drawing loop until the thread is stopped
while (!done)
toast("in run loop");
Canvas canvas = surfaceHolder.lockCanvas();
// TODO: Draw on the canvas
//String text = "Bearing = " + bearing;
String text = "text";
canvas.drawText(text, px, py, textPaint);
canvas.drawOval(boundingBox, textPaint);

public void requestExitAndWait() {
// Mark this thread as complete and combine into
// the main application thread.
done = true;
try {
} catch (InterruptedException ex) { }

public void onWindowResize(int w, int h) {
// Deal with a change in the available surface size.

private float[] calculateOrientation() {
float[] values = new float[3];
float[] R = new float[9];
float[] outR = new float[9];

SensorManager.getRotationMatrix(R, null, aValues, mValues);
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
SensorManager.getOrientation(outR, values);

// Convert from Radians to Degrees
values[0] = (float) Math.toDegrees(values[0]);
values[1] = (float) Math.toDegrees(values[1]);
values[2] = (float) Math.toDegrees(values[2]);

return values;

private void updateOrientation(float[] values) {
bearing = values[0];
//Toast.makeText(getContext(), "Bearing = " + bearing, Toast.LENGTH_SHORT).show();

SensorEventListener sensorEventListener = new SensorEventListener(){
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub

public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
aValues = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mValues = event.values;


private void toast(String str){
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, str, duration);



Similar Threads
Thread Thread Starter Forum Replies Last Post
Listing 2-15 alxndr000 BOOK: Professional ASP.NET 3.5 : in C# and VB ISBN: 978-0-470-18757-9 0 June 16th, 2010 03:26 PM
listing 15-15 pg(568) DyerOppenheimer BOOK: Professional ASP.NET 2.0 and Special Edition; ISBN: 978-0-7645-7610-2; ISBN: 978-0-470-04178-9 0 February 13th, 2008 01:41 PM
Listing 23-15 John Leo BOOK: Professional ASP.NET 2.0 and Special Edition; ISBN: 978-0-7645-7610-2; ISBN: 978-0-470-04178-9 0 April 4th, 2007 02:42 PM
Listing 23-6 Using Express Edition rsendek BOOK: Professional ASP.NET 2.0 and Special Edition; ISBN: 978-0-7645-7610-2; ISBN: 978-0-470-04178-9 2 December 7th, 2006 06:21 PM
Listing 23-43 wombel BOOK: Professional ASP.NET 2.0 and Special Edition; ISBN: 978-0-7645-7610-2; ISBN: 978-0-470-04178-9 0 November 30th, 2006 09:40 AM

Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.