I've (legally) copied and pasted some project code from an app called beatkeeper into my own app. I wanted to implement a metronome.
The app beatkeeper on itself works fine but as I soon as I copy the code and run my own app, it's stops working the moment I click the start/stop button...
04-07 09:25:05.126: E/AndroidRuntime(2708): FATAL EXCEPTION: main
04-07 09:25:05.126: E/AndroidRuntime(2708): Process: nl.ruudjanssenmusicservices.desaxofoonapp, PID: 2708
04-07 09:25:05.126: E/AndroidRuntime(2708): java.lang.NullPointerException
04-07 09:25:05.126: E/AndroidRuntime(2708): at nl.ruudjanssenmusicservices.desaxofoonapp.MetronomeActivity$6.handleMessage(MetronomeActivity.java:54)
04-07 09:25:05.126: E/AndroidRuntime(2708): at android.os.Handler.dispatchMessage(Handler.java:102)
04-07 09:25:05.126: E/AndroidRuntime(2708): at android.os.Looper.loop(Looper.java:136)
04-07 09:25:05.126: E/AndroidRuntime(2708): at android.app.ActivityThread.main(ActivityThread.java:5017)
04-07 09:25:05.126: E/AndroidRuntime(2708): at java.lang.reflect.Method.invokeNative(Native Method)
04-07 09:25:05.126: E/AndroidRuntime(2708): at java.lang.reflect.Method.invoke(Method.java:515)
04-07 09:25:05.126: E/AndroidRuntime(2708): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
04-07 09:25:05.126: E/AndroidRuntime(2708): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
04-07 09:25:05.126: E/AndroidRuntime(2708): at dalvik.system.NativeStart.main(Native Method)
Source main activity:
package nl.ruudjanssenmusicservices.desaxofoonapp;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Spinner;
import android.widget.TextView;
public class MetronomeActivity extends Activity {
private final short minBpm = 40;
private final short maxBpm = 208;
private short bpm = 100;
private short noteValue = 4;
private short beats = 4;
private short volume;
private short initialVolume;
private double beatSound = 2440;
private double sound = 6440;
private AudioManager audio;
private MetronomeAsyncTask metroTask;
private Button plusButton;
private Button minusButton;
private TextView currentBeat;
private Handler mHandler;
// have in mind that: http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler
// in this case we should be fine as no delayed messages are queued
private Handler getHandler() {
return new Handler() {
#Override
public void handleMessage(Message msg) {
String message = (String)msg.obj;
if(message.equals("1"))
currentBeat.setTextColor(Color.GREEN);
else
currentBeat.setTextColor(getResources().getColor(R.color.yellow));
currentBeat.setText(message);
}
};
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
metroTask = new MetronomeAsyncTask();
/* Set values and listeners to buttons and stuff */
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
TextView timeSignatureText = (TextView) findViewById(R.id.timesignature);
timeSignatureText.setText(""+beats+"/"+noteValue);
plusButton = (Button) findViewById(R.id.plus);
plusButton.setOnLongClickListener(plusListener);
minusButton = (Button) findViewById(R.id.minus);
minusButton.setOnLongClickListener(minusListener);
// currentBeat = (TextView) findViewById(R.id.currentBeat);
//currentBeat.setTextColor(Color.GREEN);
Spinner beatSpinner = (Spinner) findViewById(R.id.beatspinner);
ArrayAdapter<Beats> arrayBeats =
new ArrayAdapter<Beats>(this,
android.R.layout.simple_spinner_item, Beats.values());
beatSpinner.setAdapter(arrayBeats);
beatSpinner.setSelection(Beats.four.ordinal());
arrayBeats.setDropDownViewResource(R.layout.spinner_dropdown);
beatSpinner.setOnItemSelectedListener(beatsSpinnerListener);
Spinner noteValuesdSpinner = (Spinner) findViewById(R.id.notespinner);
ArrayAdapter<NoteValues> noteValues =
new ArrayAdapter<NoteValues>(this,
android.R.layout.simple_spinner_item, NoteValues.values());
noteValuesdSpinner.setAdapter(noteValues);
noteValues.setDropDownViewResource(R.layout.spinner_dropdown);
noteValuesdSpinner.setOnItemSelectedListener(noteValueSpinnerListener);
audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
initialVolume = (short) audio.getStreamVolume(AudioManager.STREAM_MUSIC);
volume = initialVolume;
SeekBar volumebar = (SeekBar) findViewById(R.id.volumebar);
volumebar.setMax(audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumebar.setProgress(volume);
volumebar.setOnSeekBarChangeListener(volumeListener);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public synchronized void onStartStopClick(View view) {
Button button = (Button) view;
String buttonText = button.getText().toString();
if(buttonText.equalsIgnoreCase("start")) {
button.setText(R.string.stop);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
metroTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
else
metroTask.execute();
} else {
button.setText(R.string.start);
metroTask.stop();
metroTask = new MetronomeAsyncTask();
Runtime.getRuntime().gc();
}
}
private void maxBpmGuard() {
if(bpm >= maxBpm) {
plusButton.setEnabled(false);
plusButton.setPressed(false);
} else if(!minusButton.isEnabled() && bpm>minBpm) {
minusButton.setEnabled(true);
}
}
public void onPlusClick(View view) {
bpm++;
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
metroTask.setBpm(bpm);
maxBpmGuard();
}
private OnLongClickListener plusListener = new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
bpm+=20;
if(bpm >= maxBpm)
bpm = maxBpm;
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
metroTask.setBpm(bpm);
maxBpmGuard();
return true;
}
};
private void minBpmGuard() {
if(bpm <= minBpm) {
minusButton.setEnabled(false);
minusButton.setPressed(false);
} else if(!plusButton.isEnabled() && bpm<maxBpm) {
plusButton.setEnabled(true);
}
}
public void onMinusClick(View view) {
bpm--;
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
metroTask.setBpm(bpm);
minBpmGuard();
}
private OnLongClickListener minusListener = new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
bpm-=20;
if(bpm <= minBpm)
bpm = minBpm;
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
metroTask.setBpm(bpm);
minBpmGuard();
return true;
}
};
private OnSeekBarChangeListener volumeListener = new OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
volume = (short) progress;
audio.setStreamVolume(AudioManager.STREAM_MUSIC, progress, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
};
private OnItemSelectedListener beatsSpinnerListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Beats beat = (Beats) arg0.getItemAtPosition(arg2);
TextView timeSignature = (TextView) findViewById(R.id.timesignature);
timeSignature.setText(""+beat+"/"+noteValue);
metroTask.setBeat(beat.getNum());
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
private OnItemSelectedListener noteValueSpinnerListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
NoteValues noteValue = (NoteValues) arg0.getItemAtPosition(arg2);
TextView timeSignature = (TextView) findViewById(R.id.timesignature);
timeSignature.setText(""+beats+"/"+noteValue);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
#Override
public boolean onKeyUp(int keycode, KeyEvent e) {
SeekBar volumebar = (SeekBar) findViewById(R.id.volumebar);
volume = (short) audio.getStreamVolume(AudioManager.STREAM_MUSIC);
switch(keycode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
volumebar.setProgress(volume);
break;
}
return super.onKeyUp(keycode, e);
}
public void onBackPressed() {
metroTask.stop();
// metroTask = new MetronomeAsyncTask();
Runtime.getRuntime().gc();
audio.setStreamVolume(AudioManager.STREAM_MUSIC, initialVolume, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
finish();
}
private class MetronomeAsyncTask extends AsyncTask<Void,Void,String> {
Metronome metronome;
MetronomeAsyncTask() {
mHandler = getHandler();
metronome = new Metronome(mHandler);
}
protected String doInBackground(Void... params) {
metronome.setBeat(beats);
metronome.setNoteValue(noteValue);
metronome.setBpm(bpm);
metronome.setBeatSound(beatSound);
metronome.setSound(sound);
metronome.play();
return null;
}
public void stop() {
metronome.stop();
metronome = null;
}
public void setBpm(short bpm) {
metronome.setBpm(bpm);
metronome.calcSilence();
}
public void setBeat(short beat) {
if(metronome != null)
metronome.setBeat(beat);
}
}
}
I think there might be a problem with the 'private Handler getHandler' on line 48, but I have absolutely no clue how to solve this...
Edit: request to post the metronome-class:
package nl.ruudjanssenmusicservices.desaxofoonapp;
import android.os.Handler;
import android.os.Message;
public class Metronome {
private double bpm;
private int beat;
private int noteValue;
private int silence;
private double beatSound;
private double sound;
private final int tick = 1000; // samples of tick
private boolean play = true;
private AudioGenerator audioGenerator = new AudioGenerator(8000);
private Handler mHandler;
private double[] soundTickArray;
private double[] soundTockArray;
private double[] silenceSoundArray;
private Message msg;
private int currentBeat = 1;
public Metronome(Handler handler) {
audioGenerator.createPlayer();
this.mHandler = handler;
}
public void calcSilence() {
silence = (int) (((60/bpm)*8000)-tick);
soundTickArray = new double[this.tick];
soundTockArray = new double[this.tick];
silenceSoundArray = new double[this.silence];
msg = new Message();
msg.obj = ""+currentBeat;
double[] tick = audioGenerator.getSineWave(this.tick, 8000, beatSound);
double[] tock = audioGenerator.getSineWave(this.tick, 8000, sound);
for(int i=0;i<this.tick;i++) {
soundTickArray[i] = tick[i];
soundTockArray[i] = tock[i];
}
for(int i=0;i<silence;i++)
silenceSoundArray[i] = 0;
}
public void play() {
calcSilence();
do {
msg = new Message();
msg.obj = ""+currentBeat;
if(currentBeat == 1)
audioGenerator.writeSound(soundTockArray);
// else
// audioGenerator.writeSound(soundTickArray);
if(bpm <= 120)
mHandler.sendMessage(msg);
audioGenerator.writeSound(silenceSoundArray);
if(bpm > 120)
mHandler.sendMessage(msg);
currentBeat++;
if(currentBeat > beat)
currentBeat = 1;
} while(play);
}
public void stop() {
play = false;
audioGenerator.destroyAudioTrack();
}
public double getBpm() {
return bpm;
}
public void setBpm(int bpm) {
this.bpm = bpm;
}
public int getNoteValue() {
return noteValue;
}
public void setNoteValue(int bpmetre) {
this.noteValue = bpmetre;
}
public int getBeat() {
return beat;
}
public void setBeat(int beat) {
this.beat = beat;
}
public double getBeatSound() {
return beatSound;
}
public void setBeatSound(double sound1) {
this.beatSound = sound1;
}
public double getSound() {
return sound;
}
public void setSound(double sound2) {
this.sound = sound2;
}
}
currentBeat is null there in onHandleMessage();
Related
Requirement is to play a chime sound an phrase after that using Android Text to Speech.
for (final Integer orderId : voiceoverIds) {
alertChimePlayer = MediaPlayer.create(getApplicationContext(), R.raw.orderalert);
alertChimePlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
String orderSpeechText = "Number " + orderId;
textToSpeech.speak(orderSpeechText, TextToSpeech.QUEUE_ADD, null, "ORDER_NO_" + orderId);
textToSpeech.playSilentUtterance(2000, TextToSpeech.QUEUE_ADD, "PAUSE_NO_" + orderId);
System.out.println(">>>>>>>>>>>>>>>>>>> orderSpeechText : " + orderSpeechText);
}
});
alertChimePlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
alertChimePlayer.start();
}
});
}
But this only works one time. How to handle this properly?
Good question. Stayed up all night on this. The problem is that in the loop, those chimes just get rapidly sent to the media player all at the same time. Media Player cant really handle that properly.
Here is my solution. I am using SoundPool to play the chime because it is better at playing short sounds in repetition.
I am also using a timer thread to trigger the "Chime + spoken text-to-speech (tts)" sequences. The tts onUtteranceProgressListener is used to play the tts after the chime sound.
Here is the tested code. What you will hear is:
chime "number 1" (3 second delay)
chime "number 2" (3 second delay)
... continues until terminated
import android.app.Activity;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;
import java.util.Locale;
public class MainActivity extends Activity implements TextToSpeech.OnInitListener {
AudioAttributes aa;
SoundPool sp;
private TextToSpeech tts;
int MAX_STREAMS = 5;
int REPEAT = 0;
int DELAY = 3000;
int orderId = 0;
// Clock thread
Thread m_clockThread;
boolean m_bClockThreadStop;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("TTS", "Starting...");
// Set up the sound pool sound
AudioAttributes aa = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build();
sp = new SoundPool.Builder()
.setMaxStreams(8)
.setAudioAttributes(aa)
.build();
// Start the tts
tts = new TextToSpeech(MainActivity.this,MainActivity.this);
tts.setLanguage(Locale.US);
}
#Override
public void onInit(int status) {
Log.e("TTS", "Enter onInit...");
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(Locale.US);
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "This Language is not supported");
} else {
Log.e("TTS", "onInit Success");
// create and run clock thread
createAndRunClockThread(this);
}
} else {
Log.e("TTS", "onInit Fail");
}
}
public void createAndRunClockThread(final Activity act) {
m_bClockThreadStop=false;
m_clockThread = new Thread(new Runnable() {
public void run() {
while(!m_bClockThreadStop) {
try {
act.runOnUiThread(new Runnable() {
public void run() {
playChime();
}
});
Thread.sleep(DELAY);
}
catch(InterruptedException e) {
Log.e("TTS", "ClockThread fail");
}
}
}
});
m_clockThread.start();
}
private void playChime() {
Log.e("TTS", "Entering startChimes...");
sp.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(final SoundPool soundPool, final int soundId, int status) {
final int priority = 0;
final int repeat = 0;
final float rate = 1.f; // Frequency Rate can be from .5 to 2.0
// Set volume
AudioManager mgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
final float volume = streamVolumeCurrent / streamVolumeMax;
// Play a chime followed by the tts
tts.speak("Number " + orderId, TextToSpeech.QUEUE_ADD, null, "ID" + orderId);
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
// Speaking started.
sp.play(soundId, volume, volume, priority, repeat, rate);
}
#Override
public void onDone(String utteranceId) {
// Speaking stopped.
orderId = orderId + 1;
}
#Override
public void onError(String utteranceId) {
// There was an error.
}
});
}
});
sp.load(this, R.raw.beep, 1);
}
}
Thanks for the answer #Mark W. But I was thinking of solution that doesn't involve explicit delays/sleeps.
So I was implementing this Service Class.
public class OrderNoticeService extends Service implements TextToSpeech.OnInitListener {
private List<OrderSpeechAsyncTask> orderSpeechAsyncTasks = new ArrayList<>();
private TextToSpeech textToSpeech;
private Context context;
public void addToOrderNoticeQueue(int orderId) {
String orderSpeechText = String.format(getResources().getString(R.string.order_voice_over_default_text), Integer.toString(orderId));
orderSpeechAsyncTasks.add(new OrderSpeechAsyncTask(getApplicationContext(), R.raw.orderalert, orderSpeechText, textToSpeech, new AsyncTaskCallback() {
#Override
public void onTaskCompleted(Object response) {
}
}));
if (orderSpeechAsyncTasks.size() > 1) {
final OrderSpeechAsyncTask orderSpeechAsyncTask = orderSpeechAsyncTasks.get(orderSpeechAsyncTasks.size() - 1);
OrderSpeechAsyncTask orderSpeechAsyncTaskPrior = orderSpeechAsyncTasks.get(orderSpeechAsyncTasks.size() - 2);
orderSpeechAsyncTaskPrior.setAsyncTaskCallback(new AsyncTaskCallback() {
#Override
public void onTaskCompleted(Object response) {
try {
orderSpeechAsyncTask.execute();
System.out.println("Execution!");
} catch (Exception e) {
}
}
});
}
}
#Override
public void onCreate() {
textToSpeech = new TextToSpeech(this, this);
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this;
return Service.START_STICKY;
}
private static final String TAG = "OrderNoticeService";
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "OrderNoticeService onBind");
return mBinder;
}
#Override
public void onDestroy() {
if (textToSpeech != null) {
textToSpeech.stop();
textToSpeech.shutdown();
}
Log.i(TAG, "OrderNoticeService onDestroy");
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
OrderNoticeVoiceOverThread orderNoticeVoiceOverThread = new OrderNoticeVoiceOverThread(context, orderSpeechAsyncTasks);
orderNoticeVoiceOverThread.start();
} else {
System.out.println("Text To Speech not supported!");
}
}
private class OrderNoticeVoiceOverThread extends Thread {
private Context context;
private List<OrderSpeechAsyncTask> orderSpeechAsyncTasks;
private boolean anyTaskRunning = false;
public OrderNoticeVoiceOverThread(Context context, List<OrderSpeechAsyncTask> orderSpeechAsyncTasks) {
this.context = context;
this.orderSpeechAsyncTasks = orderSpeechAsyncTasks;
}
public void run() {
while (true) {
for (OrderSpeechAsyncTask orderSpeechAsyncTask : new ArrayList<OrderSpeechAsyncTask>(orderSpeechAsyncTasks)) {
if (orderSpeechAsyncTask != null && orderSpeechAsyncTask.getStatus().equals(AsyncTask.Status.RUNNING)) {
anyTaskRunning = true;
break;
}
}
if (!anyTaskRunning) {
for (OrderSpeechAsyncTask orderSpeechAsyncTask : new ArrayList<OrderSpeechAsyncTask>(orderSpeechAsyncTasks)) {
if (orderSpeechAsyncTask != null && orderSpeechAsyncTask.getStatus().equals(AsyncTask.Status.PENDING)) {
orderSpeechAsyncTask.execute();
anyTaskRunning = false;
break;
}
}
}
}
}
}
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public OrderNoticeService getService() {
return OrderNoticeService.this;
}
}
}
And the OrderSpeechAsyncTask as follows.
public class OrderSpeechAsyncTask extends AsyncTask<Void, Void, Void> {
private static final String LOG_TAG = OrderSpeechAsyncTask.class.getSimpleName();
private MediaPlayer mediaPlayer;
private int soundId;
private Context context;
private String orderSpeechText;
private AsyncTaskCallback asyncTaskCallback;
private TextToSpeech textToSpeech;
public OrderSpeechAsyncTask(final Context context, int soundId, String orderSpeechText, TextToSpeech textToSpeech, AsyncTaskCallback asyncTaskCallback) {
this.context = context;
this.soundId = soundId;
this.orderSpeechText = orderSpeechText;
this.textToSpeech = textToSpeech;
this.asyncTaskCallback = asyncTaskCallback;
}
public AsyncTaskCallback getAsyncTaskCallback() {
return asyncTaskCallback;
}
public void setAsyncTaskCallback(AsyncTaskCallback asyncTaskCallback) {
this.asyncTaskCallback = asyncTaskCallback;
}
#Override
protected Void doInBackground(Void... params) {
mediaPlayer = MediaPlayer.create(context, soundId);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.release();
textToSpeech.speak(orderSpeechText, TextToSpeech.QUEUE_ADD, null, "ORDER_NO_" + orderSpeechText);
textToSpeech.playSilentUtterance(2000, TextToSpeech.QUEUE_ADD, "PAUSE_NO_" + orderSpeechText);
textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
}
#Override
public void onDone(String utteranceId) {
asyncTaskCallback.onTaskCompleted(null);
}
#Override
public void onError(String utteranceId) {
}
});
}
});
mediaPlayer.start();
return null;
}
}
This so far handles the following;
Playing the sound and the text in the list
Adding an item to the queue whilst the existing list is still being read
To do;
This doesn't handle any new item that gets added to the list once the existing items are done being read.
In my code, I have implemented the sliding layouts. I have a front page which runs a video, while the user interaction is being done with layouts sliding up and down. Here's the code:
package org.udoo.androidadkdemobidirect;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Point;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.widget.VideoView;
import java.io.DataOutputStream;
import java.io.IOException;
//import org.udoo.androidadkdemobidirect.sAdkManager;
public class MainActivity extends Activity{
// private static final String TAG = "UDOO_AndroidADKFULL";
private static String mAdkManager=null;
private VideoView myVideoView;
private MediaController mediaControls=null;
private int position = 0;
private String ppm_val=null;
private ToggleButton buttonLED;
private TextView distance;
private Button res_nextBtn;
private TextView res_tv;
private AdkReadTask mAdkReadTask;
private int myInt = -10;
private TextView tv;
private FrameLayout current=null;
private Animation slide_down;
private Animation slide_up;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
//hideNavigationBar();
buttonLED = (ToggleButton) findViewById(R.id.toggleButtonLed);
distance = (TextView) findViewById(R.id.textViewIntro);
buttonLED.setVisibility(View.INVISIBLE);
tv = (TextView) findViewById(R.id.ppm_unique);
if (mediaControls == null) {
mediaControls = new MediaController(this);
}
slide_down = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.slide_down);
slide_up = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.slide_up);
res_nextBtn = (Button) findViewById(R.id.result_next_btn);
res_tv = (TextView) findViewById(R.id.result_number_text);
myVideoView = (VideoView) findViewById(R.id.videoView);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
myVideoView.getHolder().setFixedSize(size.x, size.y);
tv.setText(""+size.x+":"+size.y);
final Animation animation1 = new AlphaAnimation(0.0f, 1.0f);
animation1.setDuration(1000);
animation1.setStartOffset(000);
final Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
animation2.setDuration(1000);
animation2.setStartOffset(500);
//animation1 AnimationListener
animation1.setAnimationListener(new Animation.AnimationListener(){
#Override
public void onAnimationEnd(Animation arg0) {
// start animation2 when animation1 ends (continue)
distance.startAnimation(animation2);
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
});
//animation2 AnimationListener
animation2.setAnimationListener(new Animation.AnimationListener(){
#Override
public void onAnimationEnd(Animation arg0) {
// start animation1 when animation2 ends (repeat)
distance.startAnimation(animation1);
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
});
distance.startAnimation(animation1);
try {
myVideoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.sound_758));
} catch (Exception e) {
}
// myVideoView.requestFocus();
//we also set an setOnPreparedListener in order to know when the video file is ready for playback
myVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mediaPlayer) {
// close the progress bar and play the video
//progressDialog.dismiss();
//if we have a position on savedInstanceState, the video playback should start from here
mediaPlayer.setLooping(true);
myVideoView.seekTo(position);
if (position == 0) {
myVideoView.start();
} else {
//if we come from a resumed activity, video playback will be paused
myVideoView.pause();
}
}
});
((MyApplication) this.getApplication()).init(this);
((MyApplication) this.getApplication()).open();
if (mAdkReadTask==null) {
mAdkReadTask = new AdkReadTask();
mAdkReadTask.execute();
}
}
/************************************************************************************************
* *
* OnClickEvents *
* *
************************************************************************************************/
public void BR_onBuyClick(View view) {
next((FrameLayout) findViewById(R.id.flavours_inc_layout));
}
public void Flavours_onBackClick(View v){
next((FrameLayout) findViewById(R.id.br_inc_layout));
}
public void Flavours_onF1Click(View view) {
next((FrameLayout) findViewById(R.id.ty_inc_layout));
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
home();
}
},
5000);
}
public void Flavours_onF2Click(View view) {
next((FrameLayout) findViewById(R.id.ty_inc_layout));
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
home();
}
},
5000);
}
public void Flavours_onF3Click(View view) {
next((FrameLayout) findViewById(R.id.ty_inc_layout));
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
home();
}
},
5000);
}
private void home() {
current.startAnimation(slide_down);
current.setVisibility(View.INVISIBLE);
current=null;
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
distance.startAnimation(slide_up);
distance.setVisibility(View.VISIBLE);
final Animation animation1 = new AlphaAnimation(0.0f, 1.0f);
animation1.setDuration(1000);
animation1.setStartOffset(000);
final Animation animation2 = new AlphaAnimation(1.0f, 0.0f);
animation2.setDuration(1000);
animation2.setStartOffset(500);
//animation1 AnimationListener
animation1.setAnimationListener(new Animation.AnimationListener(){
#Override
public void onAnimationEnd(Animation arg0) {
// start animation2 when animation1 ends (continue)
distance.startAnimation(animation2);
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
});
//animation2 AnimationListener
animation2.setAnimationListener(new Animation.AnimationListener(){
#Override
public void onAnimationEnd(Animation arg0) {
// start animation1 when animation2 ends (repeat)
distance.startAnimation(animation1);
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
});
distance.startAnimation(animation1);
((MyApplication) getApplication()).write("1");
}
},
1000);
}
public void BR_onRecycleClick(View view) {
next((FrameLayout) findViewById(R.id.ready_inc_layout));
}
public void proc_onDoneClick(View v){
next((FrameLayout) findViewById(R.id.delay_inc_layout));
onDelay();
}
public void proc_onCancelClick(View v){
next((FrameLayout) findViewById(R.id.br_inc_layout));
}
private void onDelay() {
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.delay_progressBar);
progressBar.setProgress(0);
progressBar.setVisibility(View.VISIBLE);
ValueAnimator animator = new ValueAnimator();
animator.setObjectValues(0, 100);
animator.setDuration(7000);
final TextView tv = (TextView) findViewById(R.id.delay_textPoints);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
tv.setText("" + animation.getAnimatedValue() +"%");
}
});
animator.addListener(new AnimatorListenerAdapter(){
#Override
public void onAnimationEnd(Animator animator) {
progressBar.setVisibility(View.INVISIBLE);
((MyApplication) getApplication()).write("4");
next((FrameLayout) findViewById(R.id.result_inc_layout));
((MyApplication) getApplication()).write("8");
res_nextBtn.setVisibility(View.INVISIBLE);
}
});
animator.start();
}
public void Res_onNextClick(View v){
next((FrameLayout) findViewById(R.id.points_inc_layout));
onPoints();
}
private void onPoints() {
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.points_progressBar);
progressBar.setProgress(0);
progressBar.setVisibility(View.VISIBLE);
final ValueAnimator animator = new ValueAnimator();
if (myInt>=0) {
animator.setObjectValues(0, (myInt) * 5);
}
else{
animator.setObjectValues(0, 1);
}
animator.setDuration(2000);
final TextView tv = (TextView) findViewById(R.id.points_textPoints);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
tv.setText("" + animation.getAnimatedValue());
}
});
animator.addListener(new AnimatorListenerAdapter(){
#Override
public void onAnimationEnd(Animator animator) {
progressBar.setVisibility(View.INVISIBLE);
}
});
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
animator.start();
}
},
1500);
}
public void pts_onConfirmClick(View v){
next((FrameLayout) findViewById(R.id.end_inc_layout));
((MyApplication) getApplication()).write("3");
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
home();
}
},
5000);
}
public void Ready_onYesClick(View v){
((MyApplication) this.getApplication()).write("2");
next((FrameLayout) findViewById(R.id.processing_inc_layout));
onProcessing();
}
private void onProcessing() {
final int[] i = {0};
final int[] drawablearray = new int[]{R.drawable.processing_butts_3, R.drawable.processing_butts_2, R.drawable.processing_butts_1, R.drawable.processing_butts_0};
final ImageView backgroundImageView = (ImageView) findViewById(R.id.processing_textButts);
backgroundImageView.postDelayed(new Runnable() {
public void run() {
backgroundImageView.setImageResource(drawablearray[i[0]++ % drawablearray.length]);
backgroundImageView.postDelayed(this, 1000);
}
}, 1500);
}
public void Ready_onCancelClick(View v){
next((FrameLayout) findViewById(R.id.br_inc_layout));
}
#Override
public void onResume() {
super.onResume();
((MyApplication) this.getApplication()).write("1");
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
}
private void hideNavigationBar() {
try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
/*
enable = enable navigation bar
disable = disable navigation bar
*/
os.writeBytes("pm enable com.android.systemui\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();
//////////////////////////////////////
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String output="";
/*
* We put the readSerial() method in an AsyncTask to run the
* continuous read task out of the UI main thread
*/
private class AdkReadTask extends AsyncTask<Void, String, String> {
private boolean running = true;
public void pause(){
running = false;
}
public void start(){
running = true;
}
#Override
protected String doInBackground(Void... params) {
while(running) {
if (this.isCancelled())
break;
String s = ((MyApplication) getApplication()).read();
publishProgress(s);
}
return output;
}
#Override
protected void onProgressUpdate(String... progress) {
if(progress[0].charAt(0)=='P') {
/*
TODO: change text+ppm_val to image+text
TODO: send ppm values to server
*/
tv.setText("Air quality: " + progress[0].substring(1, progress[0].length()));
ppm_val = progress[0].substring(1, progress[0].length());
((MyApplication) getApplication()).setPPM(ppm_val);
}
else if (progress[0].charAt(0)=='R'){
/*
TODO: add server verification of RFID
*/
distance.startAnimation(slide_down);
distance.setVisibility(View.GONE);
next((FrameLayout) findViewById(R.id.br_inc_layout));
}
else if (progress[0].charAt(0)=='C'){
/*
TODO: send data to server
*/
res_tv.setText(""+(int) progress[0].charAt(1));
myInt = (int) progress[0].charAt(1);
res_nextBtn.setVisibility(View.VISIBLE);
}
}
#Override
protected void onPostExecute(String result){
}
}
private void next(final FrameLayout fl) {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) fl.getLayoutParams();
if (fl == (FrameLayout) findViewById(R.id.flavours_inc_layout)){
params.height = (int) (size.y*0.6);
}
else{
params.height = (int) (size.y*0.3);
}
params.width = size.x;
int delay_delta = 1000;
// Set it back.
fl.setLayoutParams(params);
if(current!=null){
current.startAnimation(slide_down);
current.setVisibility(View.INVISIBLE);
delay_delta=0;
}
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
fl.startAnimation(slide_up);
fl.setVisibility(View.VISIBLE);
current = fl;
}
},
1200-delay_delta);
}
}
And everything worked fine before I tried changing the slide-up height. After I set up a special case for a layout 0.6*y instead of 0.3*y. The layout is being not displayed above 0.3 mark. It does function, and when I click the supposed button place it displays just before sliding down.
Ok, it was solved by accident. I changed all View.INVISIBLE to View.GONE and it works like swiss watch. I guess there's some black magic involved and I would really appreciate (and accept the answer of course) if someone could explain to me why it works. Thanks.
Cant access the time in AsyncTask, the variable point doesn't change anymore
Here is my code:
import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class GamePlayActivity extends Activity {
ArrayList<Player> arrPlayer = new ArrayList<Player>();
TextView tvLevel, tvPoint;
ImageView ivGuessedImage;
Button btn1stChoice, btn2ndChoice, btn3rdChoice, btn4thChoice;
int level = 1;
int point = 0;
Random rand = new Random(System.currentTimeMillis());
ProgressBar customProgress;
TextView progressDisplay;
int myProgress;
MediaPlayer mp1, mp2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_gameplayactivity);
mp1 = MediaPlayer.create(GamePlayActivity.this, R.raw.uefa_champion_league);
mp2 = MediaPlayer.create(GamePlayActivity.this, R.raw.the_time_of_our_life);
mp1.start();
mp1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp2.start();
}
});
mp2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp1.start();
}
});
tvLevel = (TextView) findViewById(R.id.tvLevel);
tvPoint = (TextView) findViewById(R.id.tvPoint);
ivGuessedImage = (ImageView) findViewById(R.id.ivGuessedImage);
btn1stChoice = (Button) findViewById(R.id.btn1stChoice);
btn2ndChoice = (Button) findViewById(R.id.btn2ndChoice);
btn3rdChoice = (Button) findViewById(R.id.btn3rdChoice);
btn4thChoice = (Button) findViewById(R.id.btn4thChoice);
arrPlayer = createPlayer();
Collections.shuffle(arrPlayer);
int resID = getResources().getIdentifier(arrPlayer.get(0).getPlayerFile(), "drawable", getPackageName());
ivGuessedImage.setImageResource(resID);
btn1stChoice.setText(arrPlayer.get(0).getPlayerName());
btn2ndChoice.setText(arrPlayer.get(1).getPlayerName());
btn3rdChoice.setText(arrPlayer.get(2).getPlayerName());
btn4thChoice.setText(arrPlayer.get(3).getPlayerName());
customProgress = (ProgressBar)findViewById(R.id.customProgress);
progressDisplay = (TextView)findViewById(R.id.progressDisplay);
new ShowCustomProgressBarAsyncTask().execute();
if(myProgress < 1){
Intent intent = new Intent(GamePlayActivity.this, GameOverActivity.class);
startActivity(intent);
}
btn1stChoice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (btn1stChoice.getText().toString() == arrPlayer.get(0).getPlayerName()) {
final MediaPlayer mp = MediaPlayer.create(GamePlayActivity.this, R.raw.right_answer);
mp.start();
point = point + 2;
tvPoint.setText(point + " Point");
createNewLevel();
myProgress = 100;
} else {
final MediaPlayer mp = MediaPlayer.create(GamePlayActivity.this, R.raw.wrong_answer);
mp.start();
Intent intent = new Intent(GamePlayActivity.this, GameOverActivity.class);
intent.putExtra("Point", point);
startActivity(intent);
}
}
});
btn2ndChoice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(btn2ndChoice.getText().toString() == arrPlayer.get(0).getPlayerName()){
final MediaPlayer mp = MediaPlayer.create(GamePlayActivity.this, R.raw.right_answer);
mp.start();
point = point + 2;
tvPoint.setText(point + " Point");
createNewLevel();
myProgress = 100;
}
else{
final MediaPlayer mp = MediaPlayer.create(GamePlayActivity.this, R.raw.wrong_answer);
mp.start();
Intent intent = new Intent(GamePlayActivity.this, GameOverActivity.class);
intent.putExtra("Point", point);
startActivity(intent);
}
}
});
btn3rdChoice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(btn3rdChoice.getText().toString() == arrPlayer.get(0).getPlayerName()){
final MediaPlayer mp = MediaPlayer.create(GamePlayActivity.this, R.raw.right_answer);
mp.start();
point = point + 2;
tvPoint.setText(point + " Point");
createNewLevel();
myProgress = 100;
}
else{
final MediaPlayer mp = MediaPlayer.create(GamePlayActivity.this, R.raw.wrong_answer);
mp.start();
Intent intent = new Intent(GamePlayActivity.this, GameOverActivity.class);
intent.putExtra("Point", point);
startActivity(intent);
}
}
});
btn4thChoice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(btn4thChoice.getText().toString() == arrPlayer.get(0).getPlayerName()){
final MediaPlayer mp = MediaPlayer.create(GamePlayActivity.this, R.raw.right_answer);
mp.start();
point = point + 2;
tvPoint.setText(point + " Point");
createNewLevel();
myProgress = 100;
}
else{
final MediaPlayer mp = MediaPlayer.create(GamePlayActivity.this, R.raw.wrong_answer);
mp.start();
Intent intent = new Intent(GamePlayActivity.this, GameOverActivity.class);
intent.putExtra("Point", point);
startActivity(intent);
}
}
});
}
public class ShowCustomProgressBarAsyncTask extends AsyncTask<Void, Integer, Void> {
#Override
protected void onPreExecute() {
myProgress = 100;
}
#Override
protected Void doInBackground(Void... params) {
while(myProgress>0){
myProgress--;
publishProgress(myProgress);
SystemClock.sleep(200);
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
customProgress.setProgress(values[0]);
customProgress.setSecondaryProgress(values[0] + 1);
progressDisplay.setText(String.valueOf(myProgress)+"%");
}
#Override
protected void onPostExecute(Void result) {
}
}
public void createNewLevel(){
arrPlayer.remove(0);
Collections.shuffle(arrPlayer);
int randomButtonChoice = rand.nextInt(4);
int resID = getResources().getIdentifier(arrPlayer.get(0).getPlayerFile(), "drawable", getPackageName());
((BitmapDrawable)ivGuessedImage.getDrawable()).getBitmap().recycle();
ivGuessedImage.setImageResource(resID);
switch (randomButtonChoice){
case 0: {
btn1stChoice.setText(arrPlayer.get(0).getPlayerName());
btn2ndChoice.setText(arrPlayer.get(1).getPlayerName());
btn3rdChoice.setText(arrPlayer.get(2).getPlayerName());
btn4thChoice.setText(arrPlayer.get(3).getPlayerName());
break;
}
case 1: {
btn1stChoice.setText(arrPlayer.get(1).getPlayerName());
btn2ndChoice.setText(arrPlayer.get(0).getPlayerName());
btn3rdChoice.setText(arrPlayer.get(2).getPlayerName());
btn4thChoice.setText(arrPlayer.get(3).getPlayerName());
break;
}
case 2: {
btn1stChoice.setText(arrPlayer.get(1).getPlayerName());
btn2ndChoice.setText(arrPlayer.get(2).getPlayerName());
btn3rdChoice.setText(arrPlayer.get(0).getPlayerName());
btn4thChoice.setText(arrPlayer.get(3).getPlayerName());
break;
}
case 3: {
btn1stChoice.setText(arrPlayer.get(1).getPlayerName());
btn2ndChoice.setText(arrPlayer.get(2).getPlayerName());
btn3rdChoice.setText(arrPlayer.get(3).getPlayerName());
btn4thChoice.setText(arrPlayer.get(0).getPlayerName());
break;
}
}
level++;
tvLevel.setText("Level " + level);
}
}
}
You could do that with an interface
create an interface in your AsyncTask, and create a method which will be used as the callback
public class ShowCustomProgressBarAsyncTask extends AsyncTask<Void, Integer, Void> {
interface ProgressListner {
public void onProgressChanged(int progress);
}
private ProgressListner listner;
public ShowCustomProgressBarAsyncTask(ProgressListner listner) {
this.listner = listner;
}
//..your remaining codes
#Override
protected void onProgressUpdate(Integer... values) {
//..your remaining codes
listner.onProgressChanged(values[0]);
}
}
Then implement that interface in your activity.
Also pass an instance of the interface through the constructor to the AsyncTask.
Then using that instance you can callback a method which will pass the progress value
public class GamePlayActivity extends Activity implements ProgressListner{
//.. your remaining codes
new ShowCustomProgressBarAsyncTask(this).execute();
public void onProgressChanged(int progress) {
a = progress;
}
}
I am very new to Android development and have been trying to make a simple interest calculator. It uses a SeekBar to take the number of years input. The App crashes as I click the Calculate Button.
I am using Eclipse and trying to run the app directly on the device without any emulator.
package com.sevendaytutorials.interestcalculator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener, OnSeekBarChangeListener{
private EditText principal_amount;
private EditText rate;
private SeekBar seekbar;
private TextView seekBarValue;
private Button calculate;
private TextView result;
private String Principal, Rate;
private int number_of_years;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
principal_amount = (EditText)findViewById(R.id.principal_amount);
Principal = principal_amount.getText().toString();
rate = (EditText)findViewById(R.id.interest_rate);
Rate = rate.getText().toString();
seekbar = (SeekBar)findViewById(R.id.seekBar1);
seekbar.setOnSeekBarChangeListener(this);
seekBarValue = (TextView) findViewById(R.id.number_of_years);
calculate = (Button) findViewById(R.id.calculate_button);
calculate.setOnClickListener(this);
result = (TextView) findViewById(R.id.result_textview);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v == calculate) {
Calculate();
}
}
private void Calculate() {
// TODO Auto-generated method stub
double p = Double.parseDouble(Principal);
double R = Double.parseDouble(Rate);
double r = R/100.0;
double A = p*(1+r*number_of_years);
double I = A - p;
result.setText("The amount of interest after " +
Integer.toString(number_of_years)+" year(s) would be " + Double.toString(I));
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
seekBarValue.setText(Integer.toString(progress));
number_of_years = progress;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
in your onCreate(), you did these-
Principal = principal_amount.getText().toString();
and
Rate = rate.getText().toString();
Now both of your values are null as nothing are typed during onCreate()
Now when are you calling Calculate(), you are doing these-
double p = Double.parseDouble(Principal);
double R = Double.parseDouble(Rate);
as we can see, you didn't assign any proper value to Principal & Rate yet anywhere, so you should get Exception at these lines. you should modify to-
private void Calculate() {
// TODO Auto-generated method stub
Principal = principal_amount.getText().toString();
Rate = rate.getText().toString();
if (Principal == null || Principal.isEmpty() || Rate == null || Rate .isEmpty())
{
// user are yet to fill the edittext, validation error
}else{
double p = Double.parseDouble(Principal);
double R = Double.parseDouble(Rate);
double r = R/100.0;
double A = p*(1+r*number_of_years);
double I = A - p;
result.setText("The amount of interest after " +
Integer.toString(number_of_years)+" year(s) would be " + Double.toString(I));
}
}
Local variables
SeekBar seek1, seek2, seek3;
float amount, rate, time, interest, total;
TextView tv1, tv2, tv3, tv4, tv5;
Button calculate;
String val, val1, val2, inter, totall;
In onCreate() find ids
seekBar1 = findViewById(R.id.seek1);
seekBar2 = findViewById(R.id.seek2);
seekBar3 = findViewById(R.id.seek3);
calculate = findViewById(R.id.calculate);
tvAmount = findViewById(R.id.tv1);
tvRate = findViewById(R.id.tv2);
tvtime = findViewById(R.id.tv3);
tvEMI = findViewById(R.id.tv4);
tvInterest = findViewById(R.id.tv5);
Apply setOnClickListener() on Button
calculate.setOnClickListener(this);
Apply setOnSeekBarChangeListener() using anonymous class and implement
all methods
seek1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
{
Get Value of SeekBar in String Variable and set on text view.
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
val = String.valueOf(1000 + i * 1000);
tv1.setText(val);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
});
seek2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
{
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
val1 = String.valueOf(5 + i * .5);
tv2.setText(val1);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
});
seek3.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
{
}
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
val2 = String.valueOf(i);
tv3.setText(val2);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
});
Set maximum limit of Seek Bars
seek1.setMax(99);
seek2.setMax(30);
seek3.setMax(100);
Implement onClick() for button click Action
#Override
public void onClick(View view)
{
calInterest();
tv4.setText(": ₹"+inter);
tv5.setText(": ₹"+totall);
}
Create a method for calculation calInterest() which is called at time
of button Click see onClick()
public void calInterest()
{
amount = Float.parseFloat(val);
rate = Float.parseFloat(val1);
time = Float.parseFloat(val2);
interest = (amount * rate * (time / 12))/100;
total =interest+amount;
inter = String.valueOf(interest);
totall = String.valueOf(total);
}
I have I think simple problem which I can't fix on my own. In the code below I need to set the loudBars variable to the other class. I made the setLoudBars() but it just doesn't work. Anyone sees any solution in this?
public class DrumActivity extends Activity {
private final short minBpm = 40;
private final short maxBpm = 208;
private short bpm = 100;
private short noteValue = 4;
private short beats = 4;
private short volume;
private short initialVolume;
private double beatSound = 2440;
private double sound = 6440;
private AudioManager audio;
private MetronomeAsyncTask metroTask;
private Button plusButton;
private Button minusButton;
private TextView currentBeat;
private Handler mHandler;
private int loudBars = 2;
private short silentBars = 1;
// have in mind that: http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler
// in this case we should be fine as no delayed messages are queued
private Handler getHandler() {
return new Handler() {
#Override
public void handleMessage(Message msg) {
String message = (String)msg.obj;
if(message.equals("1")) {
currentBeat.setTextColor(Color.GREEN);
}else {
currentBeat.setTextColor(getResources().getColor(R.color.yellow));
}
currentBeat.setText(message);
}
};
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drum);
metroTask = new MetronomeAsyncTask();
/* Set values and listeners to buttons and stuff */
TextView eLoudBars = (TextView) findViewById(R.id.eLoudBars);
eLoudBars.setText(""+loudBars);
TextView eSilentBars = (TextView) findViewById(R.id.eSilentBars);
Button minusLoud = (Button) findViewById(R.id.lbminus);
minusLoud.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loudBars--;
if(loudBars < 1)
loudBars = 1;
TextView eLoudBars = (TextView) findViewById(R.id.eLoudBars);
eLoudBars.setText(""+loudBars);
metroTask.setLoudBars(loudBars);
}
});
Button plusLoud = (Button) findViewById(R.id.lbplus);
plusLoud.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loudBars++;
TextView eLoudBars = (TextView) findViewById(R.id.eLoudBars);
eLoudBars.setText(""+loudBars);
metroTask.setLoudBars(loudBars);
}
});
Button minusSilent = (Button) findViewById(R.id.sbminus);
Button plusSilent = (Button) findViewById(R.id.sbplus);
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
TextView timeSignatureText = (TextView) findViewById(R.id.timesignature);
timeSignatureText.setText(""+beats+"/"+noteValue);
plusButton = (Button) findViewById(R.id.plus);
plusButton.setOnLongClickListener(plusListener);
minusButton = (Button) findViewById(R.id.minus);
minusButton.setOnLongClickListener(minusListener);
currentBeat = (TextView) findViewById(R.id.currentBeat);
currentBeat.setTextColor(Color.GREEN);
Spinner beatSpinner = (Spinner) findViewById(R.id.beatspinner);
ArrayAdapter<Beats> arrayBeats =
new ArrayAdapter<Beats>(this,
android.R.layout.simple_spinner_item, Beats.values());
beatSpinner.setAdapter(arrayBeats);
beatSpinner.setSelection(Beats.four.ordinal());
arrayBeats.setDropDownViewResource(R.layout.spinner_dropdown);
beatSpinner.setOnItemSelectedListener(beatsSpinnerListener);
Spinner noteValuesdSpinner = (Spinner) findViewById(R.id.notespinner);
ArrayAdapter<NoteValues> noteValues =
new ArrayAdapter<NoteValues>(this,
android.R.layout.simple_spinner_item, NoteValues.values());
noteValuesdSpinner.setAdapter(noteValues);
noteValues.setDropDownViewResource(R.layout.spinner_dropdown);
noteValuesdSpinner.setOnItemSelectedListener(noteValueSpinnerListener);
audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
initialVolume = (short) audio.getStreamVolume(AudioManager.STREAM_MUSIC);
volume = initialVolume;
SeekBar volumebar = (SeekBar) findViewById(R.id.volumebar);
volumebar.setMax(audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
volumebar.setProgress(volume);
volumebar.setOnSeekBarChangeListener(volumeListener);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public synchronized void onStartStopClick(View view) {
Button button = (Button) view;
String buttonText = button.getText().toString();
if(buttonText.equalsIgnoreCase("start")) {
button.setText(R.string.stop);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
metroTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
else
metroTask.execute();
} else {
button.setText(R.string.start);
metroTask.stop();
metroTask = new MetronomeAsyncTask();
Runtime.getRuntime().gc();
}
}
private void maxBpmGuard() {
if(bpm >= maxBpm) {
plusButton.setEnabled(false);
plusButton.setPressed(false);
} else if(!minusButton.isEnabled() && bpm>minBpm) {
minusButton.setEnabled(true);
}
}
public void onPlusClick(View view) {
bpm++;
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
metroTask.setBpm(bpm);
maxBpmGuard();
}
private OnLongClickListener plusListener = new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
bpm+=20;
if(bpm >= maxBpm)
bpm = maxBpm;
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
metroTask.setBpm(bpm);
maxBpmGuard();
return true;
}
};
private void minBpmGuard() {
if(bpm <= minBpm) {
minusButton.setEnabled(false);
minusButton.setPressed(false);
} else if(!plusButton.isEnabled() && bpm<maxBpm) {
plusButton.setEnabled(true);
}
}
public void onMinusClick(View view) {
bpm--;
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
metroTask.setBpm(bpm);
minBpmGuard();
}
private OnLongClickListener minusListener = new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
bpm-=20;
if(bpm <= minBpm)
bpm = minBpm;
TextView bpmText = (TextView) findViewById(R.id.bps);
bpmText.setText(""+bpm);
metroTask.setBpm(bpm);
minBpmGuard();
return true;
}
};
private OnSeekBarChangeListener volumeListener = new OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
volume = (short) progress;
audio.setStreamVolume(AudioManager.STREAM_MUSIC, progress, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
};
private OnItemSelectedListener beatsSpinnerListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Beats beat = (Beats) arg0.getItemAtPosition(arg2);
TextView timeSignature = (TextView) findViewById(R.id.timesignature);
timeSignature.setText(""+beat+"/"+noteValue);
metroTask.setBeat(beat.getNum());
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
private OnItemSelectedListener noteValueSpinnerListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
NoteValues noteValue = (NoteValues) arg0.getItemAtPosition(arg2);
TextView timeSignature = (TextView) findViewById(R.id.timesignature);
timeSignature.setText(""+beats+"/"+noteValue);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
#Override
public boolean onKeyUp(int keycode, KeyEvent e) {
SeekBar volumebar = (SeekBar) findViewById(R.id.volumebar);
volume = (short) audio.getStreamVolume(AudioManager.STREAM_MUSIC);
switch(keycode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
volumebar.setProgress(volume);
break;
}
return super.onKeyUp(keycode, e);
}
public void onBackPressed() {
metroTask.stop();
// metroTask = new MetronomeAsyncTask();
Runtime.getRuntime().gc();
audio.setStreamVolume(AudioManager.STREAM_MUSIC, initialVolume, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
finish();
}
private class MetronomeAsyncTask extends AsyncTask<Void,Void,String> {
Metronome metronome;
MetronomeAsyncTask() {
mHandler = getHandler();
metronome = new Metronome(mHandler);
}
protected String doInBackground(Void... params) {
metronome.setBeat(beats);
metronome.setNoteValue(noteValue);
metronome.setBpm(bpm);
metronome.setBeatSound(beatSound);
metronome.setSound(sound);
metronome.setLoudBars(loudBars);
metronome.play();
return null;
}
public void stop() {
metronome.stop();
metronome = null;
}
public void setBpm(short bpm) {
metronome.setBpm(bpm);
metronome.calcSilence();
}
public void setBeat(short beat) {
if(metronome != null)
metronome.setBeat(beat);
}
public void setLoudBars(int loudBars) {
if(metronome != null)
metronome.setLoudBars(loudBars);
}
}
}