Callbacks not working


#1

You know those callbacks that we made
I have placed a number of logs in both of my callbacks
but none of them work
So I am therefore assuming that my callbacks won’t work and I don’t know why :confused:
So I was wondering if maybe someone else has a clue because I am out of ideas

This is my log cat and I would like to draw your attention to the fact that it registers when the photo button
is clicked AND it records the fact that the result was cancelled but the actual callbacks are not logging anything :confused:

Here is the callback code

private Camera.ShutterCallback mShutterCallback= new Camera.ShutterCallback() 
{
	
	@Override
	public void onShutter() 
	{
	Log.d(TAG, "on Shutter");
	mProgressContainer.setVisibility(View.VISIBLE); 
	}
};

private Camera.PictureCallback mJpegCallback=new Camera.PictureCallback() 
{	
	@Override
	public void onPictureTaken(byte[] data, Camera camera) 
	{
	Log.d(TAG, "Picture Taken");
	// Create a filename
	String filename=String.format("%s%s_crime.jpg", mContext.getFilesDir(), UUID.randomUUID().toString());
	//Save the jpeg data to disk
	FileOutputStream os=null;
	boolean success=true;
		try
		{
		os=getActivity().openFileOutput(filename, Context.MODE_PRIVATE);
		os.write(data);
		Log.d(TAG, "Saved file to disk");
		}
		catch(Exception e)
		{
		Log.e(TAG, String.format("Error writing to file %s", filename),e);
		success=false;
		}
		finally
		{
			try
			{
				if(os != null)
				{os.close();}
			}
			catch(Exception eXc)
			{
			Log.e(TAG, String.format("Error closing file %s", filename),eXc);	
			}
		}
		//Return the image
		if(success)
		{
		Log.i(TAG, String.format("Image saved as %s", filename));
		Intent i=new Intent();
		i.putExtra(EXTRA_PHOTO_FILENAME, filename);
		getActivity().setResult(Activity.RESULT_OK,i);
		}
		else
		{getActivity().setResult(Activity.RESULT_CANCELED);}
	mCamera.release();
	}
};

Here is the callback being used

//Take the picture
			takePictureButton.setOnClickListener(new View.OnClickListener() 
			{
		
				@Override
				public void onClick(View v) 
				{
				//Take the picture and get out of here
				mCamera.takePicture(mShutterCallback, null,  mJpegCallback); 
				getActivity().finish();	
				Log.d(TAG,"Photo Button Clicked");
				}
			});

And here is the whole shebang

package com.blackstephen.androidnerdranchapp2criminalintent;

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

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;

public class CrimeCameraFragment extends Fragment 
{
private static final String TAG="CrimeCameraFragment";
private Camera mCamera;
private SurfaceView mSurfaceView;
private FrameLayout mProgressContainer;
public static final String EXTRA_PHOTO_FILENAME="crimeCameraFragment.filename";
private Context mContext= getActivity();

private Camera.ShutterCallback mShutterCallback= new Camera.ShutterCallback() 
{
	
	@Override
	public void onShutter() 
	{
	Log.d(TAG, "on Shutter");
	mProgressContainer.setVisibility(View.VISIBLE); 
	}
};

private Camera.PictureCallback mJpegCallback=new Camera.PictureCallback() 
{	
	@Override
	public void onPictureTaken(byte[] data, Camera camera) 
	{
	Log.d(TAG, "Picture Taken");
	// Create a filename
	String filename=String.format("%s%s_crime.jpg", mContext.getFilesDir(), UUID.randomUUID().toString());
	//Save the jpeg data to disk
	FileOutputStream os=null;
	boolean success=true;
		try
		{
		os=getActivity().openFileOutput(filename, Context.MODE_PRIVATE);
		os.write(data);
		Log.d(TAG, "Saved file to disk");
		}
		catch(Exception e)
		{
		Log.e(TAG, String.format("Error writing to file %s", filename),e);
		success=false;
		}
		finally
		{
			try
			{
				if(os != null)
				{os.close();}
			}
			catch(Exception eXc)
			{
			Log.e(TAG, String.format("Error closing file %s", filename),eXc);	
			}
		}
		//Return the image
		if(success)
		{
		Log.i(TAG, String.format("Image saved as %s", filename));
		Intent i=new Intent();
		i.putExtra(EXTRA_PHOTO_FILENAME, filename);
		getActivity().setResult(Activity.RESULT_OK,i);
		}
		else
		{getActivity().setResult(Activity.RESULT_CANCELED);}
	mCamera.release();
	}
};

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
	{
	//Inflate the view
	View v=inflater.inflate(R.layout.fragment_crime_camera, parent, false);
	//Make the button to take the picture
	Button takePictureButton =(Button) v.findViewById(R.id.btn_crime_camera_takePictureButton);
	//set the viewfinder progress bar to invisible
	mProgressContainer=(FrameLayout) v.findViewById(R.id.crime_camera_progress_container);
	mProgressContainer.setVisibility(View.INVISIBLE);	
			//Take the picture
			takePictureButton.setOnClickListener(new View.OnClickListener() 
			{
		
				@Override
				public void onClick(View v) 
				{
				//Take the picture and get out of here
				mCamera.takePicture(mShutterCallback, null,  mJpegCallback); 
				getActivity().finish();	
				Log.d(TAG,"Photo Button Clicked");
				}
			});
		
	
	//Create the much needed surface view
	mSurfaceView=(SurfaceView) v.findViewById(R.id.crime_camera_surfaceView);
	SurfaceHolder holder=mSurfaceView.getHolder();
	//setType() and SURFACE_TYPE_PUSH_BUFFERS are both depreciated
	//but are required for camera preview to work on pre 3.0 devices
	holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	//add a hook callback for the holder
	holder.addCallback(new SurfaceHolder.Callback() {
		
		@Override
		public void surfaceDestroyed(SurfaceHolder holder)
		{
		//We can no longer display on this surface so stop the preview
			if(mCamera != null)
			{mCamera.takePicture(mShutterCallback,null, mJpegCallback);}
		}
		
		@Override
		public void surfaceCreated(SurfaceHolder holder) 
		{
			try
			{
				if(mCamera !=null)
				{
					mCamera.setPreviewDisplay(holder);
				}
			}
			catch(IOException iOx)
			{Log.e(TAG,"Error setting up preview display",iOx);}
		}
		
		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
		{
			//The surface has changed size: update the camera preview size
		Camera.Parameters parameters=mCamera.getParameters();
			Size s= getBestSupportedSize(parameters.getSupportedPreviewSizes(),width ,height);
			{
			parameters.setPreviewSize(s.width, s.height);
			s=getBestSupportedSize(parameters.getSupportedPictureSizes(),width,height);
			parameters.setPictureSize(s.width, s.height);
			mCamera.setParameters(parameters);
				try
				{mCamera.startPreview();	}
				catch (Exception eX)
				{
				Log.e(TAG, "Could not start preview", eX);
				//mCamera.release();
				mCamera=null;
				}
			}
		}
	});	
	return v;
	}
	
	/**A simple algorithm to get the largest size available.
	 * for a more robust version see CameraPreview.java in the ApiDemos
	 * sample app from Android.*/
	private Size getBestSupportedSize(List<Size> sizes, int width, int height)
	{
	Size bestSize=sizes.get(0);
	int largestArea=bestSize.width * bestSize.height;
		for(Size s: sizes)
		{
		int area= s.width * s.height;
			if(area > largestArea)
			{
			bestSize =s;
			largestArea= area;
			}
		}
	return bestSize;
	}

	@TargetApi(9)
	@Override
	public void onResume()
	{
	super.onResume();
	//We need a camera
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
		{mCamera=Camera.open(0);}
		else
		{mCamera=Camera.open();}
	}
	
	@Override
	public void onPause()
	{
	super.onPause();
	//Never assume that the camera is valid it may be in use by other apps
		//Release the camera
		if(mCamera != null)
		{
		mCamera.release();
		mCamera=null;
		}
	}

}

Thanks in advance for your help


#2

The Logcat message: “The result was canceled” looks suspicious. Curious why you have a call to finish on the containing Activity in the onClick() handler for the take picture button event. Seems this is what may be causing things to stop abruptly.


#3

Thanks for the help, I got it working now after tying up a few more loose ends :smiley:
Actually the call to finish was a hangover from the previous camera chapter because we made a viewfinder and we used the call to finish so that we
could close the viewfinder by clicking on the take picture button.
but I didn’t delete it when I was meant to
The problem it caused was to delete the activity and therefore stopped the camera from taking a picture

actually if I am not mistaken I think I read somewhere in the official documentation that it is recommended to start the camera in
a separate thread

and I can see why