我正在编写一个Android应用程序,它应该在用户定义的时间间隔内拍摄照片(20秒-1分钟)。即使在后台运行或设备正在睡眠时,它也应该拍摄照片。该应用程序将运行很长一段时间。如果需要唤醒设备,应尽快恢复睡眠以节省电池寿命。拍照后,该应用程序将处理一些额外的工作(比较两张图片)。
我读了一些关于调度警报(http://developer.android.com/training/scheduling/alarms.htm),创建服务(也是@android培训)和Android AsyncTasks,Java线程(http://www.mergeconflict.net/2012/05/java-threads-vs-android-asynctask-which.html)
的内容...但我仍然不确定实现这一目标的最佳方法是什么。
我的问题是:
非常感谢您的帮助。
答案 0 :(得分:0)
关于我们的问题,我知道我可以帮助开始在用户定义的时间间隔重复拍照任务的方面。对于此类任务,您可以使用Timer来实现此目的。代码看起来像这样:
mTmr = new Timer();
mTsk = new TimerTask() {
@Override
public void run() {
//Take picture or do whatever you want
}
};
mTmr.schedule(mTsk, 0, USER_DEFINED_EXECUTION_INTERVAL);
schedule
开始计时器。此处使用的schedule
的第一个参数是要运行的任务mTsk
。第二个参数是第一次执行之前的延迟(以毫秒为单位),在这种情况下没有延迟。第三个参数是您想要操作的参数,即执行的间隔。参数是执行之间的时间,所以如果它是20秒,你就会超过20,000。如果是一分钟,它将是60,000。您可以使用您喜欢的任何方法从用户处获取此值。
为了让计时器继续运行,请确保您不要在mTmr.cancel
中拨打onPause
,因为在您的情况下,您希望在用户不在应用内时保持计时器正常运行。不调用cancel
表示计时器将保留其资源,直到用户关闭该应用程序。
或者您可以查看此How to schedule a periodic task in Java?如果您想使用ScheduledExecutorService
而不是Timer
。
答案 1 :(得分:0)
我已经制作了这个应用程序 - Lenx。它广泛使用相机,我在后台处理图像。我使用AsyncTask来处理图像,它从未给出任何问题。该应用程序还有一个计时器,在一定的时间间隔后启动该过程。我使用的逻辑非常简单。
我还没有使用过Camera2 API,因此代码可能已被弃用。我创建了CameraPreview
类来实现Camera.PreivewCallback
。
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (data == null) {
return;
}
int expectedBytes = previewWidth * previewHeight *
ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
if (expectedBytes != data.length) {
Log.e(TAG, "Mismatched size of buffer! Expected ");
mState = STATE_NO_CALLBACKS;
mCamera.setPreviewCallbackWithBuffer(null);
return;
}
if (mProcessInProgress || mState == STATE_PROCESS_IN_PROGRESS) {
mCamera.addCallbackBuffer(data);
return;
}
if (mState == STATE_PROCESS) {
mProcessInProgress = true;
processDataTask = new ProcessDataTask();
processDataTask.execute(data);
}
}
public void startProcessing() {
mState = STATE_PROCESS;
}
我的AsyncTask就是这样的
private class ProcessDataTask
extends
AsyncTask<byte[], Void, Boolean> {
@Override
protected Boolean doInBackground(byte[]... datas) {
mState = STATE_PROCESS_IN_PROGRESS;
Log.i(TAG, "background process started");
byte[] data = datas[0];
long t1 = java.lang.System.currentTimeMillis();
// process your data
long t2 = java.lang.System.currentTimeMillis();
Log.i(TAG, "processing time = " + String.valueOf(t2 - t1));
mCamera.addCallbackBuffer(data);
mProcessInProgress = false;
return true;
}
@Override
protected void onPostExecute(Boolean result) {
mState = STATE_PROCESS_WAIT;
}
}
只要相机预览正在运行, onPreviewFrame()
将始终被调用。您需要获取数据并仅在触发某些内容时对其进行处理。因此,只需更改变量的状态,在本例中为mState
,并根据状态调用AsyncTask
。