2

我试图从相机中获取照片。在后台使用相机Android

@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; 

       } 

的问题是,该方法getJpegCallback周围是不正确的:(文件夹中没有日志和图片)Ю 当我调试应用程序,TAG - getJpegCallback不logcat中显示,但TAG takePictureNoPreview显示。关闭应用程序后,相机不允许(现在没有问题)。怎么了?

+1

我所经历的是我需要一个布局中的实际SurfaceView来拍照,所以我添加了一个SurfaceView,高度= 20dp,marginTop = -100dp或某物“将其移出视线”但它仍然存在于布局中。也许你应该尝试这样的事情。另一个想法是:你不应该在回调的surfaceCreated/Changed方法中调用setPreviewDisplay和startPreview? – damian

+0

好的。我尝试第一个变体 – user1755546

+0

您是否尝试在背景中录制视频 –

回答

3

我在开发EyeSpy时遇到了这个问题。我想要捕捉图像,即使应用程序在后台或前台。我尝试了几个星期,但没有运气。使用相机捕捉照片意味着显示其预览。

From Document(5.和6.)您必须使用SurfaceView来显示预览。

当您关闭应用程序或您的应用程序进入后台时,SurfaceView的表面将被销毁。这就是为什么我认为这是不可能的。

如果您发现任何其他方式,请在此发布。

希望这有助于你..

+0

您是否尝试过类似的方法? - ><使用权限的android:name =“android.permission.SYSTEM_ALERT_WINDOW”/> - >显示自定义“警报窗口”没有内容,但表面视图(不可见或某处在屏幕外),使用这一个预览显示? - > http://stackoverflow.com/questions/7678356/launch-popup-window-from-service – damian

+0

@ damian谢谢你让我知道..我今天早上尝试它,它的工作...我会试试看为我的应用程序。 –

+0

你有可能展开代码来完成这个任务吗?我有“测试测试”语言弹出,但无法让相机在没有FCing的情况下运行。 – Fmstrat

2

从API 11上,而不是用SurfaceViewSurfaceHolder,您可以使用SurfaceTexture。然后,您使用Camera.setPreviewTexture而不是Camera.setPreviewDisplay进行设置。

它适用于我在不同设备上的服务。

This回答以及this one讨论这一点。

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

请给予一些deatails。 –

-1

你可以试试这个

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" /> 

只是这样做其工作对我来说。 希望它有帮助。