Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android take photo on unlock secretly

I am trying to build an app which captures a photo everytime the phone is unlocked. The user should not see that a photo has been taken. So it should basically behave like an anti-theft app.

I have read that I should use a dummy SurfaceTexture, so the preview is not shown on the screen, but I am not able to capture a photo.

Here is what I have written so far. It is just a sample activity to get in touch with the Camera object:

package com.brushmate.chameleon;

import java.io.IOException;

import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.SystemClock;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.util.Log;
import android.view.SurfaceView;

public class SettingsActivity extends Activity {
    private static final String TAG = "Chameleon Wallpaper";

    @SuppressLint("NewApi") protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);

        Log.d(TAG, "Activity created");

        Camera cam = getCamera();

        if (cam != null) {
            Log.d(TAG, "Camera available");

            SurfaceTexture dummy = new SurfaceTexture(0);

            try {
            cam.setPreviewTexture(dummy);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            Log.d(TAG, "Preview texture set");

            cam.startPreview();

            Log.d(TAG, "Preview started");

            cam.takePicture(null, null, new Camera.PictureCallback() {

                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    Log.d(TAG, "Image taken");
                }
            });

            cam.stopPreview();

            Log.d(TAG, "Preview stopped");

            cam.release();

            Log.d(TAG, "Camera released");
        }
    }

    private Camera getCamera() {
        Camera cam = null;

        try {
            cam = Camera.open();
        } catch (RuntimeException e) {
            Log.e(TAG, "Camera not available", e);
        }

        return cam;
    }

}

And here is my Logcat output:

05-12 23:54:56.947: D/Chameleon Wallpaper(19614): Activity created
05-12 23:54:56.947: I/AwesomePlayer(161): setDataSource_l(URL suppressed)
05-12 23:54:56.977: I/AwesomePlayer(161): setDataSource_l(URL suppressed)
05-12 23:54:57.007: I/CameraClient(161): Opening camera 0
05-12 23:54:57.117: E/mm-camera(175): sensor_load_chromatix: libchromatix_imx111_preview.so: 30
05-12 23:54:57.217: E/mm-camera(175): vfe_ops_init: E
05-12 23:54:57.237: E/mm-camera(175): vfe_legacy_stats_buffer_init: AEC_STATS_BUFNUM
05-12 23:54:57.237: E/mm-camera(175): vfe_legacy_stats_buffer_init: AEC_STATS_BUFNUM
05-12 23:54:57.247: E/mm-camera(175): mctl_init_stats_proc_info: snap_max_line_cnt =30096
05-12 23:54:57.267: D/Chameleon Wallpaper(19614): Camera available
05-12 23:54:57.267: D/Chameleon Wallpaper(19614): Preview texture set
05-12 23:54:57.267: E/QCameraHWI(161): android::status_t android::QCameraHardwareInterface::setPreviewWindow(preview_stream_ops_t*): mPreviewWindow = 0x0x400b9e98, mStreamDisplay = 0x0x4008c378
05-12 23:54:57.267: D/QCameraHWI(161): android::status_t android::QCameraHardwareInterface::startPreview():  start preview now
05-12 23:54:57.267: I/QCameraHWI(161): android::status_t android::QCameraHardwareInterface::startPreview2():Setting ZSL mode
05-12 23:54:57.267: E/mm-camera(175): config_proc_CAMERA_SET_INFORM_STARTPREVIEW
05-12 23:54:57.267: E/mm-camera(175): config_update_stream_info Storing stream parameters for video inst 1 as : width = 640, height 480, format = 1 inst_handle = 810081 cid = 0
05-12 23:54:57.307: E/mm-camera(175): config_update_stream_info Storing stream parameters for video inst 3 as : width = 640, height 480, format = 1 inst_handle = 830083 cid = 0
05-12 23:54:57.307: E/mm-camera(175): config_update_stream_info Storing stream parameters for video inst 4 as : width = 512, height 384, format = 1 inst_handle = 840084 cid = 0
05-12 23:54:57.307: E/mm-camera(175): config_decide_vfe_outputs: Ports Used 3, Op mode 1
05-12 23:54:57.307: E/mm-camera(175): config_decide_vfe_outputs Current mode 0 Full size streaming : Disabled
05-12 23:54:57.307: E/mm-camera(175): config_decide_vfe_outputs: Primary: 640x480, extra_pad: 0x0, Fmt: 1, Type: 1, Path: 1
05-12 23:54:57.307: E/mm-camera(175): config_decide_vfe_outputs: Secondary: 640x480, extra_pad: 0x0, Fmt: 1, Type: 3, Path: 4
05-12 23:54:57.307: E/mm-camera(175): config_update_inst_handles Updated the inst handles as 810081, 830083, 0, 0 
05-12 23:54:57.387: W/ActivityManager(592): Activity pause timeout for ActivityRecord{420bd848 u0 com.brushmate.chameleon/.SettingsActivity}
05-12 23:54:57.447: E/mm-camera(175): sensor_load_chromatix: libchromatix_imx111_zsl.so: 26
05-12 23:54:57.537: E/mm-camera(175): camif_client_set_params: camif has associated with obj mask 0x1
05-12 23:54:57.537: E/mm-camera(175): config_v2_CAMERA_START_common CAMIF_PARAMS_ADD_OBJ_ID failed -1 
05-12 23:54:57.537: E/mm-camera(175): vfe_operation_config: format 3
05-12 23:54:57.537: E/mm-camera(175): vfe_operation_config:vfe_op_mode=5
05-12 23:54:57.537: E/mm-camera(175): Invalid ASD Set Params Type
05-12 23:54:57.537: E/mm-camera(175): vfe_set_bestshot: Bestshot mode not changed
05-12 23:54:57.567: D/Chameleon Wallpaper(19614): Preview started
05-12 23:54:57.607: E/mm-libcamera2(161): PROFILE HAL: First preview frame received: 1368395697.614272749
05-12 23:54:57.607: E/BufferQueue(19614): [unnamed-19614-0] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=6 undequeudCount=0)
05-12 23:54:57.647: E/mm-libcamera2(161): mm_camera_dispatch_buffered_frames: mframe 0x0, sframe = 0x0
05-12 23:54:57.647: E/mm-libcamera2(161): PROFILE HAL: stopPreview(): E: 1368395697.653949232
05-12 23:54:57.647: E/mm-camera(175): config_MSG_ID_STOP_ACK: streamon_mask is not clear. Should not call PP_Release_HW
05-12 23:54:57.667: D/Chameleon Wallpaper(19614): Preview stopped
05-12 23:54:57.667: E/mm-libcamera2(161): PROFILE HAL: stopPreview(): E: 1368395697.676839512
05-12 23:54:57.667: E/QCameraHWI(161): android::status_t android::QCameraHardwareInterface::setPreviewWindow(preview_stream_ops_t*):Received Setting NULL preview window
05-12 23:54:57.677: E/QCameraHWI(161): android::status_t android::QCameraHardwareInterface::setPreviewWindow(preview_stream_ops_t*): mPreviewWindow = 0x0x0, mStreamDisplay = 0x0x4008c378
05-12 23:54:57.677: W/QCameraHWI_Preview(161):  Setting NULL preview window 
05-12 23:54:57.677: I/CameraClient(161): Destroying camera 0
05-12 23:54:57.687: E/mm-camera(175): config_shutdown_pp Camera not in streaming mode. Returning. 
05-12 23:54:57.687: E/mm-camera(175): vfe_ops_deinit: E
05-12 23:54:57.758: D/Chameleon Wallpaper(19614): Camera released
05-12 23:54:57.758: W/AudioFlinger(161): session id 77 not found for pid 161
05-12 23:54:57.758: W/AudioFlinger(161): session id 78 not found for pid 161
05-12 23:54:57.808: D/libEGL(19614): loaded /system/lib/egl/libEGL_adreno200.so
05-12 23:54:57.808: D/libEGL(19614): loaded /system/lib/egl/libGLESv1_CM_adreno200.so
05-12 23:54:57.808: D/libEGL(19614): loaded /system/lib/egl/libGLESv2_adreno200.so
05-12 23:54:57.818: I/Adreno200-EGL(19614): <eglInitialize:269>: EGL 1.4 QUALCOMM build: Nondeterministic AU_full_mako_PARTNER-ANDROID/JB-MR1-DEV_CL2961380_release_AU (CL2961380)
05-12 23:54:57.818: I/Adreno200-EGL(19614): Build Date: 12/10/12 Mon
05-12 23:54:57.818: I/Adreno200-EGL(19614): Local Branch: 
05-12 23:54:57.818: I/Adreno200-EGL(19614): Remote Branch: m/partner-android/jb-mr1-dev
05-12 23:54:57.818: I/Adreno200-EGL(19614): Local Patches: NONE
05-12 23:54:57.818: I/Adreno200-EGL(19614): Reconstruct Branch: NOTHING
05-12 23:54:57.848: D/OpenGLRenderer(19614): Enabling debug mode 0
05-12 23:54:57.888: I/ActivityManager(592): Displayed com.brushmate.chameleon/.SettingsActivity: +1s63ms

As far as I understood, the procedure is correct. So what am I doing wrong?

like image 504
stevecross Avatar asked May 12 '13 22:05

stevecross


People also ask

Can my phone take a picture when someone tries to unlock it?

HiddenEye – This Android app takes a picture when someone tries to unlock your phone by incorrectly guessing your passcode. The app can also be synced with your Dropbox account, so any pictures taken can be sent there directly.

What is the hidden eye app?

Hidden Eye is a simple app with no frills that will photograph the person when they try to unlock your phone. You can set it to play your ringtone when a user tries to unlock your phone without your knowledge. * Enable screen security lock on your phone.


1 Answers

After days of trying and further reading I found out that it was a timing problem. The Camera object is released before the jpeg callback is called. You just have to release the camera inside the callback.

package com.brushmate.chameleon;

import java.io.IOException;

import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.SystemClock;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.util.Log;
import android.view.SurfaceView;

public class SettingsActivity extends Activity {
    private static final String TAG = "Chameleon Wallpaper";

    @SuppressLint("NewApi") protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);

        Log.d(TAG, "Activity created");

        Camera cam = getCamera();

        if (cam != null) {
            Log.d(TAG, "Camera available");

            SurfaceTexture dummy = new SurfaceTexture(0);

            try {
            cam.setPreviewTexture(dummy);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            Log.d(TAG, "Preview texture set");

            cam.startPreview();

            Log.d(TAG, "Preview started");

            cam.takePicture(null, null, new Camera.PictureCallback() {

                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    Log.d(TAG, "Image taken");

                    cam.stopPreview();

                    Log.d(TAG, "Preview stopped");

                    cam.release();

                    Log.d(TAG, "Camera released");
                }
            });
        }
    }

    private Camera getCamera() {
        Camera cam = null;

        try {
            cam = Camera.open();
        } catch (RuntimeException e) {
            Log.e(TAG, "Camera not available", e);
        }

        return cam;
    }

}
like image 125
stevecross Avatar answered Sep 27 '22 20:09

stevecross