• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps Camera API error, help?

Hi, I'm new to Android developing. I've started to write an camera application based on the Camera Preview code offered in the Android Developers's Resources site. However, when running the code that I have I get the error "Application Camera Demo (process com.ev.android.camera) has stopped unexpectedly. Please Try again later" and a forced exit.

All I did to the Camera Preview code was to include a button in the screen that will allow users to snap photos when click and of course, the takepicture() function to take a picture.

Here's my code:

Code:
package com.ev.android.camera;

import java.io.IOException;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.FrameLayout;

public class CameraApp extends Activity {
    /** Called when the activity is first created. */
	
	private Preview mPreview;
	private Button buttonSnap;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        //hide window title
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        mPreview = new Preview(this); //pass this as the context
        //add the preview as a FrameLayout object
        ((FrameLayout)findViewById(R.id.preview)).addView(mPreview);
        
        buttonSnap = (Button)findViewById(R.id.buttonSnap);
        
        //Camera will take the picture when the button is pressed.
        buttonSnap.setOnClickListener(new View.OnClickListener(){
        	public void onClick(View v){
        		mPreview.mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
        	}
        });
        
        setContentView(mPreview);
    }
    
    //Called when shutter is open
    ShutterCallback shutterCallback = new ShutterCallback() {
    	public void onShutter() {
    		System.out.println("Taking picture...");
    	}
    };
    
    //Handles data for raw picture
    PictureCallback rawCallback = new PictureCallback(){
    	public void onPictureTaken(byte[] data, Camera camera){
    		
    	}
    };
    
    //Handles data for JPEG picture
    PictureCallback jpegCallback = new PictureCallback(){
    	public void onPictureTaken(byte[] data, Camera camera){
    		
    		// implement data handling here.
    	}
    };
    
    
}


//-------------------Preview Class-------------------------

// Preview class for camera must be created for Camera to start its view

class Preview extends SurfaceView implements SurfaceHolder.Callback{
	//member fields of the class Preview
	
	SurfaceHolder mHolder;
	Camera mCamera;
	
	//class constructor
	Preview(Context context){
		super(context);
		
		mHolder = getHolder();
		mHolder.addCallback(this);	//adds a SurfaceHolder.Callback in the holder.
		mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		
		
	}
	
	public void surfaceCreated(SurfaceHolder holder){
		//surface has been created, camera can be notified to draw on the canvas
		
		mCamera = Camera.open();	// create a camera object
		try{
			mCamera.setPreviewDisplay(holder);	//set the cam's display to as the holder holding the view
		//	mCamera.startPreview();
		} catch (IOException exception){
			mCamera.release();	// destroy the camera object
			mCamera = null;
		}
	}
	
	public void surfaceDestroyed(SurfaceHolder holder){
		mCamera.stopPreview();
		mCamera.release();
		mCamera = null;
	}
	
	 //------------------------------------------------------------------------------
	//optimization function borrowed from Android Developers code: CameraPreview.java
	   private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
	        final double ASPECT_TOLERANCE = 0.05;
	        double targetRatio = (double) w / h;
	        if (sizes == null) return null;

	        Size optimalSize = null;
	        double minDiff = Double.MAX_VALUE;

	        int targetHeight = h;

	        // Try to find an size match aspect ratio and size
	        for (Size size : sizes) {
	            double ratio = (double) size.width / size.height;
	            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
	            if (Math.abs(size.height - targetHeight) < minDiff) {
	                optimalSize = size;
	                minDiff = Math.abs(size.height - targetHeight);
	            }
	        }

	        // Cannot find the one match the aspect ratio, ignore the requirement
	        if (optimalSize == null) {
	            minDiff = Double.MAX_VALUE;
	            for (Size size : sizes) {
	                if (Math.abs(size.height - targetHeight) < minDiff) {
	                    optimalSize = size;
	                    minDiff = Math.abs(size.height - targetHeight);
	                }
	            }
	        }
	        return optimalSize;
	    }
	   
	   
	   //----------------------------------------------------------------------------
			
	   public void surfaceChanged(SurfaceHolder holder, int format, int w, int h){
		   // Now that the size is known, set up the camera parameters and begin
	       // the preview.
	       Camera.Parameters parameters = mCamera.getParameters();

	       List<Size> sizes = parameters.getSupportedPreviewSizes();
	       Size optimalSize = getOptimalPreviewSize(sizes, w, h);
	       parameters.setPreviewSize(optimalSize.width, optimalSize.height);

	        mCamera.setParameters(parameters);
	        mCamera.startPreview();
	    }
}

I've also added the permission in the manifest file:
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.ev.android.camera"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
        <activity android:name=".CameraApp"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    
    <uses-feature android:name="android.hardware.camera" />
	<uses-permission android:name="android.permission.CAMERA" />


</manifest>

This application is written at API level 5, and I'm using an emulator at API level 7 (Motorola Milestone's emulator). I've tried porting the application to the Milestone device itself and the same error appears.

I've read that camera errors could be caused by lack of memory, declaration in the manifest file or the setPreviewSizes() function in the surfaceChanged() method, but I can't pin point what exactly is wrong with my project.

Can someone please help me? >_<
 

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones