I want write value from SeekBar to log in new Thread. I want press button and start write logs. and change seekBar value and write it in log.
public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener, View.OnTouchListener {
private SeekBar seekBar;
private Button button;
private TextView textView;
private EditText editText;
private Thread thread;
private int value = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar = (SeekBar) findViewById(R.id.seekBar);
button = (Button) findViewById(R.id.button);
textView = (TextView) findViewById(R.id.textView);
editText = (EditText) findViewById(R.id.editText);
seekBar.setOnSeekBarChangeListener(this);
button.setOnTouchListener(this);
print();
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
value = progress;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
print();
Toast.makeText(MainActivity.this, "ACTION_DOWN", Toast.LENGTH_SHORT).show();
return true; // if you want to handle the touch event
case MotionEvent.ACTION_UP:
thread.stop();
Toast.makeText(MainActivity.this, "ACTION_UP", Toast.LENGTH_SHORT).show();
return true; // if you want to handle the touch event
}
return false;
}
public void print() {
Runnable runnable = new Runnable() {
#Override
public void run() {
Log.d("MyLog", String.valueOf(value));
}
};
thread = new Thread(runnable);
thread.start();
}
}
but my log write once. How can I write log every second?
You could do something like this:
Handler handler = new Handler();
boolean stop = false;
Runnable runnable = new Runnable() {
#Override
public void run() {
Log.d("MyLog", String.valueOf(value));
if (!stop) {
handler.postDelayed(this, 1000);
}
}
};
// start logging by calling this method
public void print() {
handler.post(runnable);
}
// stop logging by calling this method
public void printStop() {
stop = true;
}
It works for me:
new Thread(new Runnable() {
#Override
public void run() {
while(true) {
//do whatever you want
try {
Thread.sleep(1000); //sleep time in milliseconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
Related
I was working in a very simple music player with a seek bar. But I got a problem with playing music,it doesn't work correctly every second - it backwards a while, then remain again like it's a buggy.
I know why but I can't solve it.
When the progress bar moves forward, the music recalibrates and vice versa, when the music moves forward, the progress bar recalibrates.
It's probably because of that that every time it goes back.
But I tried several things and still have the same problem.
Another problem is that when the music is paused, the progress bar goes in the opposite direction until it reaches zero. It doesn't stay where it was before the break.
The full code :
public class MainActivity extends AppCompatActivity {
private MediaPlayer mediaPlayer;
private SeekBar seekBar;
private boolean bool = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.seekBar = (SeekBar) findViewById(R.id.sound_bar);
this.mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.music);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition() * seekBar.getMax() / mediaPlayer.getDuration());
}
}, 500, 500);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mediaPlayer.seekTo(seekBar.getProgress() * mediaPlayer.getDuration() / seekBar.getMax());
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public void playSound(View view) {
Button button = (Button) view;
if(bool) {
mediaPlayer.pause();
bool = false;
button.setText("Jouer le son");
} else {
mediaPlayer.start();
bool = true;
button.setText("Mettre en pause");
}
}
#Override
protected void onPause() {
super.onPause();
mediaPlayer.pause();
}
#Override
protected void onStart() {
super.onStart();
if(bool) {
mediaPlayer.start();
}
}
}
Maybe use another thread to control the seekbar would help.
Take a look at this
I want the countdowntimer to be on a separate thread and for it to update the UI on each tick. Every time I click start the app just closes and I get the 'app has stopped' error message.
public class Activity_MultiplayerGame extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity__multiplayer_game);
}
public void btnStart_onClick(View view){
CountDownTimer timer = new CountDownTimer(15000, 1000){
#Override
public void onTick(final long millisUntilFinished) {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView countdownText = (TextView) findViewById(R.id.countdown);
Integer timeUntilFinished = (int) millisUntilFinished/1000;
countdownText.setText(timeUntilFinished);
}
});
}
#Override
public void onFinish() {
TextView countdownText = (TextView) findViewById(R.id.countdown);
countdownText.setText("Finished");
}
};
timer.start();
}
}
I've made the assumption that creating a CountDownTimer gives it its own thread?
you can use Handler. I wrote a sample for you
this code increase a counter every one second and show and update counter value on a textView.
public class MainActivity extends Activity {
private Handler handler = new Handler();
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text);
startTimer();
}
int i = 0;
Runnable runnable = new Runnable() {
#Override
public void run() {
i++;
textView.setText("counter:" + i);
startTimer();
}
};
public void startTimer() {
handler.postDelayed(runnable, 1000);
}
public void cancelTimer() {
handler.removeCallbacks(runnable);
}
#Override
protected void onStop() {
super.onStop();
cancelTimer();
}
}
You cannot update UI from other thread than main (ui) thread on android. There are many ways to approach the problem, but I suppose you should start with AsyncTask if you really need another thread. Check doInBackround and onProgressUpdate methods.
If you don't need other thread (and if this is only about the counter you dont') you can check Handler class and postAtTime(Runnable, long), postDelayed(Runnable, long) methods. Or you can make subclass of Handler class and use combination of sendMessageDelayed(android.os.Message, long) and overridden handleMessage().
Here's your problem:
countdownText.setText(timeUntilFinished);
You have passed integer to setText(int) method, which actually takes the string resource id rather than the integer to be displayed. You should use the method setText(String).
Try this:
countdownText.setText(String.valueOf(timeUntilFinished));
This code also work it decrease counter(or increase whatever you want) and show in text view you can also stop or reset counter via click the same button.
public class MainActivity extends AppCompatActivity {
TextView textView;
Button count;
boolean timelapseRunning = true;
int NUM_OF_COUNT=15;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textview);
count=(Button)findViewById(R.id.count);
runTimer();
}
public void onclick(View view){
if (!timelapseRunning) {
timelapseRunning=true;
} else {
timelapseRunning = false;
}
if(NUM_OF_COUNT==0){
NUM_OF_COUNT=15;
}
}
private void runTimer() {
final Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
textView.setText(""+NUM_OF_COUNT);
if (!timelapseRunning && NUM_OF_COUNT>0) {
NUM_OF_COUNT--;
}
handler.postDelayed(this, 1000);
}
});
}
}
The CountDownTimer gives out callbacks on the same thread, in which it was created. So the runOnUiThread in onTick is absolutely not required if the CountDownTimer constructor was called on UI thread.
Also,
TextView countdownText = (TextView) findViewById(R.id.countdown);
being called in onTick method is poor design, as findViewById method consumes considerable processing power.
Finally the actual problem as Nabin Bhandari pointed out is the integer value passed to setText method. You need to wrap it to string.
This code is enough
final TextView countdownText = (TextView) findViewById(R.id.countdown);
CountDownTimer timer = new CountDownTimer(15000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
countdownText.setText(String.valueOf(millisUntilFinished/1000));
}
#Override
public void onFinish() {
countdownText.setText("Finished");
}
};
timer.start();
How to automatically Click a Button in Android after a 5 second delay
I tried with the codes that are entered in the link but my application has crashed
My codes;
public class MainActivity extends AppCompatActivity {
Button button;
TextView text;
#Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonClick();
Thread timer = new Thread() {
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
button.performClick();
}
}
};
timer.start();
} catch (Resources.NotFoundException e) {
e.printStackTrace();
}
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
button.performClick();
}
}, 1000);
}
public void buttonClick() {
button=(Button) findViewById(R.id.button);
text=(TextView) findViewById(R.id.text);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Random s=new Random();
int number=s.nextInt(3);
switch (number)
{case 1:text.setText("1");
break;
case 2: text.setText("2");
break;
}
}
});
}
}
Logcat Error
You need to use
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
to avoid this error.
Please check Android "Only the original thread that created a view hierarchy can touch its views."
Also you can just use the Handler to perform the button click after a specified amount of time, no need to use the timer.
This is more simpler method to run every second. you dont need to trigger the button. just call the method you want to execute
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Handler handler = new Handler();
Runnable runnable = new Runnable(){
#Override
public void run() {
buttonClick();
if(handler!=null)
handler.postDelayed(runnable, 1000);
}
}
handler.postDelayed(runnable, 1000);
}
good afternoon I have two classes, one that implement one progressBar this class I intend to create a public method that will run startActivity(). the main class would have a button that would call the method. However this giving error null reference.
ProgressBarUtil:
public class ProgressBarUtil extends BaseActionBarActivity {
private ProgressBar progressBar;
private Handler handler;
private int progress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress_bar_util);
inicializaComponentes();
}
public void inicializaComponentes() {
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setIndeterminate(true);
handler = new Handler();
executaProgressbar();
}
public void startProgressBar(){
startActivity(new Intent(getBaseContext(),ProgressBarUtil.class));
}
private void executaProgressbar() {
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
finish();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
class that will call the method starProgressBar
The other class
#Override
public void onClick(View view) {
int id = view.getId();
if (btnDownload.getId() == id){
new ProgressBarUtil().startProgressBar();
}
}
been working on a prject for a while, now I want it so that when the user touches the screen it changes the color of the textView(DigitalClock). I'm a bit of a noob when it comes to java so I really need a fully working example if possible? Here's my code so far:
public class MainActivity extends Activity {
private static final Random RANDOM = new Random();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
Handler handler = new RandomMoveHandler((TextView) findViewById(R.id.digitalClock1));
handler.sendEmptyMessage(0);
}
private static class RandomMoveHandler extends Handler {
private final WeakReference<TextView> textViewWeakReference;
private RandomMoveHandler(TextView textView) {
this.textViewWeakReference = new WeakReference<TextView>(textView);
}
#Override
public void handleMessage(Message msg) {
TextView textView = textViewWeakReference.get();
if (textView == null) {
Log.i(TAG, "WeakReference is gone so giving up.");
return;
}
int x = RANDOM.nextInt(670 - 100);
int y = RANDOM.nextInt(1230 - 100);
Log.i(TAG, String.format("Moving text view to (%d, %d)", x, y));
textView.setX(x);
textView.setY(y);
//change the text position here
this.sendEmptyMessageDelayed(0, 30000);
}
}
textView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// use any of your own colors here...
textView.setTextColor(android.R.color.holo_purple);
return true;
}
});
See also https://developer.android.com/reference/android/widget/TextView.html#setTextColor(int)