Question

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();
}
Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top