Erstellen einer App, die einen EditText-Wert annimmt und diesen in Morse-Code übersetzt und Audio ausgibt, während eine TextView-Hintergrundfarbe geändert wird, um die Aufgabe zu bearbeiten. Die Audio- und TextView-Farbänderung soll zusammen erfolgen.
ich diese Klasse mit MorseTask.java
die ich glaube, ist mir die meisten Probleme verursacht:Morsecode-Anwendung AsyncTask Error 5
public class MorseTask extends AsyncTask<String, Integer, Void> {
private String translate;
@Override
protected Void doInBackground(String... params) {
translate = params[0];
int hold = 500;
LinkedList<Signal> signals = MorseCode.genOnOffSchedule(translate, hold);
long start = System.currentTimeMillis();
while (!signals.isEmpty()){
Signal sig = signals.removeFirst();
boolean landed = false;
while(!landed){
landed = (System.currentTimeMillis() - start) > sig.getOnset();
flashUI(sig);
}
}
return null;
}
//TODO this
public void flashUI(Signal signal){
int flashColor = Color.rgb(255, 255, 255);
int oldColor = Color.rgb(2, 2, 2);
if(signal.isOn()){
publishProgress(1);
MainActivity.textView2.setBackgroundColor(flashColor);
int toneHrzt = 440;
AudioTrack sound = AudioUtils.generateTone(toneHrzt, signal.getDuration());
sound.play();
//TODO this may need not null I'm not sure
if(sound == null){
sound.release();
}
}
else{
publishProgress(0);
MainActivity.textView2.setBackgroundColor(oldColor);
}
try {
Thread.sleep(signal.getDuration());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
//TODO add something here probably a void param
protected void onPostExecute(TextView result){
//TODO reset the activity, possibly
}
}
MorseCode.genOnOffSchedule(String, int)
ist ein Verfahren, das im wesentlichen die Sequenz/Muster des Morsecode einrichtet.Ich bin mir nicht sicher, wie man
onPostExecute
anders als möglicherweise die Aktivität zurücksetzen.
Hier ist meine MainActivity und wie ich die Ausführung der Aufgabe:
public class MainActivity extends AppCompatActivity {
public static TextView textView2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView2 = (TextView)findViewById(R.id.textView2);
final EditText message = (EditText)findViewById(R.id.editText);
final Button translate = (Button)findViewById(R.id.button);
translate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String text = message.getText().toString();
MorseTask transmit = new MorseTask();
transmit.execute(text);
}
});
}
}
Und schließlich meine logcat Fehler:
04-11 19:45:45.191 7815-7937/MYDOMAIN E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #5
Process: MYDOMAIN, PID: 7815
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6357)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:909)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:4690)
at android.view.View.invalidateInternal(View.java:11801)
at android.view.View.invalidate(View.java:11737)
at android.view.View.invalidateDrawable(View.java:15825)
at android.widget.TextView.invalidateDrawable(TextView.java:5129)
at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:368)
at android.graphics.drawable.ColorDrawable.setColor(ColorDrawable.java:134)
at android.view.View.setBackgroundColor(View.java:16184)
at edu.ggc.amauldin.morsecode.MorseTask.flashUI(MorseTask.java:45)
at edu.ggc.amauldin.morsecode.MorseTask.doInBackground(MorseTask.java:34)
at edu.ggc.amauldin.morsecode.MorseTask.doInBackground(MorseTask.java:18)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Sinn macht. Nur, wie kann ich sicherstellen, dass es blinkt, ohne FlashUI innerhalb der Bedingung, wo "signal.isOn()". Ich glaube nicht, dass ich wissen würde, welches Signal oder die Variable, die ich verwendet habe, "sig" gespielt wurde, um synchron mit dem Ton zu blinken. –
Ich bin nicht ganz sicher, was Sie sagen, aber jedes Mal, wenn Sie 'setBackgroundColor()' aufrufen, rufen Sie 'publishProgress()' entweder mit '0' oder' 1' auf, also mit 'onProgressUpdate()' Überprüfen Sie den übergebenen Wert und legen Sie den Hintergrund entsprechend fest. Wenn '0' =>' oldColor', wenn '1' =>' flashColor'. –
Ja, ich habe nicht festgestellt, was ich versucht habe zu vermitteln, aber überraschenderweise haben Sie meine Bedenken mit allen Widrigkeiten gegen Sie beantwortet. Vielen Dank! –