Updating android ui with timer - java

i am new to android programming, i searched through all the answers about this topic but still i am not able to implement what i want to do. My problem is: i want to update the picture at imageview with another picture in given periods. The imageview is needed to be updated with different pictures every time, total of 15-20 times. Here is what i have done so far but it is not working at all.
public class IlkMasal extends Activity {
MediaPlayer sound;
private Handler m_handler;
private ImageView image;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.firsttale);
m_handler = new Handler();
Button menu = (Button)findViewById(R.id.Button01);
Button startbutton = (Button)findViewById(R.id.button1);
sound = MediaPlayer.create(this, R.raw.music4);
sound.start();
image = (ImageView)findViewById(R.id.imageView1);
image.setImageResource(R.drawable.picture2);
startbutton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
m_handler.removeCallbacks(m_statusChecker);
m_handler.postDelayed(m_statusChecker, 2000);
}
});
menu.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent main= new Intent("android.intent.action.MAIN");
startActivity(main);
}
});
}
Runnable m_statusChecker = new Runnable()
{
public void run(){
image.setImageResource(R.drawable.picture3);
m_handler.removeCallbacks(m_statusChecker);
m_handler.postDelayed(m_statusChecker, 2000);
}
};
}
After i click startbutton i want to update the ui with different pictures every time. I will appreciate your help.

Yo can set this runnable to run on your onClic and you will still need a method to get the next picture you want to show.
final int delay = 5000;
final int period = 1000;
final Runnable r = new Runnable() {
public void run() {
image.setImageResource(getNextPicture());
postDelayed(this, period);
}
};
postDelayed(r, delay);
Regards.

use runOnUiThread for Updating UI Elements from NON Ui Thread as:
Current_Activity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
image.setImageResource(R.drawable.picture3); //Update UI elements here
}
});

Related

Countdown with individual Sound

I have a problem with my countdown and I want to play an individual sound at the end. For this I have created a list. When the corresponding picture is clicked, the selection should be saved and played in this method:
private void loadMusic() {
if (timerStatus == TimerStatus.PAUSED)
new Runnable() {
#Override
public void run() {
playSound(R.raw.sound1);
}
public void playSound(int sound1) {
MediaPlayer mp = MediaPlayer.create(getBaseContext(), (R.raw.sound2));
mp.start();
}
}.run()
}
I tried to solve this with an array in the onCreate method, but this is "void" and therefore I don't get a return:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layout.sound);
final int[] selection = new int[1];
imageButton1 = findViewById(id.iv_bowl1);
imageButton1.setOnClickListener(v -> {
selection[0] = 1;
Toast.makeText(Sound.this, "1-click", Toast.LENGTH_SHORT).show();
});
return selection[0];
}
Thanks for help.

Start loop and stop code with single button click

I want to make a simple button which will start to loop a function every period of time which I can set. But not only it will start the loop, but also stop the loop if I click the button again. Is there anyway I can achieve this with a single button?
Here's how I'd do it
public class MainActivity extends AppCompatActivity {
private Button btn;
private View.OnClickListener runOnClickListener;
private View.OnClickListener stopOnClickListener;
void init() {
Handler handler = new Handler();
int duration = 5000;
Runnable runnable = new Runnable() {
#Override
public void run() {
foo();
handler.postDelayed(this, duration);
}
};
runOnClickListener = view -> {
runnable.run();
btn.setOnClickListener(stopOnClickListener);
};
stopOnClickListener = view -> {
handler.removeCallbacks(runnable);
btn.setOnClickListener(runOnClickListener);
};
btn.setOnClickListener(runOnClickListener);
}
void foo() {
Log.i("foo", "foo");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.btn);
init();
}
}
Yeah, give you a simple example.
First, create two constant values and one instance variable:
//indicate whether or not the loop is running
private boolean isRunning = false;
//used for handler to send empty msg
private final static int MSG_LOOP = 1;
private final static long LOOP_INTERVAL = 5000;
Then create a Handler instance to handle the loop logic:
Handler handler = new Handler() {
#Override
public void handleMessage(#NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MSG_LOOP:
doStuff();
break;
}
}
};
private void doStuff() {
//after what you want to do is done, send another MSG_LOOP msg with delay
handler.sendEmptyMessageDelayed(MSG_LOOP, LOOP_INTERVAL);
}
And finally:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isRunning) {
//cancel if any in the message queue
handler.removeMessages(MSG_LOOP);
} else {
//if you do not want to start the loop immediately, then use: "sendEmptyMessageDelayed"
handler.sendEmptyMessage(MSG_LOOP);
}
}
});

Generate Sound and Record Audio parallely using Threads

So basically, I am making an application which at the touch of a button generates a sound for 1 second after every 10 seconds and simultaneously records all other sounds as well.
I want the sound recording to happen in that 10 second pause. I tried to use threads and thread interrupts for this. But don't really know how to use them properly for this case.
Here is my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playButton = (Button)findViewById(R.id.button);
textView = (TextView) findViewById(R.id.textView);
playButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Sound Gen Thread
Runnable myRunnable = new Runnable() {
#Override
public void run() {
new Timer().scheduleAtFixedRate(new TimerTask() {
public void run() {
AudioTrack tone = generateTone(freq, 1000);
tone.play();
}
}, 0, 10000);
}
};
new Thread(myRunnable).start();
//Recording Thread
Runnable myRunnable1 = new Runnable() {
#Override
public void run() {
doInBackground();
}
};
new Thread(myRunnable1).start();
}
});
}

TextView not showing text in a particular listener

I am trying to have a textview display a message for 5 seconds and then disappear.
public class MainActivity extends AppCompatActivity {
public Date start;
public Date end;
Handler handle = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startButton = (Button) findViewById(R.id.startButton);
Button endButton = (Button) findViewById(R.id.stopButton);
// other variables
final TextView errTextView = (TextView) findViewById(R.id.errorTextView);
final DateFormat df = new SimpleDateFormat("MM/dd/yy");
final Thread t = new Thread(new Runnable() {
#Override
public void run() {
//call function in MainActivity class
handle.postDelayed(this, 100);
}
});
final Thread errt = new Thread(new Runnable() {
#Override
public void run() {
errTextView.setText("");
}
});
startButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if (start != null)
errTextView.setText("Timer Reset");
handler.postDelayed(errt, 5000);
start = new Date();
dateEditText.setText(df.format(start));
hoursEditText.setText("");
errTextView.setText("");
handle.post(t);
}
});
endButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
if (start == null) {
errTextView.setText("Timer must be started before pressing Stop. Press Start.");
}
else {
start = null;
}
if(handle != null)
handle.removeCallbacksAndMessages(null);
}
});
If the user presses the start button, start will get the current time and save it. So, if the user presses the start button again, the start button should not be null. If the user presses the twice, the condition should hold, errTextView should display "Timer reset", and the handler should tell the main thread to set errTextView = "" after 5 seconds. errTextView properly shows text in the stop button listener, but not in the start listener.
You call
errTextView.setText("");
Every time startButton is pressed immediately. Therefore errTextView will always be empty once startButton is clicked

Why I can't start a thread 2x in my Activity?

I push a web service call in my activity to a thread (shown below). The first time I do this in the activity it works fine (gets the text from my edittext and loads the service to get lat/lng data)
But when I click the back button (emulator) and try to fire off this thread a second time it blows up after the .start(); in my click handler. What might I be doing wrong here? thanks
private Thread getLocationByZip = new Thread() {
public void run() {
try {
EditText filterText = (EditText) findViewById(R.id.zipcode);
Editable zip = filterText.getText();
LocationLookupService locationLookupService = new LocationLookupService();
selectedLocation = locationLookupService.getLocationByZip(zip.toString());
locationHandler.post(launchFindWithLocationInfo);
} catch (Exception e) {
}
}
};
private Runnable launchFindWithLocationInfo = new Runnable() {
#Override
public void run() {
try {
Intent abc = new Intent(LocationLookup.this, FindWithLocation.class);
startActivity(abc);
} catch (Exception e) {
}
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.location);
locationHandler = new Handler();
findViewById(R.id.findbyzip).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getLocationByZip.start();
}
});
}
Update
After the great advice I went with an AsyncTask so if anyone finds this going forward the above thread/handler model looks something like the below as an asynctask
private class LocationLookupTask extends AsyncTask<String, Void, Location> {
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
this.dialog = ProgressDialog.show(LocationLookup.this, "", "Loading...");
}
#Override
protected Location doInBackground(String... zips) {
Location selectedLocation = null;
for (String zip : zips) {
LocationLookupService locationLookupService = new LocationLookupService();
selectedLocation = locationLookupService.getLocationByZip(zip);
}
return selectedLocation;
}
#Override
protected void onPostExecute(Location location) {
this.dialog.dismiss();
((AppDelegate) getApplicationContext()).setSelectedLocation(location);
Intent abc = new Intent(LocationLookup.this, FindWithLocation.class);
startActivity(abc);
}
}
Now to call this in the onclick you would do this
findViewById(R.id.findbyzip).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
EditText filterText = (EditText) findViewById(R.id.zipcode);
Editable zip = filterText.getText();
LocationLookupTask task = new LocationLookupTask();
task.execute(new String[]{zip.toString()});
}
});
You can't start a thread twice:
It is never legal to start a thread more than once.
Taken from Thread.start().
So, you need to create a new thread and start that one.
You can not call twice the start method of the Thread class, I suggest you also control the logic within the method onCreate since according to the life cycle of an Activity that method may be called by Android lifecycle Activity Manager.
Furthermore i suggest you to avoid this approach and consider to use the AsyncTask provided by the Android SDK.
http://developer.android.com/reference/android/os/AsyncTask.html
If you really want to do this without creating a new class or using AsyncTask, you could just make a method to get a new Thread on each call:
private Thread getLocationByZip;
private void getLocation() {
getLocationByZip = new Thread() {
public void run() {
try {
EditText filterText = (EditText) findViewById(R.id.zipcode);
Editable zip = filterText.getText();
LocationLookupService locationLookupService = new LocationLookupService();
selectedLocation = locationLookupService.getLocationByZip(zip.toString());
locationHandler.post(launchFindWithLocationInfo);
} catch (Exception e) {
}
}
};
getLocationByZip.start();
}
Then replace getLocationByZip.start() in your code with getLocation(). However, I agree that an AsyncTask would be a better way to go, though this would work for you.

Categories