我正在开发一个获取心率的Android项目。应用程序运行正常但它不断进行处理并给出不同的读数。我希望应用程序在设定的时间后停止处理图像。我使用了postDelayed
方法,但它没有用,或者我没有使用它。也许有人可以帮忙。下面是进行图像处理的类。如何在大约20秒后停止处理?
/**
* This class extends Activity to handle a picture preview, process the preview
* for a red values and determine a heart beat.
*/
public class HeartRateMonitor extends Activity {
private static final String TAG = "HeartRateMonitor";
private static final AtomicBoolean processing = new AtomicBoolean(false);
private static SurfaceView preview = null;
private static SurfaceHolder previewHolder = null;
private static Camera camera = null;
private static View image = null;
private static TextView text = null;
private static WakeLock wakeLock = null;
private static int averageIndex = 0;
private static final int averageArraySize = 4;
private static final int[] averageArray = new int[averageArraySize];
public static enum TYPE {
GREEN, RED
};
private static TYPE currentType = TYPE.GREEN;
public static TYPE getCurrent() {
return currentType;
}
private static int beatsIndex = 0;
private static final int beatsArraySize = 3;
private static final int[] beatsArray = new int[beatsArraySize];
private static double beats = 0;
private static long startTime = 0;
/**
* {@inheritDoc}
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_heart_beat_rate);
preview = (SurfaceView) findViewById(R.id.preview);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
image = findViewById(R.id.image);
text = (TextView) findViewById(R.id.text);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNotDimScreen");
}
/**
* {@inheritDoc}
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
/**
* {@inheritDoc}
*/
@Override
public void onResume() {
super.onResume();
wakeLock.acquire();
camera = Camera.open();
startTime = System.currentTimeMillis();
}
/**
* {@inheritDoc}
*/
@Override
public void onPause() {
super.onPause();
wakeLock.release();
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
private PreviewCallback previewCallback = new PreviewCallback() {
/**
* {@inheritDoc}
*/
@Override
public void onPreviewFrame(byte[] data, Camera cam) {
if (data == null) throw new NullPointerException();
Camera.Size size = cam.getParameters().getPreviewSize();
if (size == null) throw new NullPointerException();
if (!processing.compareAndSet(false, true)) return;
int width = size.width;
int height = size.height;
int imgAvg = ImageProcessing.decodeYUV420SPtoRedAvg(data.clone(), height, width);
// Log.i(TAG, "imgAvg="+imgAvg);
if (imgAvg == 0 || imgAvg == 255) {
processing.set(false);
return;
}
int averageArrayAvg = 0;
int averageArrayCnt = 0;
for (int i = 0; i < averageArray.length; i++) {
if (averageArray[i] > 0) {
averageArrayAvg += averageArray[i];
averageArrayCnt++;
}
}
int rollingAverage = (averageArrayCnt > 0) ? (averageArrayAvg / averageArrayCnt) : 0;
TYPE newType = currentType;
if (imgAvg < rollingAverage) {
newType = TYPE.RED;
if (newType != currentType) {
beats++;
// Log.d(TAG, "BEAT!! beats="+beats);
}
} else if (imgAvg > rollingAverage) {
newType = TYPE.GREEN;
}
if (averageIndex == averageArraySize) averageIndex = 0;
averageArray[averageIndex] = imgAvg;
averageIndex++;
// Transitioned from one state to another to the same
if (newType != currentType) {
currentType = newType;
image.postInvalidate();
}
long endTime = System.currentTimeMillis();
double totalTimeInSecs = (endTime - startTime) / 1000d;
if (totalTimeInSecs >= 10) {
double bps = (beats / totalTimeInSecs);
int dpm = (int) (bps * 60d);
if (dpm < 20 || dpm > 120) {
startTime = System.currentTimeMillis();
beats = 0;
processing.set(false);
return;
}
// Log.d(TAG,
if (beatsIndex == beatsArraySize) beatsIndex = 0;
beatsArray[beatsIndex] = dpm;
beatsIndex++;
int beatsArrayAvg = 0;
int beatsArrayCnt = 0;
for (int i = 0; i < beatsArray.length; i++) {
if (beatsArray[i] > 0) {
beatsArrayAvg += beatsArray[i];
beatsArrayCnt++;
}
}
startTime = System.currentTimeMillis();
beats = 0;
final int beatsAvg = (beatsArrayAvg / beatsArrayCnt);
// final ArrayList HeartRateResultPojoObjArrayList = new ArrayList();
//maybe here
final AlertDialog alertDialog = new AlertDialog.Builder(HeartRateMonitor.this).create();
alertDialog.setTitle("Your Heart Rate is:");
alertDialog.setMessage(String.valueOf(beatsAvg) + " bpm");
alertDialog.setIcon(R.drawable.green_icon);
alertDialog.setButton(BUTTON_NEUTRAL, "Save",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent newActivityIntent = new Intent(HeartRateMonitor.this, History.class);
startActivity(newActivityIntent);
}
});
alertDialog.setButton(BUTTON_POSITIVE, "Share Result with a Doctor", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.putExtra("sms_body", "My Heart Rate is " + String.valueOf(beatsAvg) + "bpm. " + " Any Advice for me?");
sendIntent.setType("vnd.android-dir/mms-sms");
startActivity(sendIntent);
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"SMS failed, please try again later!",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
alertDialog.show();
}
}, 25000);
}
processing.set(false);
}
};
private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
/**
* {@inheritDoc}
*/
@SuppressLint("LongLogTag")
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(previewHolder);
camera.setPreviewCallback(previewCallback);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback", "Exception in setPreviewDisplay()", t);
}
}
/**
* {@inheritDoc}
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters = camera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
Camera.Size size = getSmallestPreviewSize(width, height, parameters);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
Log.d(TAG, "Using width=" + size.width + " height=" + size.height);
}
camera.setParameters(parameters);
camera.startPreview();
}
/**
* {@inheritDoc}
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Ignore
}
};
private Camera.Size getSmallestPreviewSize(int width, int height, Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width <= width && size.height <= height) {
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 :(得分:0)
它取决于正在运行的类的类型,如果它是AsyncTask,
cancel ( true)
取消当前操作。
如果您愿意,可以在其中一个对话框中的方法onCancel ()
内使用它。
调用cancel ( true)
时,它会更改已取消的状态,因此请将逻辑包装在
while ( ! isCancelled ( ) ) {
// do your logic
}