Camera Example

This example shows how to access the camera on a device and display its output in a view.

A screenshot of the application.

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()

Files