【问题标题】:Take photo with camera on sms receive在短信接收上用相机拍照
【发布时间】:2013-04-24 18:06:36
【问题描述】:

我有这个活动(MakePhotoActivity)类,当您打开应用程序时会拍照。我已将其设置为使用前置摄像头。

然后我有另一个类,它是一个已经在工作的 SMS 广播接收器。

现在,我想让它在收到短信时,使用我当前的班级拍照。但是我怎样才能将它们整合在一起呢?

当我尝试将方法(surfaceChanged 等)复制到我的广播接收器类,并在接收短信时,我将代码放在 onCreate 内(在 MakePhotoActivity 中)。而且它不起作用。

public class MakePhotoActivity 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;
    private int cameraId = 0;

    //Camera variables
    //a surface holder
    private SurfaceHolder sHolder; 
    //a variable to control the camera
    private Camera mCamera;
    //the camera parameters
    private Parameters parameters;


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


        //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
        sv = (SurfaceView) findViewById(R.id.surfaceView);

        //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
        sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    private int findFrontFacingCamera() {
        int cameraId = -1;
        // Search for the front facing camera
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                Log.d("A", "Camera found");

                cameraId = i;
                break;
            }
        }
        return cameraId;
    }

    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
    {
        //get camera parameters
        parameters = mCamera.getParameters();

        //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()
        {

            public void onPictureTaken(byte[] data, Camera camera)
            {
                //decode the data obtained by the camera into a Bitmap
                bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
                //set the iv_image
                iv_image.setImageBitmap(bmp);
                FileOutputStream outStream = null;
                try{
                    outStream = new FileOutputStream("/sdcard/Image"+System.currentTimeMillis()+".jpg");
                    outStream.write(data);
                    outStream.close();
                } catch (FileNotFoundException e){
                    Log.d("CAMERA", e.getMessage());
                } catch (IOException e){
                    Log.d("CAMERA", e.getMessage());
                }
            }
        };

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


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

        if (mCamera == null) {
            cameraId = findFrontFacingCamera();
            mCamera = Camera.open(cameraId);
            try {
                mCamera.setPreviewDisplay(holder);

                // TODO test how much setPreviewCallbackWithBuffer is faster
                // mCamera.setPreviewCallback((PreviewCallback) this);
            } catch (IOException e) {
                mCamera.release();
                mCamera = null;
            }
        }
    }


    public void surfaceDestroyed(SurfaceHolder holder)
    {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera = null;
        }
    } 

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        if (mCamera!=null)
        {
            mCamera.stopPreview();
            mCamera.release();
            mCamera=null;
        }
    }
}

更新:这就是我所做的。放入服务,但我收到一个错误,说应用程序通过了 NULL 表面,相机服务器死了!,ICamera 死了,错误 100。

我参考了http://easyandroidtutorials.blogspot.in/2012/09/capture-image-without-preview-as.html的代码,做了一些小改动,还是不行。

public class CameraService extends Service
{
    //Camera variables
    //a surface holder
    private SurfaceHolder sHolder; 
    //a variable to control the camera
    private Camera mCamera;
    //the camera parameters
    private Parameters parameters;
    SurfaceView sv;
    private int cameraId = 0;
    /** Called when the activity is first created. */
    @Override
    public void onCreate()
    {
        super.onCreate();
        Log.i("Service", "Service started");




    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try {


                if (mCamera == null) {
                    cameraId = findFrontFacingCamera();
                    mCamera = Camera.open(cameraId);

                try {
                    // Thread.sleep(3000);
                    sv = new SurfaceView(getApplicationContext());
                    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
                    mCamera.release();
                    mCamera = null;
                    e.printStackTrace();
                }


                //Get a surface
                //sHolder = sv.getHolder();
                //tells Android that this surface will have its data constantly replaced
                // sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return Service.START_STICKY;
    }

    private int findFrontFacingCamera() {
        int cameraId = -1;
        // Search for the front facing camera
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                Log.d("A", "Camera found");

                cameraId = i;
                break;
            }
        }
        return cameraId;
    }

    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());
            }

        }
    };


    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

有人对此有任何帮助吗?谢谢。

【问题讨论】:

  • 您是否阅读过Android官方文档中的BroadcastReceiver documentationIntent and intent filters
  • 嗨,我不是要开始接收短信活动。相反,我正在尝试让它在没有活动类的情况下在接收短信时自动拍照。
  • 哦,对不起,现在我明白了。现在,如果我没记错的话,理论说你应该运行service 来这样做,但我不知道你的代码为什么会失败。抛出了哪个错误?
  • 我已经更新了关于错误的帖子,以及我创建的服务类。

标签: android camera sms broadcast


【解决方案1】:

在你的短信广播接收器的 onReceive 方法中这样做:

Intent intent = new Intent(this, MakePhotoActivity.class);
startActivity(intent);

查看http://developer.android.com/training/basics/firstapp/starting-activity.html 了解有关开始活动的更多信息

要在服务中拍照,您需要创建一个虚拟表面视图。这是一个应该解释如何做到这一点的链接: how to take camera capture without a preview from a service or thread?

如果您想禁用快门声音: camera.enableShutterSound(false); http://developer.android.com/reference/android/hardware/Camera.html#enableShutterSound(boolean)

【讨论】:

  • 您好,我可能忘了说活动类不应该打开。意思是说照片将在没有任何交互的情况下拍摄,因为一旦收到短信,它就会拍摄照片。我可以利用活动中现有的代码并放置在广播接收器中吗?
  • 我以前从未从 SMSBroadcastReciever 捕获图像,但它应该可以工作。如果没有,请尝试创建一个可以进行图像捕获的服务或透明活动
  • 我尝试创建一个虚拟表面视图,但它不起作用,给了我一些错误。查看我更新的帖子。
  • 这就是我最初所做的,但效果不佳。给我错误 100(相机死机)。还有其他方法吗?
  • hmmm...这是解决方案:stackoverflow.com/questions/9930633/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
相关资源
最近更新 更多