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();
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With