Android在广播接收器内异步拍照

时间:2013-08-31 23:44:23

标签: android broadcastreceiver android-camera intentservice

我一直在努力解决上述问题,所以非常感谢任何答案。

首先,我的主要目的是在收到意图时(在广播接收器内)拍照。 我已经尝试了很多方法,但无济于事。 以下(显示相关代码片段以获得视觉清晰度)代码说明了一种方法:

public class ArduinoReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
takePictureUsingCamera();
}    }

函数takePictureUsingCamera()调用处理相机的类中的函数(例如在FrameLayout中显示相机预览)。特定的函数在android中调用android takePicture函数:     this.mPreview.mCamera.takePicture(null,null,this.mPicture);

然而,当我收到意图时,应用程序崩溃了。我觉得这背后的原因是拍摄照片可能要求在广播接收器内完成太多工作。 (我使用按钮使用简单的图片捕获测试了这个功能,它运行得很好。)

所以,我尝试的第二种方法是创建一个Intentservice,它将在收到意图时处理拍照(以及其他相关任务,如存储图片)。

Service的onHandleIntent(Intent intent)方法现在将具有this.mCameraView.takePicture(filename)函数。但是,我需要使用intent将我的CameraView类作为对象传递给此服务。为此,我创建了一个Serializable类,并尝试使用intent的putExtra方法传递它。几次崩溃后,我意识到CameraView类不可序列化(它在FrameLayout中显示相机预览)。

我想到的另一种替代方法是在新服务中创建cameraView对象本身,但为此我需要上下文和对主活动的引用 - 我认为不能使用意图传递。 这样就可以选择开始一个新的活动来拍摄广播接收器中的图片 - 再次看起来就像做了太多的工作。 正如我之前所说,我尝试了一些方法,但没有取得任何成功。我个人认为不会出现这样的问题。我非常感谢并非常感谢任何回答者。

3 个答案:

答案 0 :(得分:1)

我不是百分之百确定你想要做什么,但听起来你想要在播出时想要触发某些事情(拍照)?

为此,您可以在主活动中创建一个处理程序,然后在收到广播时向其发送消息。在你的活动中有这样的事情。

Handler myHandler = new Handler() {
        @Override 
        public void handleMessage(Message msg) {
                        takePicture();
                    }
});

broadcastReceiver = new YourReceiverClass(myHandler);

intentFilter = new IntentFilter(
            "your_package_name.YourReceiverClass");
    registerReceiver(broadcastReceiver, intentFilter);

接收器中的类似内容

private Handler handler;
public YourReceiverClass(Handler handler) {
    this.handler = handler;
}

public void onReceive(Context context, Intent intent) {
    Bundle bundle = intent.getExtras();
    if (handler != null) {
            handler.sendEmptyMessage(0);
            }
}

答案 1 :(得分:0)

好的,所以经过一段时间的努力并考虑到使用处理程序的上述建议后,我仍然没有完全解决方案。然而,经过一些测试后,应用程序似乎在拍了几张照片后崩溃了。这也是单击拍摄按钮拍照时的情况。

目前,我正在使用以下代码处理程序:

    Handler myHandler = new Handler(Looper.getMainLooper())
{
@Override 
public void handleMessage(Message msg)
{
System.out.println("HANDLER received a message");
takePictureUsingCamera();
}
};

我认为这与一些高级Android概念有关吗?也许某些东西已经耗尽内存?如果有人能根据上述观点给我一些建议,我将非常感激。

答案 2 :(得分:0)

嗯,这不是一项简单的任务。我在我的应用程序中做了同样的事情。 基本上流程很简单 - 当你收到广播时,你应该启动你的Service / IntentService,它将执行以下操作:

  • 从BroadcastReceiver获取参数
  • 获取部分唤醒锁
  • 启动打开相机的新线程,初始化所有需要的参数(图像分辨率,压缩等),提供相机预览窗口(这是一个有问题的部分,我将在稍后介绍),检查自动对焦并启动它,从自动对焦获取回调并拍摄照片。在回调中,您将获得图片的二进制数据。不要忘记最后关闭相机。

现在关于预览表面 - 这里的问题是你没有Activity上下文,因此预览窗口将只是具有NULL表面的“虚拟”窗口。而这个事实在不同的设备上会产生很多问题 - 其中一些设备会起作用,而另一些则会失败。 创建此窗口的代码是

cameraPreview = new SurfaceView(_serviceReference.get());
cameraPreview.setZOrderOnTop(true);                
cameraPreview.getHolder().setFormat(PixelFormat.TRANSPARENT);
camera.setPreviewDisplay(cameraPreview.getHolder());
camera.startPreview();