This example shows how to access the camera on a device and display its output in a view.
Note that, in order to access the camera, the application needs to be built with the android.hardware.camera feature and android.permission.CAMERA permission. The build script takes care of this.
We import the classes and modules needed by our application. The most relevant to this example are the Camera class from the android.hardware module and the SurfaceHolder and SurfaceView classes from the android.view module.
from java.lang import String
from android.app import Activity
import android.os
from android.hardware import Camera
from android.view import SurfaceHolder, SurfaceView
The CameraActivity class is derived from the standard Activity class and represents the application. Android will create an instance of this class when the user runs it.
class CameraActivity(Activity):
__interfaces__ = [SurfaceHolder.Callback]
The class implements the SurfaceHolder.Callback interface, declaring
this in the list of interfaces defined by the __interfaces__
attribute.
Implementing this interface involves implementing three methods that are
described later.
We define a field that we can use as an instance attribute. This is needed because we cannot explicitly create an instance of the Camera class and the default value we want to assign to the attribute is the special None value, which corresponds to a null value in Java.
__fields__ = {"camera": Camera}
The initialisation method calls the corresponding method in the base
class. We also assign a value of None to the camera
attribute, indicating
that no camera is currently available.
def __init__(self):
Activity.__init__(self)
self.camera = None
The onCreate method calls the corresponding method in the base class to help set up the activity. We obtain an object that represents the camera and set up the user interface.
@args(void, [android.os.Bundle])
def onCreate(self, bundle):
Activity.onCreate(self, bundle)
We use a SurfaceView to display a live preview from the camera. In order to receive updates from the camera, we register the activity to receive callbacks from the preview's SurfaceHolder object.
preview = SurfaceView(self)
self.holder = preview.getHolder()
self.holder.addCallback(self)
#self.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
We use the preview as the main view in the activity.
self.setContentView(preview)
The onResume method is called when the activity starts or when the user navigates to it. After calling the corresponding method in the base class, we try to obtain a Camera object by calling the static open method. If a valid object is returned we obtain the first size supported by the device.
def onResume(self):
Activity.onResume(self)
self.camera = Camera.open()
if self.camera != None:
parameters = self.camera.getParameters()
self.size = parameters.getSupportedPreviewSizes().get(0)
The onPause method is called when the user navigates away from the
activity. After calling the corresponding method in the base class, we
release the Camera object obtained earlier, releasing it so that other
activities can use it, and setting the camera
attribute to None to
indicate that the activity no longer has access to the camera.
def onPause(self):
Activity.onPause(self)
if self.camera != None:
self.camera.release()
self.camera = None
The following three methods must be implemented because they are part of the SurfaceHolder.Callback interface whose methods are abstract.
The surfaceCreated method is used to inform us that a surface has been created to show images from the camera. If we have access to the camera, we tell it to use the SurfaceHolder associated with the SurfaceView object we created earlier.
def surfaceCreated(self, holder):
if self.camera != None:
self.camera.setPreviewDisplay(holder)
The surfaceDestroyed method is used to inform the activity that a surface has been destroyed. If we have access to the camera, we stop the generation of preview images since the activity can no longer display them.
def surfaceDestroyed(self, holder):
if self.camera != None:
self.camera.stopPreview()
The surfaceChanged method is used to inform the activity about changes to the format or size of the surface. We read the current parameters of the camera, update the preview size to match the size provided and start the camera preview.
def surfaceChanged(self, holder, format, width, height):
parameters = self.camera.getParameters()
parameters.setPreviewSize(self.size.width, self.size.height)
self.camera.setParameters(parameters)
self.camera.startPreview()