0

I have this activity (MakePhotoActivity) class that takes photo when you open the application. I have set it to use front facing camera.

Then I have another class, which is a SMS broadcast receiver that is already working.

Now, I would like to make it such that on receiving sms, I want it to take photo using the current class I have. But how can I integrate them together?

As I have tried copying the methods (surfaceChanged, etc) to my broadcast receiver class, and on sms receive, I placed the code that is inside the onCreate (in MakePhotoActivity). And it is not working.

public class MakePhotoActivity extends Activity implements SurfaceHolder.Callback
{
    //a variable to store a reference to the Image View at the main.xml file
    private ImageView iv_image;
    //a variable to store a reference to the Surface View at the main.xml file
    private SurfaceView sv;

    //a bitmap to display the captured image
    private Bitmap bmp;
    private int cameraId = 0;

    //Camera variables
    //a surface holder
    private SurfaceHolder sHolder; 
    //a variable to control the camera
    private Camera mCamera;
    //the camera parameters
    private Parameters parameters;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        //get the Image View at the main.xml file
        iv_image = (ImageView) findViewById(R.id.imageView);

        //get the Surface View at the main.xml file
        sv = (SurfaceView) findViewById(R.id.surfaceView);

        //Get a surface
        sHolder = sv.getHolder();

        //add the callback interface methods defined below as the Surface   View callbacks
        sHolder.addCallback(this);

        //tells Android that this surface will have its data constantly replaced
        sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    private int findFrontFacingCamera() {
        int cameraId = -1;
        // Search for the front facing camera
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                Log.d("A", "Camera found");

                cameraId = i;
                break;
            }
        }
        return cameraId;
    }

    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
    {
        //get camera parameters
        parameters = mCamera.getParameters();

        //set camera parameters
        mCamera.setParameters(parameters);
        mCamera.startPreview();

        //sets what code should be executed after the picture is taken
        Camera.PictureCallback mCall = new Camera.PictureCallback()
        {

            public void onPictureTaken(byte[] data, Camera camera)
            {
                //decode the data obtained by the camera into a Bitmap
                bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
                //set the iv_image
                iv_image.setImageBitmap(bmp);
                FileOutputStream outStream = null;
                try{
                    outStream = new FileOutputStream("/sdcard/Image"+System.currentTimeMillis()+".jpg");
                    outStream.write(data);
                    outStream.close();
                } catch (FileNotFoundException e){
                    Log.d("CAMERA", e.getMessage());
                } catch (IOException e){
                    Log.d("CAMERA", e.getMessage());
                }
            }
        };

        mCamera.takePicture(null, null, mCall);
    }


    public void surfaceCreated(SurfaceHolder holder)
    {
        // The Surface has been created, acquire the camera and tell it where
        // to draw the preview.

        if (mCamera == null) {
            cameraId = findFrontFacingCamera();
            mCamera = Camera.open(cameraId);
            try {
                mCamera.setPreviewDisplay(holder);

                // TODO test how much setPreviewCallbackWithBuffer is faster
                // mCamera.setPreviewCallback((PreviewCallback) this);
            } catch (IOException e) {
                mCamera.release();
                mCamera = null;
            }
        }
    }


    public void surfaceDestroyed(SurfaceHolder holder)
    {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera = null;
        }
    } 

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        if (mCamera!=null)
        {
            mCamera.stopPreview();
            mCamera.release();
            mCamera=null;
        }
    }
}

UPDATE: This is what I have done. Put into a service, but I get an error that says app passed NULL surface, Camera server died!, ICamera died, Error 100.

I reference the code from http://easyandroidtutorials.blogspot.in/2012/09/capture-image-without-preview-as.html and made some minor changes, still can't work.

public class CameraService extends Service
{
    //Camera variables
    //a surface holder
    private SurfaceHolder sHolder; 
    //a variable to control the camera
    private Camera mCamera;
    //the camera parameters
    private Parameters parameters;
    SurfaceView sv;
    private int cameraId = 0;
    /** Called when the activity is first created. */
    @Override
    public void onCreate()
    {
        super.onCreate();
        Log.i("Service", "Service started");




    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try {


                if (mCamera == null) {
                    cameraId = findFrontFacingCamera();
                    mCamera = Camera.open(cameraId);

                try {
                    // Thread.sleep(3000);
                    sv = new SurfaceView(getApplicationContext());
                    mCamera.setPreviewDisplay(sv.getHolder());
                    parameters = mCamera.getParameters();

                    //set camera parameters
                    mCamera.setParameters(parameters);
                    mCamera.startPreview();
                    mCamera.takePicture(null, null, mCall);

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    mCamera.release();
                    mCamera = null;
                    e.printStackTrace();
                }


                //Get a surface
                //sHolder = sv.getHolder();
                //tells Android that this surface will have its data constantly replaced
                // sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return Service.START_STICKY;
    }

    private int findFrontFacingCamera() {
        int cameraId = -1;
        // Search for the front facing camera
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                Log.d("A", "Camera found");

                cameraId = i;
                break;
            }
        }
        return cameraId;
    }

    Camera.PictureCallback mCall = new Camera.PictureCallback()
    {

        public void onPictureTaken(byte[] data, Camera camera)
        {
            //decode the data obtained by the camera into a Bitmap

            FileOutputStream outStream = null;
            try{
                outStream = new FileOutputStream("/sdcard/Image.jpg");
                outStream.write(data);
                outStream.close();
            } catch (FileNotFoundException e){
                Log.d("CAMERA", e.getMessage());
            } catch (IOException e){
                Log.d("CAMERA", e.getMessage());
            }

        }
    };


    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

Anyone with any help on this? Thanks.

user1778855
  • 659
  • 1
  • 11
  • 29
  • Have you read the [BroadcastReceiver documentation](http://developer.android.com/reference/android/content/BroadcastReceiver.html) and [Intent and intent filters](http://developer.android.com/guide/components/intents-filters.html) both from Android official documentation? – Nahuel Barrios Apr 24 '13 at 18:38
  • Hi, I'm not trying to start the activity on sms receive. rather, I'm trying make it take photo automatically on sms receive without the activity class. – user1778855 Apr 24 '13 at 18:40
  • Oh sorry, now I understand. Now, if I'm not wrong the theory says that you should run a [service](http://developer.android.com/guide/components/services.html) to do so, but I don't know why your code is failing. Which error is being throwing? – Nahuel Barrios Apr 24 '13 at 18:53
  • I have updated my post on the error, and the service class I have created. – user1778855 Apr 24 '13 at 18:58

1 Answers1

0

in the onReceive method of your sms broadcast reciever do this:

Intent intent = new Intent(this, MakePhotoActivity.class);
startActivity(intent);

check http://developer.android.com/training/basics/firstapp/starting-activity.html for more info on starting an activities

to take the picture in the service would require you to create a dummy surfaceview. Here's a link that should explain how to do it: how to take camera capture without a preview from a service or thread?

if you want to disable the shutter sound: camera.enableShutterSound(false); http://developer.android.com/reference/android/hardware/Camera.html#enableShutterSound(boolean)

Community
  • 1
  • 1
Nicolas Brown
  • 1,546
  • 1
  • 10
  • 17
  • Hi, I may have forgot to mention that the activity class should not be open. Meaning to say that the photo will be taking without any interaction as in once sms receive, it will take the photo. Can I make use of the existing codes in the activity and place inside the broadcast receiver? – user1778855 Apr 24 '13 at 18:30
  • i've never captured an image from an SMSBroadcastReciever before, but it should work. If it doesnt, try creating a service or a transarent activity that would do the image capturing – Nicolas Brown Apr 24 '13 at 18:49
  • I have tried creating a dummy surface view, but it doesn't work, gave me some error. See my updated post. – user1778855 Apr 24 '13 at 18:59
  • that's what I did initially, but it doesn't work as well. Gave me the Error 100 (Camera died). any other way? – user1778855 Apr 25 '13 at 09:31
  • hmmm...here's the solution to that: http://stackoverflow.com/questions/9930633/android-camera-server-died-and-camera-error-100 – Nicolas Brown Apr 29 '13 at 02:50
  • this as well: http://stackoverflow.com/questions/8647628/android-camera-server-died-and-camera-error-100 – Nicolas Brown Apr 29 '13 at 02:50