Android: Take Photo Without User Interface

I am interested in writing an app for android where after a certain event in the app a photo is automatically taken using the camera on the android.

Things I need:

  • No Preview of photo

  • No Button for User to press to take the photo

  • Just run the operation to take a photo and store it to the album.

  • here is some code i tried from a tutorial online:

    public void snap(){
           mCamera = Camera.open();
           SurfaceView sv = new SurfaceView(getApplicationContext());
    
    
           try {
                      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
                      e.printStackTrace();
                }
    
    
           //Get a surface
             sHolder = sv.getHolder();
    
    }
     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());
                      }
    
           }
        };
    
    
          public IBinder onBind(Intent intent) {
                // TODO Auto-generated method stub
                return null;
          }
    

    along with the logcat of what it did

        11-24 01:54:37.738: E/AndroidRuntime(6971): FATAL EXCEPTION: main                                                                                                                  
        11-24 01:54:37.738: E/AndroidRuntime(6971): java.lang.RuntimeException: Unable to start activity   ComponentInfo{com.example.udptest/com.example.udptest.Main}: java.lang.RuntimeException: takePicture failed
        11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2308)
        11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2358)
        11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.app.ActivityThread.access$600(ActivityThread.java:153)
        11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
        11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.os.Handler.dispatchMessage(Handler.java:99)
        11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.os.Looper.loop(Looper.java:137)
        11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.app.ActivityThread.main(ActivityThread.java:5227)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at java.lang.reflect.Method.invokeNative(Native Method)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at java.lang.reflect.Method.invoke(Method.java:511)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at dalvik.system.NativeStart.main(Native Method)
    11-24 01:54:37.738: E/AndroidRuntime(6971): Caused by: java.lang.RuntimeException: takePicture failed
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.hardware.Camera.native_takePicture(Native Method)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.hardware.Camera.takePicture(Camera.java:1101)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.hardware.Camera.takePicture(Camera.java:1046)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at com.example.udptest.Main.snap(Main.java:129)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at com.example.udptest.Main.onCreate(Main.java:84)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.app.Activity.performCreate(Activity.java:5104)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2262)
    11-24 01:54:37.738: E/AndroidRuntime(6971):     ... 11 more
    

    Any ideas what might be going on here, or a better way to accomplish this task?


    This is service to capture photo in background, hope it helps.:

    public class CapPhoto extends Service
    {
        private SurfaceHolder sHolder;    
        private Camera mCamera;
        private Parameters parameters;
    
    
      @Override
        public void onCreate()
        {
          super.onCreate();
          Log.d("CAM", "start");
    
          if (android.os.Build.VERSION.SDK_INT > 9) {
              StrictMode.ThreadPolicy policy = 
                   new StrictMode.ThreadPolicy.Builder().permitAll().build();
              StrictMode.setThreadPolicy(policy);}
              Thread myThread = null;
    
    
      }
      @Override
      public void onStart(Intent intent, int startId) {
    
        super.onStart(intent, startId);
    
     if (Camera.getNumberOfCameras() >= 2) { 
    
        mCamera = Camera.open(CameraInfo.CAMERA_FACING_FRONT); }
    
     if (Camera.getNumberOfCameras() < 2) { 
    
        mCamera = Camera.open(); }
        SurfaceView sv = new SurfaceView(getApplicationContext());
    
    
         try {
                   mCamera.setPreviewDisplay(sv.getHolder());
                   parameters = mCamera.getParameters();
                   mCamera.setParameters(parameters);
                   mCamera.startPreview();
    
                   mCamera.takePicture(null, null, mCall);
             } catch (IOException e) { e.printStackTrace(); }
    
            sHolder = sv.getHolder();
            sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
      }
    
      Camera.PictureCallback mCall = new Camera.PictureCallback()
      {
    
         public void onPictureTaken(final byte[] data, Camera camera)
         {
    
            FileOutputStream outStream = null;
                    try{
    
                        File sd = new File(Environment.getExternalStorageDirectory(), "A");
                        if(!sd.exists()) {                                 
                          sd.mkdirs();
                          Log.i("FO", "folder" + Environment.getExternalStorageDirectory());
                        } 
    
                            Calendar cal = Calendar.getInstance();
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
                            String tar = (sdf.format(cal.getTime()));
    
                            outStream = new FileOutputStream(sd+tar+".jpg");
                            outStream.write(data);  outStream.close();
    
                            Log.i("CAM", data.length + " byte written to:"+sd+tar+".jpg");
                            camkapa(sHolder);               
    
    
                     } catch (FileNotFoundException e){
                        Log.d("CAM", e.getMessage());
                    } catch (IOException e){
                        Log.d("CAM", e.getMessage());
                    }}
      };
    
    
        @Override
        public IBinder onBind(Intent intent) {
              return null;
        }
    
        public void camkapa(SurfaceHolder sHolder) {
    
            if (null == mCamera)
                return;
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
            Log.i("CAM", " closed");
            }
    
        }
    

    AndroidManifest.xml

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-feature android:name="android.hardware.camera" />
    
    <service android:name=".CapPhoto" android:enabled="true">
                 <intent-filter>
    
                </intent-filter>
            </service>
    

    Call this in your MainActivity to call service :

        Intent service;
    
        ....
    
        Calendar cal = Calendar.getInstance();
    
        service = new Intent(getBaseContext(), CapPhoto.class);
        cal.add(Calendar.SECOND, 15);
        //TAKE PHOTO EVERY 15 SECONDS
        PendingIntent pintent = PendingIntent.getService(this, 0, service, 0);
        AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                     60*60*1000, pintent);
        startService(service);
    

    Few tips:

  • First of all, don't hardcode file paths. Your /sdcard might not exist at all, so your outStream will be null, and it will crash when you call any method from outStream. Instead, use Environment.getExternalStoragePublicDirectory or Environment.getExternalStorageDirectory (for devices with Android version < 2.2). See here

  • no photo preview - you can make your preview 1pixel x 1pixel in size, so it will be barely visible

  • you need to declare permissions in AndroidManifest:

    "android.permission.CAMERA" and "android.permission.WRITE_EXTERNAL_STORAGE" (if you want to save pictures)

  • I suggest you go through the example form the docs and experiment.


    This guide tell you how to build a Camera App.I hope this can help you. http://developer.android.com/guide/topics/media/camera.html#custom-camera

    链接地址: http://www.djcxy.com/p/75714.html

    上一篇: 如何设置AFNetworking 2.0默认标题?

    下一篇: Android:无需用户界面拍照