Reputation: 5354
I am trying to make the LED light on my back-facing camera blink every N seconds:
private void blink() {
for (int i = 0; i < 5; i++) {
turnOnLedLight();
try {
Thread.sleep(1000); // N = 1 second
}
catch (InterruptedException e) {
Log.e("Test", "Got interrupted.");
}
turnOffLedLight();
}
}
private static Camera camera = null;
private void turnOnLedLight() {
camera = Camera.open();
Parameters p = camera.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
camera.startPreview();
}
private void turnOffLedLight() {
camera.stopPreview();
camera.release();
camera = null;
}
The code above works, but is there a better approach besides putting the thread to sleep? The blink
method is called in the doInBackground
method in an AsyncTask
.
Update
I realized that the code above makes the LED light stay on for N seconds. I want to know whether there is a better way to make it stay on for N seconds and stay off for N seconds.
Upvotes: 0
Views: 74
Reputation: 8371
Here's another way to do it if your on/off cycle is symmetrical:
public Boolean ledOn = false;
...
// Change the LED state once a second for 5 minutes:
CountDownTimer cdt = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
ledOn = !ledOn;
if (ledOn)
turnOffLedLight();
else
turnOnLedLight();
}
public void onFinish() {
Log.d(TAG, "LED is on? "+ ledOn.toString());
}
};
...
cdt.start();
...
cdt.cancel();
(Edited to better handle starting/stopping.)
Upvotes: 0
Reputation: 807
you can use System.currentTimeMillis() if you're trying to make it more accurate,like:
long previousTimeMillis = System.currentTimeMillis();
int i = 0;
while(i < 5){
if(System.currentTimeMillis() - previousTimeMillis >= 1000){
turnOffLedLight();
previousTimeMillis = System.currentTimeMillis();
i++;
}else{
turnOnLedLight();
}
}
and here's what you can do to make led stay on and off for N seconds:
long previousTimeMillis = Sustem.currentTimeMillis();
boolean shouldTurnOnLight = true;
int i = 0;
while(i < 5){
if(System.currentTimeMillis() - previousTimeMillis >= 1000){
if(shouldTurnOnLight){
turnOnLedLight();
shouldTurnOnLight = false;
}else{
turnOffLedLight();
shouldTurnOnLight = true;
}
previousTimeMillis = System.currentTimeMillis();
i++;
}
}
Upvotes: 0
Reputation: 93561
I'd do it in an alarm via alarmManager. You're holding up the AsyncTask thread. As of 3.0, Async tasks all share a thread and are executed round robin. This means in you have any other async tasks, it would be blocked. In addition an Alarm will wake the phone if it goes to sleep, if the phone goes to sleep while you're in your thread the thread will be paused and will be frozen in its current state of blinking until the user wakes it.
I'd also do Camera.open only once, when you first want the camera, and release it when you no longer want it anymore, rather than request it in each turnOnLedLight (causing you to get and release the camera 5 times). Right now if someone changed apps while you were off and opened the camera app, you could be locked out from getting the camera again (and likely crash).
Upvotes: 2