Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScheduledExecutorService run only once inside Service

I am running ScheduledExecutorService inside of my service which takes image in background. ScheduledExecutorService running only once means taking only one picture after the interval passed in function. Showing no errors at all. Following is the code of my Service

package com.anawaz.spy;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import android.app.Service;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.IBinder;
import android.util.Log;

public class CamService extends Service {

    private static final String TAG = "TAG";

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    Camera camera;
    ScheduledFuture beeperHandle;

    /* Service Life cycle Overrides */
    @Override
    public void onCreate() {
        super.onCreate();
        camera = Camera.open();
        try {
            camera.setPreviewDisplay(null);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //takePicsPeriodically(MainActivity.getSpInt(MainActivity.SP_Period));
        takePicsPeriodically(5);
    }

    @Override
    public void onDestroy() {
        stopPics();
        super.onDestroy();
    }

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

    // @Override
    // public IBinder onBind(Intent arg0) {
    // return myRemoteServiceStub;
    // }
    // /* ----------------------------------- */
    //
    // private IMyRemoteService.Stub myRemoteServiceStub = new
    // IMyRemoteService.Stub() {
    //
    // /* Basic Service Methods */
    // public boolean isCollecting() {
    // return (beeperHandle != null);
    // }
    // /* ------------------------- */
    // };

    public void takePicsPeriodically(long period) {
        final Runnable beeper = new Runnable() {
            public void run() {
                Log.d("TAG", "New Picture Taken");
                camera.takePicture(shutterCallback, rawCallback, jpegCallback);
            }
        };
        camera.startPreview();
        beeperHandle = scheduler.scheduleAtFixedRate(beeper, period, period,TimeUnit.SECONDS);
    }

    public void stopPics() {
        beeperHandle.cancel(true);
        beeperHandle = null;
        camera.stopPreview();
        camera.release();
        camera = null;
    }

    /* Camera Call backs */
    ShutterCallback shutterCallback = new ShutterCallback() {
        public void onShutter() {
            Log.d(TAG, "onShutter'd");
        }
    };

    /** Handles data for raw picture */
    PictureCallback rawCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            Log.d(TAG, "onPictureTaken - raw");
        }
    };

    /** Handles data for j peg picture */
    PictureCallback jpegCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            FileOutputStream outStream = null;
            try {
                // write to local sand box file system
                // outStream =
                // CameraDemo.this.openFileOutput(String.format("%d.jpg",
                // System.currentTimeMillis()), 0);
                // Or write to s d card
                File mFolder;
                mFolder = new File("/sdcard/Spy/");
                if (!mFolder.exists()) {
                    mFolder.mkdir();
                }
                outStream = new FileOutputStream(String.format(
                        "/sdcard/Spy/Image_%d.jpg", System.currentTimeMillis()));
                outStream.write(data);
                outStream.close();
                Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
            Log.d(TAG, "onPictureTaken - jpeg");
        }
    };

}

No Logcat because not getting any error. Service is also running after taking picture. What I am doing wrong?

like image 446
Ahmed Nawaz Avatar asked Jun 21 '14 13:06

Ahmed Nawaz


1 Answers

After Reading this post http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/ I tried try catch block. And Found that camera.takePicture(shutterCallback, rawCallback, jpegCallback); was throwing exception. Which was because of my mistake That I was not starting preview after taking first picture. Refer to this answer. https://stackoverflow.com/a/21728454/1770916

Following is the Updated Working code of my service.

package com.anawaz.spy;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import android.app.Service;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.IBinder;
import android.util.Log;

public class CamService extends Service {

    private static final String TAG = "TAG";

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    Camera camera;
    ScheduledFuture beeperHandle;

    /* Service Life cycle Overrides */
    @Override
    public void onCreate() {
        super.onCreate();
        camera = Camera.open();
        try {
            camera.setPreviewDisplay(null);
        } catch (IOException e) {
            e.printStackTrace();
        }
        File mFolder = new File("/sdcard/Spy/");
        if (!mFolder.exists()) {
            mFolder.mkdir();
        }
        takePicsPeriodically(MainActivity.getSpInt(MainActivity.SP_Period));
        //takePicsPeriodically(5);
    }

    @Override
    public void onDestroy() {
        stopPics();
        super.onDestroy();
    }

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

    public void takePicsPeriodically(long period) {
        camera.startPreview();
        beeperHandle = scheduler.scheduleAtFixedRate(beeper,period, period,TimeUnit.SECONDS);
    }

    final Runnable beeper = new Runnable() {
        public void run() {
            Log.d("TAG", "New Picture Taken");
            try {
                camera.startPreview();
                camera.takePicture(shutterCallback, rawCallback, jpegCallback);
            }catch (Exception e) {
                Log.e("TAG","error in executing: It will no longer be run!: "+e.getMessage());
                e.printStackTrace();
            }
        }
    };
    public void stopPics() {
        beeperHandle.cancel(true);
        beeperHandle = null;
        camera.stopPreview();
        camera.release();
        camera = null;
    }

    /* Camera Call backs */
    final ShutterCallback shutterCallback = new ShutterCallback() {
        public void onShutter() {
            Log.d(TAG, "onShutter'd");
        }
    };

    /** Handles data for raw picture */
    final PictureCallback rawCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            Log.d(TAG, "onPictureTaken - raw");
        }
    };

    /** Handles data for j peg picture */
    final PictureCallback jpegCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            FileOutputStream outStream = null;
            try {
                // write to local sand box file system
                // outStream =
                // CameraDemo.this.openFileOutput(String.format("%d.jpg",
                // System.currentTimeMillis()), 0);
                // Or write to s d card

                outStream = new FileOutputStream(String.format(
                        "/sdcard/Spy/Image_%d.jpg", System.currentTimeMillis()));
                outStream.write(data);
                outStream.close();
                Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
            Log.d(TAG, "onPictureTaken - jpeg");
        }
    };

}
like image 76
Ahmed Nawaz Avatar answered Nov 06 '22 07:11

Ahmed Nawaz