Login     Sign Up
Tugadar Networking Community (@admin)
5 months ago
43 Views

Using the Camera

The popularity of digital cameras (particularly within phone handsets) has caused their prices to drop just as their size has shrunk dramatically. It’s now becoming difficult to even find a mobile phone with-out a camera, and Android devices are unlikely to be exceptions.

To access the camera hardware, you need to add the CAMERA permission to your application manifest, as shown here:

<uses-permission android:name=”android.permission.CAMERA”/>

This grants access to the Camera Service. The Camera class lets you adjust camera settings, take pic-tures, and manipulate streaming camera previews.

To access the Camera Service, use the static open method on the Camera class. When your application has finished with the camera, remember to relinquish your hold on the Service by calling release fol-lowing the simple use pattern shown in the code snippet below:

Camera camera = Camera.open();

… Do things with the camera … ] camera.release();

Controlling Camera Settings

The current camera settings are available as a Camera.Parameters object. Call the getParameters method on the Camera to access the current parameters.

You can use the set* methods on the returned Parameters to modify the settings. To apply changes, call setParameters, passing in the modified values as shown below:

Camera.Parameters parameters = camera.getParameters(); parameters.setPictureFormat(PixelFormat.JPEG); camera.setParameters(parameters);

The Camera Parameters can be used to specify the image and preview size, image format, and preview frame rate.

Using the Camera Preview

Access to the camera’s streaming video means that you can incorporate live video into your applica-tions. Some of the most exciting early Android applications have used this functionality as the basis for augmenting reality.

The camera preview can be displayed in real time onto a Surface, as shown in the code snippet below:

camera.setPreviewDisplay(mySurface);

camera.startPreview();

… ] camera.stopPreview();

You’ll learn more about Surfaces in the following chapter, although Android includes an excellent example of using a SurfaceView to display the camera preview in real time. This example is available in the graphics/CameraPreview project in the SDK API demos.

You can also assign a PreviewCallback to be fired for each preview frame, allowing you to manipu-late or display each preview frame individually. Call the setPreviewCallback method on the Camera object, passing in a new PreviewCallback implementation overriding the onPreviewFrame method as shown here:

camera.setPreviewCallback(new PreviewCallback() {

public void onPreviewFrame(byte[] _data, Camera _camera) { // TODO Do something with the preview image.

}

});

Taking a Picture

Take a picture by calling takePicture on a Camera object, passing in a ShutterCallback and PictureCallback implementations for the RAW and JPEG-encoded images. Each picture callback will receive a byte array representing the image in the appropriate format, while the shutter callback is triggered immediately after the shutter is closed.

private void takePicture() {

camera.takePicture(shutterCallback, rawCallback, jpegCallback);

}

ShutterCallback shutterCallback = new ShutterCallback() {

public void onShutter() {

// TODO Do something when the shutter closes.

}

};

PictureCallback rawCallback = new PictureCallback() { public void onPictureTaken(byte[] _data, Camera _camera) {

// TODO Do something with the image RAW data.

}

};

PictureCallback jpegCallback = new PictureCallback() { public void onPictureTaken(byte[] _data, Camera _camera) {

// TODO Do something with the image JPEG data.

}

};

Introducing the Sensor Manager

The Sensor Manager is used to manage the sensor hardware available on an Android device. Use getSystemService to get a reference to the Sensor Service as shown in the code snippet below:

String service_name = Context.SENSOR_SERVICE;

SensorManager sensorManager = (SensorManager)getSystemService(service_name);

The following sections look closely at how to use the Sensor Manager to monitor orientation and accelera-tion, but the pattern shown here can be used to monitor sensor results from any available hardware sensor:

SensorListener mySensorListener = new SensorListener() { public void onSensorChanged(int sensor, float[] values) {

// TODO Deal with sensor value changes

}

public void onAccuracyChanged(int sensor, int accuracy) { // TODO Auto-generated method stub

}

};

The SensorListener interface is used to listen for Sensor value and accuracy changes.

Implement the onSensorChanged method to react to value changes. The sensor parameter identifies the sensor that triggered the event, while the values float array contains the new values detected by that sensor.

Implement onAccuracyChanged to react to changes in a sensor’s accuracy. The sensor parameter again identifies the sensor that triggered the event, while the accuracy parameter indicates the new accuracy of that sensor using one of the constants:

SensorManager.SENSOR_STATUS_ACCURACY_HIGH Indicates that the sensor is reporting with

the highest possible accuracy.

SensorManager.SENSOR_STATUS_ACCURACY_LOW Indicates that the sensor is reporting with

low accuracy and needs to be calibrated.

SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM Indicates that the sensor data is of

average accuracy, and that calibration might improve the readings.

SensorManager.SENSOR_STATUS_UNRELIABLE Indicates that the sensor data is unreliable,

meaning that either calibration is required or readings are not currently possible.

The Sensor Manager includes constants to help identify the sensor triggering the change event. The fol-lowing list includes the sensors for which constants are currently defined. Some or all of these sensors will be available to your applications depending on the hardware available on the host device:

❑SensorManager.SENSOR_ACCELEROMETER Is an accelerometer sensor that returns the cur-rent acceleration along three axes in meters per second squared (m/s2). The accelerometer is explored in greater detail later in this chapter.

❑SensorManager.SENSOR_ORIENTATION Is an orientation sensor that returns the current ori-entation on three axes in degrees. The orientation sensor is explored in greater detail later in this chapter.

❑SensorManager.SENSOR_LIGHT Is an ambient-light sensor that returns a single value describing the ambient illumination in lux.

SensorManager.SENSOR_MAGNETIC_FIELD Is a sensor used to determine the current mag-netic field measured in microteslas (μT) along three axes.

❑SensorManager.SENSOR_PROXIMITY Is a proximity sensor that returns a single value describing the distance between the device and the target object in meters (m).

❑SensorManager.SENSOR_TEMPERATURE Is a thermometer sensor that returns the ambient temperature in degrees Celsius (˚C).

To receive notifications of changes from a particular sensor, create a Sensor Listener as described previ-ously, and register it with the Sensor Manager specifying the sensor that should trigger the Listener and the rate at which the sensor should update, as shown in the following code snippet:

sensorManager.registerListener(mySensorListener,

SensorManager.SENSOR_TRICORDER,

SensorManager.SENSOR_DELAY_FASTEST);

The Sensor Manager includes the following constants (shown in descending order of responsiveness) to let you select a suitable update rate:

❑SensorManager.SENSOR_DELAY_FASTEST Specifies the fastest possible sensor update rate.

❑SensorManager.SENSOR_DELAY_GAME Selects an update rate suitable for use in controlling games.

SensorManager.SENSOR_DELAY_NORMAL Specifies the default update rate.

❑SensorManager.SENSOR_DELAY_UI Specifies a rate suitable for updating UI features.

The rate you select is not binding; the Sensor Manager may return results faster or slower than you specify, though it will tend to be faster. To minimize the associated resource cost of using the sensor in your application you should try to select the slowest suitable rate.

An overloaded registerListener method is also available that applies the default (SENSOR_DELAY_

NORMAL) update rate, as shown below:

sensorManager.registerListener(mySensorListener, SensorManager.SENSOR_TRICORDER);