5

I'm trying to get the picture into service from Camera.

@Override
public void onCreate() {
    super.onCreate();
    //android.os.Debug.waitForDebugger();

    myCamera=Camera.open();


      SurfaceView dummy=new SurfaceView(getApplicationContext());
    try {
        if(myCamera!=null)
        {
            myCamera.setPreviewDisplay(dummy.getHolder());
            myCamera.setPreviewCallback(this);
            Log.i(TAG,"myCamera is not null");
        }
            getFrames();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        Log.e(TAG, "setPreviewDisplay " + e);
    }    
    myCamera.startPreview(); 
}


    public void getFrames() {

        new Thread(new Runnable() {

            public void run() {

                    while(flag)
                    {
                        Log.i(TAG, "getFrames");
                        try{

                            //method();
                        takePictureNoPreview();
                        Thread.sleep(54);

                        } catch (Exception e) {
                            Log.e(TAG, "getFrames thread error: " + e);
                        }
                    }
                     myCamera.release();  

            }
        }).start();
    }


public void takePictureNoPreview(){
            try{
              Log.i(TAG,"takePictureNoPreview");
              myCamera.takePicture(null, null, getJpegCallback())
            } catch (Exception e) {
                Log.e(TAG, "takePictureNoPreview " + e);
            }


     private PictureCallback getJpegCallback(){
                PictureCallback jpeg=new PictureCallback() {   
                  @Override
                  public void onPictureTaken(byte[] data, Camera camera) {
                    try {
                      Log.i(TAG,"getJpegCallback");
                      FileOutputStream(String.format("/sdcard/RealSpeaker/%d.jpg", System.currentTimeMillis()));
                      FileOutputStream os = new FileOutputStream(String.format("/sdcard/Sample/%d.jpg", System.currentTimeMillis()));
                         os.write(data);
                         os.close();
                    }  catch (IOException e) {
                      //do something about it
                    }
                  }
                };
                return jpeg;

              }

The problem is that the method getJpegCallback around is incorrect: (no logs and images in a folder)ю When i'm debugging application, TAG - getJpegCallback do not show in LogCat, but TAG takePictureNoPreview shows. And after closing application, Camera dont allow(now it's no problem). What's wrong?

mmBs
  • 8,421
  • 6
  • 38
  • 46
user1755546
  • 1,049
  • 2
  • 13
  • 27
  • 1
    What I've experienced is that I needed an actual SurfaceView within the layout to take a picture, so I've added a SurfaceView with height=20dp and marginTop=-100dp or something to "move it out of sight" but it still being existent in the layout. Maybe you should try something like this. Another idea is: Shouldn't you call setPreviewDisplay and startPreview in the surfaceCreated/Changed method of the callback? – damian Sep 05 '13 at 11:29
  • Ok. i'm try first variant – user1755546 Sep 05 '13 at 11:33
  • Are you trying to record video in background – Auto-Droid ツ Sep 05 '13 at 11:35

6 Answers6

3

I faced this issue when developing EyeSpy. I wanted to capture images even app is in background or foreground. I tried for some weeks but no luck. Capturing photo using camera means displaying its preview.

From Document(5. and 6.) And you have to use SurfaceView to display preview.

When you close app or your app goes into background the surface of SurfaceView will be destroyed. That is why I think it's not possible.

If you found any other way then please post here.

Hope this help you..

Ketan Ahir
  • 6,678
  • 1
  • 23
  • 45
  • Did you try something like this? -> -> display custom "alert window" with no content but a surfaceview (invisible or somewhere off-screen), using this one as preview display? -> http://stackoverflow.com/questions/7678356/launch-popup-window-from-service – damian Sep 05 '13 at 11:37
  • @damian Thanks for letting me know..I tried it today morning and it worked...I will give it a try for my app. – Ketan Ahir Sep 07 '13 at 04:30
  • Any chance you could expand on the code to complete this? I have the "test test test" language popping up, but cannot get the camera to run without FCing. – Fmstrat Jan 12 '14 at 15:55
3

From API 11 on, instead of using the SurfaceHolder of your SurfaceView, you can use a SurfaceTexture. Then, you set it up using Camera.setPreviewTexture instead of Camera.setPreviewDisplay.

It worked fine for me in a service on different devices.

This answer as well as this one discuss this point.

Community
  • 1
  • 1
JonasVautherin
  • 7,297
  • 6
  • 49
  • 95
0
public class TakePicture 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;
    FileOutputStream fo;

    // Camera variables
    // a surface holder
    private SurfaceHolder sHolder;
    // a variable to control the camera
    private Camera mCamera;
    // the camera parameters
    private Parameters parameters;
    private String FLASH_MODE;
    private boolean isFrontCamRequest = false;
    private Camera.Size pictureSize;

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

        // check if this device has a camera
        if (checkCameraHardware(getApplicationContext())) 
        {
            // 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
            Bundle extras = getIntent().getExtras();
            String flash_mode = extras.getString("FLASH");
            FLASH_MODE = flash_mode;
            boolean front_cam_req = extras.getBoolean("Front_Request");
            isFrontCamRequest = true;


            System.out.println("front_cam_req :"+front_cam_req);
            sv = (SurfaceView) findViewById(R.id.camera_preview);

            // 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
            if (Build.VERSION.SDK_INT < 11)
                sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        }
        else {
            // display in long period of time
            Toast.makeText(getApplicationContext(),
                    "Your Device dosen't have a Camera !", Toast.LENGTH_LONG)
                    .show();
        }

    }

    /** Check if this device has a camera */
    private boolean checkCameraHardware(Context context) {
        if (context.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA)) {
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }
    }

    /** Check if this device has front camera */
    private boolean checkFrontCamera(Context context) 
    {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) 
        {
            // this device has front camera
            return true;
        } 
        else
        {
            // no front camera on this device
            return false;
        }
    }

    public static Camera getCameraInstance()
    {
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        } catch (Exception e) {
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        // get camera parameters
        if (mCamera != null) {
            parameters = mCamera.getParameters();
            if (FLASH_MODE == null || FLASH_MODE.isEmpty()) {
                FLASH_MODE = "auto";
            }
            parameters.setFlashMode(FLASH_MODE);
            pictureSize = getBiggesttPictureSize(parameters);
            if (pictureSize != null)
                parameters
                        .setPictureSize(pictureSize.width, pictureSize.height);
            // 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() {
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    // decode the data obtained by the camera into a Bitmap
                    Log.d("ImageTakin", "Done");

                    bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
                    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                    if (bmp != null)
                        bmp.compress(Bitmap.CompressFormat.JPEG, 100, bytes);

                    File imagesFolder = new File(
                            Environment.getExternalStorageDirectory(),
                            "OneSheeld");
                    if (!imagesFolder.exists())
                        imagesFolder.mkdirs(); // <----
                    File image = new File(imagesFolder,
                            System.currentTimeMillis() + ".jpg");

                    // write the bytes in file
                    try {
                        fo = new FileOutputStream(image);
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                    }
                    try {
                        fo.write(bytes.toByteArray());
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                    }

                    // remember close de FileOutput
                    try {
                        fo.close();
                        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
                                Uri.parse("file://"
                                        + Environment
                                                .getExternalStorageDirectory())));

                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                    }
                    if (mCamera != null) {
                        mCamera.stopPreview();
                        // release the camera
                        mCamera.release();
                    }
                    Toast.makeText(getApplicationContext(),
                            "Your Picture has been taken !", Toast.LENGTH_LONG)
                            .show();
                    if (bmp != null) {
                        bmp.recycle();
                        bmp = null;
                        System.gc();
                    }
                    TakePicture.this.finish();

                }
            };

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

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

            //Toast.makeText(getApplicationContext()," isFrontCamRequest()",Toast.LENGTH_LONG).show();

            System.out.println("isFrontCamRequest 1");
            // set flash 0ff
            FLASH_MODE = "off";
            // only for gingerbread and newer versions
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD)
            {
                System.out.println("isFrontCamRequest 2");
                mCamera = openFrontFacingCameraGingerbread();
                try {
                    mCamera.setPreviewDisplay(holder);

                } catch (IOException exception) {
                    mCamera = null;
                    Toast.makeText(getApplicationContext(),"API dosen't support front camera",Toast.LENGTH_LONG).show();
                    TakePicture.this.finish();
                }
            }
            else 
            {
                System.out.println("isFrontCamRequest 3");
                if (checkFrontCamera(getApplicationContext()))
                {
                    mCamera = openFrontFacingCameraGingerbread();
                    try
                    {
                        mCamera.setPreviewDisplay(holder);

                    }
                    catch (IOException exception)
                    {
                        mCamera = null;
                        Toast.makeText(getApplicationContext(),
                                "API dosen't support front camera",
                                Toast.LENGTH_LONG).show();
                        TakePicture.this.finish();
                    }
                }/*
                 * else { // API dosen't support front camera or no front camera
                 * Log.d("Camera",
                 * "API dosen't support front camera or no front camera");
                 * Toast.makeText( getApplicationContext(),
                 * "API dosen't support front camera or no front camera",
                 * Toast.LENGTH_LONG).show();
                 * 
                 * finish(); }
                 */

            }
        } 
        else
        {
            System.out.println("isFrontCamRequest 4");
            mCamera = getCameraInstance();
            try
            {
                mCamera.setPreviewDisplay(holder);

            } 
            catch (Exception exception) {
                mCamera = null;
            }
        }

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // stop the preview
        /*
         * mCamera.stopPreview(); // release the camera mCamera.release();
         */
        // unbind the camera from this object
        mCamera = null;
    }

    private Camera openFrontFacingCameraGingerbread() {
        int cameraCount = 0;
        Camera cam = null;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        cameraCount = Camera.getNumberOfCameras();
        for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
            Camera.getCameraInfo(camIdx, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                try {
                    cam = Camera.open(camIdx);
                } catch (RuntimeException e) {
                    Log.e("Camera",
                            "Camera failed to open: " + e.getLocalizedMessage());
                    Toast.makeText(getApplicationContext(),
                            "Front Camera failed to open", Toast.LENGTH_LONG)
                            .show();
                }
            }
        }
        return cam;
    }

    @Override
    protected void onDestroy() {
        Intent intent = new Intent("custom-event-name");
        // You can also include some extra data.
        intent.putExtra("message", "This is my message!");
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

        super.onDestroy();
    }

    private Camera.Size getBiggesttPictureSize(Camera.Parameters parameters) {
        Camera.Size result = null;

        for (Camera.Size size : parameters.getSupportedPictureSizes()) {
            if (result == null) {
                result = size;
            } else {
                int resultArea = result.width * result.height;
                int newArea = size.width * size.height;

                if (newArea > resultArea) {
                    result = size;
                }
            }
        }

        return (result);
    }
}
0

It seems the solution is late but still..Actually we can have a UI from a service by usgin WindowManager in onCreate() and inflating a layout..and setVisibility(View.INVISIBLE)

@Override public void onCreate() {
        super.onCreate();
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        recording = false;
        myview = inflater.inflate(R.layout.service_layout, null);
        layout = (FrameLayout) myview.findViewById(R.id.preview);
        minimize = (ImageButton) myview.findViewById(R.id.minimize);
        minimize.setVisibility(ImageButton.GONE);
        start = (Button) myview.findViewById(R.id.record);
        start.setVisibility(Button.GONE);
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!recording) {
                    if (prepareMediaRecorder()) {
                        try {
                            mediaRecorder.start();
                            Log.e("Camera------>", "working after");
                            recording = true;
                            start.setText("STOP");
                            handler.post(sendUpdates);
                        }catch (Exception e){
                            Log.getStackTraceString(e);
                        }
                    }
                }else{
                    mediaRecorder.stop(); // stop the recording
                    releaseMediaRecorder();
                    recording = false;
                    Log.e("Camera1------>", "working");
                    start.setText("START");
                    handler.post(sendUpdates);
                }

            }
        });

you can also refer to a sample app https://github.com/gauravbspr/Research-Projects/tree/master/Camera%20Service and also contribute if seem neccesary

0

Don't know if this is late but for anyone who is still searching please try thisAndroid Background Camera https://github.com/YoboZorle/Android-Background-Camera

yobo zorle
  • 348
  • 3
  • 8
-1

You can try this

Intent translucent = new Intent(getApplication(),
                                TakePicture.class);
                        translucent.putExtra("FLASH", "on");
                        startActivity(translucent); 
                      Toast.makeText(getApplicationContext(), "Started Capture", 500).show();




 <SurfaceView
    android:id="@+id/camera_preview"
    android:layout_width="1dp"
    android:layout_height="1dp" />

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <uses-permission android:name="android.permission.RECORD_VIDEO"/>


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

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />



    <uses-feature android:name="android.hardware.camera.front" android:required="false" />

JUST DO THIS ITS WORKING FOR ME. Hope it helps.

Koekiebox
  • 5,793
  • 14
  • 53
  • 88