【问题标题】:Using the camera in Background Android在后台 Android 中使用相机
【发布时间】:2013-09-09 05:01:17
【问题描述】:

我正在尝试将照片从相机中投入使用。

@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 会显示。关闭应用程序后,相机不允许(现在没问题)。怎么了?

【问题讨论】:

  • 我的经验是,我需要在布局中使用实际的 SurfaceView 来拍照,所以我添加了一个高度=20dp 和 marginTop=-100dp 的 SurfaceView 或其他东西来“移动它”看不见”,但它仍然存在于布局中。也许你应该尝试这样的事情。另一个思路是:不应该在回调的surfaceCreated/Changed方法中调用setPreviewDisplay和startPreview吗?
  • 好的。我正在尝试第一个变体
  • 您是否要在后台录制视频

标签: android background android-camera android-service surfaceview


【解决方案1】:

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

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

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

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

希望对你有所帮助..

【讨论】:

  • 你尝试过这样的事情吗? -> -> 显示自定义“警报窗口”,没有内容,只有一个表面视图(不可见或屏幕外某处),使用这个作为预览显示? -> stackoverflow.com/questions/7678356/…
  • @damian 感谢您告诉我..我今天早上试了一下,它成功了...我会在我的应用程序上试一试。
  • 你有没有机会扩展代码来完成这个?我弹出了“测试测试测试”语言,但没有 FCing 就无法让相机运行。
【解决方案2】:

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

在不同设备上的服务对我来说效果很好。

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

【讨论】:

    【解决方案3】:
    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);
        }
    }
    

    【讨论】:

    • 请提供一些细节。
    【解决方案4】:

    似乎解决方案已经晚了,但仍然......实际上我们可以通过在 onCreate() 中使用 WindowManager 并膨胀布局......和 ​​setVisibility(View.INVISIBLE)

    从服务中获得 UI
    @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);
                    }
    
                }
            });
    

    您也可以参考示例应用程序https://github.com/gauravbspr/Research-Projects/tree/master/Camera%20Service 并在必要时提供帮助

    【讨论】:

      【解决方案5】:

      不知道这是否晚了,但对于仍在搜索的任何人,请试试这个Android Background Camerahttps://github.com/YoboZorle/Android-Background-Camera

      【讨论】:

        【解决方案6】:

        你可以试试这个

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

        只要这样做对我有用。 希望对您有所帮助。

        【讨论】:

          猜你喜欢
          • 2013-10-17
          • 1970-01-01
          • 1970-01-01
          • 2011-07-04
          • 2015-03-29
          • 1970-01-01
          • 2013-04-29
          • 2020-01-25
          • 1970-01-01
          相关资源
          最近更新 更多