Reputation: 304
I'm trying to turn the LED on and of for a particular lenght (out_tic), based on a given Text in Morse-Code(Text). I tried to solve this with a "postDelay" and also with sleep() or wait() , but the flash has allways the same lenght or the app crashes.. I think it's because the Flash is told to start when it hasn't closed yet.
cam = Camera.open();
Handler handler = new Handler();
for(int i=0;i<Text.length();i++){
if(Text.charAt(i)=='.' ||Text.charAt(i)=='·'){
ledon();
handler.postDelayed(new Runnable() {
public void run() {
ledoff();
}
}, out_tic);
}
else if(Text.charAt(i)=='-'){
ledon();
handler.postDelayed(new Runnable() {
public void run() {
ledoff();
}
}, 3*out_tic);
}
else if(Text.charAt(i)=='/'){
if(Text.charAt(i-1)=='/'){
}
}
}
The ledon() and ledoff() Methodes just set Parameters and start/stop the Preview.
Thanks for your help!
New code that works for me:
(Due to JRaymond)
final String Text = "./-..-/.-/--/.--./.-.././/";
final int out_tic = 200;
new Thread(new Runnable(){
@Override
public void run() {
for(int i=0;i<Text.length();i++){
if(Text.charAt(i)=='.' ||Text.charAt(i)=='·'){
flash(out_tic);
flashpause(out_tic);
continue;
}
else if(Text.charAt(i)=='-'){
flash(3*out_tic);
flashpause(out_tic);
continue;
}
else if(Text.charAt(i)=='/'){
flashpause(2*out_tic);
if(Text.charAt(i-1)=='/'){
flashpause(4*out_tic);
}
}
}
}
}).start();
}
private Handler handler = new Handler();
private void flash(final int sleeptime) {
handler.post(new Runnable() {
@Override
public void run() {
ledon();
}
});
try {
Thread.sleep(sleeptime);
} catch (InterruptedException e){
}
handler.post(new Runnable(){
public void run() {
ledoff();
}
});
}
private void flashpause(final int sleeptime) {
try {
Thread.sleep(sleeptime);
} catch (InterruptedException e){
}
}
private Camera cam;
private void ledon() {
cam = Camera.open();
Parameters params = cam.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
cam.setParameters(params);
cam.startPreview();
}
private void ledoff() {
cam.stopPreview();
cam.release();
}
Upvotes: 3
Views: 195
Reputation: 11782
I think I've pieced out your puzzle- all of your runnables are getting posted so that they occur at pretty much the same time. postDelayed
schedules the Runnable
for a time from now, not from the time that the last Runnable
was scheduled. I think your best solution would be something like this, which offloads the LED control to another thread:
cam = Camera.open();
Handler handler = new Handler();
new Thread(new Runnable() {
public void run() {
for(int i=0;i<Text.length();i++){
if(Text.charAt(i)=='.' ||Text.charAt(i)=='·') {
flash(out_tic);
continue;
}
else if(Text.charAt(i)=='-'){
flash(3 * out_tic)
continue;
}
// I don't quite understand what this does, but the same principles apply
else if(Text.charAt(i)=='/'){
//Warte 2*out_tic lang (1mal wurde schon gewartet)
if(Text.charAt(i-1)=='/'){
}
}
}
}
private void flash(int tic) {
handler.post(new Runnable() {
public void run() {
ledon();
}
});
try {
Thread.sleep(out_tic);
} catch (InterruptedException e) {
}
handler.post(new Runnable() {
public void run() {
ledoff();
}
}
}
});
Note that the above is pretty messy, you might want to move things around and clean it up a little - but the idea is that you let a different thread from the UI do the sleeping and then post back to the handler when the Camera parameters need to be changed.
Upvotes: 1