I have a thread that start playing mp3 file, in this thread i update my TextView after round trip i use other thred to update my player and my TextView but in this case the textview not updated ?!
public void updatePlayProgressUpdater() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mediaLengthInSeconds = sharedPreferences.getLong("mediaLengthInSeconds", 0);
float mediaPositionSeconds = sharedPreferences.getFloat("mediaPositionSeconds", 0);
float progress = (mediaPositionSeconds / mediaLengthInSeconds);
sb.setProgress((int) (progress * 100));
sb.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
seekChange(v);
return false;
}
});
try {
textStreamed
.setText(convertDuration(mediaPlayer.getCurrentPosition() / 1000)
+ "/" + convertDuration(mediaLengthInSeconds));
} catch (Exception e) {
Log.v("Exception","");
}
Runnable notification = new Runnable() {
public void run() {
updatePlayProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
}
...
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater();
}
};
...
// comment ...
public void startPlayProgressUpdater() {
mediaLengthInSeconds = mediaPlayer.getDuration() / 1000;
float mediaPositionSeconds = mediaPlayer.getCurrentPosition() / 1000;
float progress = (mediaPositionSeconds / mediaLengthInSeconds);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putLong("mediaLengthInSeconds", mediaLengthInSeconds);
editor.putFloat("mediaPositionSeconds", mediaPositionSeconds);
editor.commit(); // I missed to save the data to preference here,.
sb.setProgress((int) (progress * 100));
// playButton.setImageResource(R.drawable.pause);
sb.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
seekChange(v);
return false;
}
});
textStreamed
.setText(convertDuration(mediaPlayer.getCurrentPosition() / 1000)
+ "/" + convertDuration(mediaLengthInSeconds));
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
}
}
...
private void LoadPreferences(){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
int state = sharedPreferences.getInt("stateDB", 0);
sb.setProgress(state);
textStreamed.setText(sharedPreferences.getString("statetextStreamed", ""));
coursTitle.setText(sharedPreferences.getString("coursTitle", ""));
coursIntervenant.setText(sharedPreferences.getString("coursIntervenant", ""));
new Thread() {
public void run() {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
updatePlayProgressUpdater();
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
...
#Override
protected void onResume() {
super.onResume();
LoadPreferences();
}
When you create an app, there is a single main thread (referred to as the UI thread) that handles all UI updating. Other threads you create cannot update the UI directly. It sounds like you have two update methods, one being called from the UI thread and one from a background thread.
There are many articles that explain it better than I can, such as http://developer.android.com/training/multiple-threads/communicate-ui.html.
on line 525 replace startPlayProgressUpdater(); with:
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
Related
i am trying to disable the save button for exactly 1 hour, before the user can save data again. I have come up with some code but since i am still really new to programming i am kind of stuck and any help would be appritiated.
The problem is the button does not lock when i click save.
public void AddData(){
gumb_poslji.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Activity activity = getActivity();
Calendar calander = Calendar.getInstance();
Integer cDay = calander.get(Calendar.DAY_OF_MONTH);
Integer cHour = calander.get(Calendar.HOUR_OF_DAY);
Integer cDayOfTheWeek = calander.get(Calendar.DAY_OF_WEEK)-1;
Integer cMonth = calander.get(Calendar.MONTH)+1;
int seekBarProgressValue = seekBar.getProgress();
String strI = String.valueOf(seekBarProgressValue);
String poslji_data = strI;
boolean pregled_vnosa = myDb.insertData(poslji_data,cHour,cDay,cDayOfTheWeek,cMonth);
if (pregled_vnosa==true)
Toast.makeText(activity, "Vnos uspešen",Toast.LENGTH_LONG).show();
else
Toast.makeText(activity, "Vnos neuspešen!!!",Toast.LENGTH_LONG).show();
}
});
gumb_poslji.setEnabled(true);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(3600000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
gumb_poslji.setEnabled(false);
}
});
}
}).start();
}
Handler mHandler= new Handler();
static Runnable mUpdateTimeTask = new Runnable() {
public void run() {
gumb_poslji.setEnabled(false);
mHandler= .removeCallbacks(mUpdateTimeTask);
}
};
mHandler.postDelayed(this, 3600000);
I tried to implement a layout that works like a progress bar. I want to it to be able to be set to any level I want in special cases. For example to be set to 20.
#Override
public void handleMessage(Message msg) {
if (msg.what == 0x123) {
mCDrawable.setLevel(mProgress);
}
}
Runnable a= new Runnable() {
#Override
public void run() {
running = true;
handler.sendEmptyMessage(0x123);
mProgress = 20;
try {
Thread.sleep(18);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
public void add(int num){
Thread s = new Thread(a);
s.start();
}
I do it by calling the "add" function.
The problem is that in a "while" where the progress changes continueslly it works:
Runnable r = new Runnable() {
#Override
public void run() {
running = true;
while (running) {
handler.sendEmptyMessage(0x123);
if (mProgress > MAX_PROGRESS) {
mProgress = 0;
}
mProgress += 100;
try {
Thread.sleep(18);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
What is the difference? How can I set it to a specific value otherwise?
---edit----:
I tried this code and it still doesnt work:
public void add(int num){
int lvl = mClipDrawable.getLevel();
Log.d("______________", "the first was "+lvl);
lvl += 100;
if (lvl > 10000) {
lvl = 1000;
}
Log.d("______________", "set to "+lvl);
mClipDrawable.setLevel(lvl);
}
the first level was 0 and it set 100..
I need count down timer that whenever I clicked or times up, send result and time score to another activity. So I used thread, but I don't know why in first time run activity it don't show time for some seconds in textview, one more strange thing is that when press back,then go to activity again it works fine.
count down code:
if (flagTime) {
flagTime = false;
new Thread(new Runnable() {
#Override
public void run() {
int counter = 60;
while (function.isActivityVisible() && counter > 0) {
counter--;
final int finalCounter = counter;
try {
Thread.sleep(1000);
G.HANDLER.post(new Runnable() {
#Override
public void run() {
if (function.isActivityVisible()) {
timeSc=finalCounter;
String preSec = "";
if (finalCounter < 10) {
preSec = "0";
}
if (function.isActivityVisible()
&& finalCounter <= 0) {
flagTime = false;
Intent intent = new Intent(
Memorize.this,
MemorizeResult.class);
intent.putExtra("TIME", 60);
intent.putExtra("ARRAY_RESULT",
array_choice);
startActivity(intent);
finish();
}
String score = "00:" + preSec
+ finalCounter;
txt[20].setText( " time ramaining " + score);
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
if (!function.isActivityVisible()) {
flagTime = false;
finish();
}
}
}).start();
}
I use many flag to handle it, but it seems don't work properly.
Try using a CountDownTimer
Something like:
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
I have two threads, two handlers. From thread i check a random number and send result to handle to update ui. But i am getting the error "only the original thread that created a view hierarchy can touch its views.". I searched some articles, they tell to use handler. I am doing that, yet can not avoid the errors.
After some checking, I found that it crashes when A sends the result. In case of B, it works
Also, can i use one handler for two thread?
public class MainActivity extends Activity implements View.OnClickListener{
Button start;
TextView status_B, status_A;
Boolean isRunning;
Thread Athread, Bthread;
int a, b;
Handler a_Handler, b_Handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initialize variables
start = (Button) findViewById(R.id.button);
start.setOnClickListener(this);
status_B = (TextView) findViewById(R.id.textView);
status_A = (TextView) findViewById(R.id.textView1);
a_Handler = new Handler() {
public void handleMessage(Message msg)
{
int number = msg.getData().getInt("number");
String winner = msg.getData().getString("winner");
start.setEnabled(true);
isRunning = false;
status_A.setText(winner + number);
}
};
b_Handler = new Handler() {
public void handleMessage(Message msg)
{
int number = msg.getData().getInt("number");
String winner = msg.getData().getString("winner");
start.setEnabled(true);
isRunning = false;
status_B.setText(winner + number);
}
};
}
#Override
protected void onStart() {
super.onStart();
isRunning = false;
}
#Override
public void onClick(View v) {
start.setEnabled(false);
status_B.setText("Guessing...");
if (!isRunning)
{
Athread = new Thread(new Runnable() {
#Override
public void run() {
while (isRunning)
{
try
{
Athread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
a = (int) (Math.random()*1000);
System.out.println("a "+ a);
if(a%7 == 0) {
isRunning = false;
Bundle bundle = new Bundle();
bundle.putString("winner", "A");
bundle.putInt("number", a);
Message msg = a_Handler.obtainMessage();
msg.setData(bundle);
a_Handler.handleMessage(msg);
}
}
}
});
Bthread = new Thread(new Runnable() {
#Override
public void run() {
while(isRunning)
{
try
{
Bthread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
b = (int) (Math.random()*1000);
System.out.println("b "+ b);
if(b%7 == 0) {
isRunning = false;
Bundle bundle = new Bundle();
bundle.putString("winner", "B");
bundle.putInt("number", b);
Message msg = b_Handler.obtainMessage();
msg.setData(bundle);
b_Handler.sendMessage(msg);
}
}
}
});
isRunning = true;
Athread.start();
Bthread.start();
}
}
}
You need put your code to modify views on UI thread:
a_Handler = new Handler() {
public void handleMessage(Message msg)
{
final int number = msg.getData().getInt("number");
final String winner = msg.getData().getString("winner");
runOnUiThread(new Runnable() {
#Override
public void run() {
start.setEnabled(true);
status_A.setText(winner + number);
}
});
isRunning = false;
}
};
b_Handler = new Handler() {
public void handleMessage(Message msg)
{
final int number = msg.getData().getInt("number");
final String winner = msg.getData().getString("winner");
runOnUiThread(new Runnable() {
#Override
public void run() {
start.setEnabled(true);
status_B.setText(winner + number);
}
});
isRunning = false;
}
};
I have a horizontal progress bar in android. I need to make it complete in 60 seconds.
Why doesn't the below code work?
int progress = 0;
progressBarHorizontal.setMax(60);
while(progress < 60) {
progressHandler.postDelayed((new Runnable() {
public void run() {
progressBarHorizontal.setProgress(progress);
}
}),progress * 1000);
progress++;
}
Please suggest some other methods. I tried this:
new Thread(new Runnable() {
int progress = 0;
public void run() {
long timerEnd = System.currentTimeMillis() + 60 * 1000;
while (timerEnd > System.currentTimeMillis() ) {
progress = (int) (timerEnd - System.currentTimeMillis()) / 1000;
// Update the progress bar
progressHandler.post(new Runnable() {
public void run() {
progressBarHorizontal.setProgress(progress);
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Log.w("tag","Progress thread cannot sleep");
}
}
}
}).start();
But it is not working either.
The second piece of code actually works, the problem was with my logic.
you can try the CountDownTimer :
pd = ProgressDialog.show(MovementEntry.this, "", "Please Wait...",
true, false);
pd.show();
new CountDownTimer(60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
//this will be done every 1000 milliseconds ( 1 seconds )
int progress = (60000 - millisUntilFinished) / 1000;
pd.setProgress(progress);
}
#Override
public void onFinish() {
//the progressBar will be invisible after 60 000 miliseconds ( 1 minute)
pd.dismiss();
}
}.start();
This one will update the statusbar until it reaches its maximum value:
private int progress = 0;
private final int pBarMax = 60;
...
final ProgressBar pBar = (ProgressBar) findViewById(R.id.progressBar1);
pBar.setMax(pBarMax);
final Thread pBarThread = new Thread() {
#Override
public void run() {
try {
while(progress<=pBarMax) {
pBar.setProgress(progress);
sleep(1000);
++progress;
}
}
catch(InterruptedException e) {
}
}
};
pBarThread.start();
You can try this code for that:
Thread timer = new Thread(){
public void run(){
try{
sleep(10000);
while(progressBarStatus < 10000){
StartPoint.this.runOnUIThread(new Runnable(){
public void run()
{
progressBar.setProgress(progressBarStatus);
progressBarStatus += 1000;
}
});
}
}catch(InterruptedException e){
e.printStackTrace();
}finally{
}
}
};
timer.start();
This code works for me
new Thread(new Runnable() {
public void run() {
long timerEnd = System.currentTimeMillis() + 60 * 1000;
while (timerEnd > System.currentTimeMillis()) {
progress = 60 - (int) (timerEnd - System.currentTimeMillis()) / 1000;
// Update the progress bar
progressHandler.post(new Runnable() {
public void run() {
progressBarHorizontal.setProgress(progress);
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Log.w("App","Progress thread cannot sleep");
}
}
progressHandler.post(new Runnable() {
public void run() {
okButton.performClick();
}
});
}
}).start();