I have a major problem about changing the value from a constructor
This is an app for flashlights. It will connect to a site to check the interval value (ex. 500 ms) and it will store it to an variable named frum_timer every 2 seconds.
Here's a object for that.
(also it will update a boolean if there's a new value)
FlashActivity = new CountDownTimer(40000, frum_timer) {
#Override
public void onTick(long millisUntilFinished) {
stats_of_run = true;
if (bool) {
final_form.setText("\\Flash ON//");
// CAMERA INSTRUCTIONS FOR OPENING FLASH
bool = false;
frumtimer_stats.setText("Speed:" + frum_timer);
} else {
stats_of_run = true;
final_form.setText("->Flash OFF-<");
// CAMERA INSTRUCTIONS FOR CLOSING FLASH
bool = true;
}
}
#Override
public void onFinish() {
}
}.start();
I made another CountDownTimer object with a refresh rate of 200 seconds to make sure the frum_timer from FlashActivity object will take change.
and using this
frumtimer_stats.setText("Speed:" + frum_timer);
in FlashActivity for displaying the variable.
However, after the variable frum_timer is changed, the FlashLight keep going again and again at the same old speed even if a made an FlashActivity.cancel() followed by FlashActivity.start()
Can someone give me some help?
Full link of code:
https://mycodestock.com/public/snippet/14395
Summary:
1.You start the app.
2. Refresh countdown starts in 2 sec
3. When there is a frum_timer the FlashActivity will start. After 2 sec, if there is another value stored on frum_timer, the actual FlashActivity will be canceled and will start a new one.
4.The problem is the new FlashActivity start but with the old frum_timer
I used:
public void startProgress(View view) {
// do something long
Runnable runnable = new Runnable() {
#Override
public void run() {
for (int i = 0; i <= 20; i++) {
final int value = i;
doFakeWork();
progress.post(new Runnable() {
#Override
public void run() {
// text.setText("Updating");
progress.setMax(20);
progress.setProgress(value);
}
});
}
}
};
new Thread(runnable).start();
}
private void doFakeWork() {
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Related
Can someone help me to understand what is happening here? Have been trying to debug, but feel like stuck!
I am trying to animate some online images in my Android app using the following method.
private void animateImages() {
// URL loading
// int i = 1; (initialized earlier)
// ArrayList<String> myImages = new ArrayList<>(); (initialized earlier)
myImages.clear();
While (i < 11) {
// Adds ten images using web link
myImages.add("My_web_url");
i++;
}
AccelerateInterpolator adi = new AccelerateInterpolator();
try {
Field mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
mScroller.set(viewPager, new MyScroller(getApplicationContext(), adi, 1));
}
catch (NoSuchFieldException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
if (viewPager != null) {
viewPager.setAdapter(new MyPageAdapter(getApplicationContext(), myImages));
}
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
// Printing variables for debugging
System.out.println("The page number is=" + currentPage);
System.out.println("The myImages size is=" + myImages.size());
public void run() {
if (currentPage == myImages.size() - 1) {
currentPage = 0;
}
viewPager.setCurrentItem(currentPage++, true);
}
};
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
// delay and period can be initialized as desired
}, delay, period);
}
}
When I call this method in OnCreate, animation works fine. However, when I call this method in OnClickButton Listener, variable myImages size (before public void run()) become zero and due to this animation doesn't work.
In the above, MySCroller and MyPageAdapeter are java classes. But, most likely, the issue is related to button click, and I don't understand why it resets the myImages size which halts the animation!
This is how button click listener is called. What am I doing wrong?
MyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animateImages();
}
});
Edit 1:
Thanks to all the comments, I made a little progress.
I moved all these variables from MainActivity to animateImages() method. The animation runs with button click as well but there is a bump in animation, where too images moves too fast then bump and so on..
// Added just before while loop
DELAY_MS = 1000;
PERIOD_MS = 1000;
i = 1;
currentPage = 0;
I notice the same animation bump if I move the URL loading while loop to OnCreate().
The second time you call animateImages it clears myImages but then doesn't loop because i is not reset so it remains empty. Move creation of that list to onCreate instead to avoid that issue.
I'm getting java.lang.IllegalStateException in my Android Music Player Application every time when I closes the Activity
mCurrentPosition = mediaPlayer.getCurrentPosition()/1000; // In milliseconds
I've tried nearly all the codes available and even all at java.lang.illegalStateException randomly occurs when getting mediaPlayer.getCurrentPosition also
Here's my Java code where I'm using it:
protected void initializeSeekBar(){
mSeekBar.setMax(mediaPlayer.getDuration()/1000);
mRunnable = new Runnable() {
#Override
public void run() {
int mCurrentPosition;
if(mediaPlayer!=null && mediaPlayer.isPlaying()){
mCurrentPosition = mediaPlayer.getCurrentPosition()/1000; // In milliseconds
}
else {
mCurrentPosition = 0;
}
if (mSeekBar != null) {
mSeekBar.setProgress(mCurrentPosition);
getAudioStats();
}
handler.postDelayed(mRunnable,1000);
}
};
handler.postDelayed(mRunnable,1000);
}
Please Help me out of this. Thanks in Advance
Edit 1
Also, my Seekbar goes to start when the music pauses and on play, it continues from where it was before pausing
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
getAudioStats();
initializeSeekBar();
if(mediaPlayer != null && fromUser) {
mediaPlayer.seekTo(progress * 1000);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
protected void getAudioStats(){
long duration = mediaPlayer.getDuration()/1000; // In milliseconds
long due = (mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition())/1000;
long pass = duration - due;
String test = DateUtils.formatElapsedTime(pass);
String test1 = DateUtils.formatElapsedTime(due);
current_time.setText("" + test);
//mDuration.setText("" + duration + " seconds");
total_time.setText("" + test1);
}
You need to remove your runnable from the handler queue when the activity closes (or, better yet, when it pauses). Try putting this in your activity's onPause() method:
handler.removeCallbacks(mRunnable);
For additional robustness, inside the runnable itself, you should only re-queue the runnable if the activity is still active. So instead of this:
handler.postDelayed(mRunnable,1000);
you should do this (assuming this code is in the activity class):
if (!isDestroyed()) {
handler.postDelayed(mRunnable,1000);
}
Also make sure you are stopping the media player before the activity is destroyed.
P.S. If you call initializeSeekBar() multiple times, you will be reassigning mRunnable and leaving the old one in the handler queue where it can cause trouble later. To fix this, you should add this at the start of initializeSeekBar():
protected void initializeSeekBar(){
if (mRunnable != null) {
handler.removeCallbacks(mRunnable);
}
// ... the rest of the method that you currently have
i am trying to make a button that when its clicked , it changes its color image and starts a countdowntimer in a method activeDelay() as here:
piscaAutoButton = (Button) rootView.findViewById(R.id.piscaAutoButton);
piscaAutoButton.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(final View view) {
if (sessionManager.getPisca()) {
sessionManager.setPisca(false);
trigger = false;
piscaAutoButton.setBackgroundResource(R.drawable.button_bg_round);
} else {
sessionManager.setPisca(true);
piscaAutoButton.setBackgroundResource(R.drawable.button_add_round);
trigger = true;
activeDelay(trigger);
}
here is my activeDelay method:
private boolean activeDelay(boolean trigger) {
while (trigger) { // LOOP WHILE BUTTON IS TRUE CLICKED
int timerDelay = manualControl.getDelayPisca(); //input for timer
//delay manual
new CountDownTimer(timerDelay * 1000, 1000) {
public void onFinish() {
System.out.println("sent");
try {
System.out.println("blink button " + manualControl.getBlinkButton());
if (!manualControl.getBlinkButton().isEmpty()) {
MenuActivity.mOut.write(manualControl.getBlinkButton().getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void onTick(long millisUntilFinished) {
}
}.start();
}
return trigger;
}
My problem is that i need the counter keeps going after finished, stopping just when the user clicks again in the button (trigger = false). I am having problems to program that, if someone could help,i know the return inside activeDelay ejects from the method, how can we solve that ,tks
I would suggest you to don't use CountDownTimer(this runs for some specific time period) , instead of this you should use Handler(this run infinitely) . i am sending you handler code.
private Handler handler = new Handler();
//call this when you want to start the timer .
handler.postDelayed(runnable, startTime);
Runnable runnable = new Runnable() {
#Override
public void run() {
// Do here , whatever you want to do(show updated time e.t.c.) .
handler.postDelayed(this, xyz); //xyz is time interval(in your case it is 1000)
}
};
//Stop handler when you want(In your case , when user click the button)
handler.removeCallbacks(runnable);
I am making an app to do something in webview automatically.
I want to make a pause between two lines inside (for-loop) until page finished loading without using Thread.sleep because it freezing my application.
this is my code:
webview.loadUrl("http://**********");
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for(int i=1;i<10;i++){
evaluateJavascript( "document.getElementById('select').value=" + i)
evaluateJavascript("document.getElementById('Search').click();")
//wait until finished loading
while( isloading() ){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
evaluateJavascript( "document.getElementById('any_select').value=5")
.
.
.
.
}
public boolean isloading(){
boolean isloading;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webview.evaluateJavascript("(function() { return document.getElementById(\"Loading\").style.display; })();", new ValueCallback<String>() {
#Override
public void onReceiveValue(String s) {
if(s.equals("none")){
isloading=false;
}else{
isloading=true;
}
}
});
}
if(isloading=true)return true;
if(isloading=false)return false;
}
If you don't want to use Thread.sleep then the alternative is to use AsyncTask in your application.
You can do your loading task in doInBackground() method of AsyncTask and call it using new AsyncTaskClass.execute();
You can go through it from here : http://developer.android.com/reference/android/os/AsyncTask.html
You can do something similar (instead of AsyncTask):
Edit:
Timer timer = new Timer();
while( isloading() ){
try {
timer.schedule( new TimerTask(){
public void run() {
//
}
}, delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
If you want to achieve, what i understand, that once your second line is called you want to stop there and when after 1000 ms you want to continue. You can do one thing, copy all the code after your second line and put that in run method of below code:
new Handler().postDelayed(new Runnable()
{
#Override
public void run() {
}
}, 1000);
It will execute you code after 1000ms
If you want to execute sequentially actions happening on UIThread and in backgrounds threads you should be looking for the Bolt Library by Parse/Facebook.
It apply Javascript promises to Android application.
You can go through it from here : https://github.com/BoltsFramework/Bolts-Android
I try to use this code to prevent multi-click in ImageView but it doesn't help.
Boolean isClicked = false;
#Override
public void onClick(View v)
{
if (v == imgClick && !isClicked)
{
//lock the image
isClicked = true;
Log.d(TAG, "button click");
try
{
//I try to do some thing and then release the image view
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
isClicked = false;
}
}
In the log cat, I can see 5 lines "button click" when I click on ImageView for 5 times as quickly as possible. I can see the log cat print the first line, wait for a while (2 seconds) and then print the next line. I think when I click the ImageView, the fired event is moved to queue in order, isn't it?. So how can I stop that?
I also try to use setEnable() or setClickable() instead of isClicked variable but it doesn't work too.
Just try this working code
Boolean canClick = true; //make global variable
Handler myHandler = new Handler();
#Override
public void onClick(View v)
{
if (canClick)
{
canClick= false; //lock the image
myHandler.postDelayed(mMyRunnable, 2000);
//perform your action here
}
}
/* give some delay..*/
private Runnable mMyRunnable = new Runnable()
{
#Override
public void run()
{
canClick = true;
myHandler.removeMessages(0);
}
};
Instead of sleeping in 2 seconds, I use some task like doSomeThing() method (has accessed UI thread), and I don't know when it completed. So how can I try your way?
//I referred this android link. You can handle thread more efficiently but i hope below code will work for you..
//you try this and
Boolean canClick = true; //make global variable
public void onClick(View v) {
if(canClick){
new DownloadImageTask().execute();
}
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
protected Bitmap doInBackground(String... urls) {
Log.d("MSG","Clicked");
canClick =false;
//perform your long operation here
return null;
}
protected void onPostExecute(Bitmap result) {
canClick =true;
}
}
You could keep track of the last consumed click upon your View, and based on it either perform the necessary actions, or simply return:
private long calcTime;
private boolean isClickedLately(final long millisToWait)
{
if (System.currentTimeMillis() - calcTime < millisToWait)
return true;
return false;
}
#Override
public void onClick(View v)
{
if (isClickedLately(2000))
return;
calcTime = System.currentTimeMillis();
Log.d(TAG, "consuming button click");
// perform the necessary actions
}
With the millisToWait parameter you can adjust the threshold of "waiting", but if you know that you want to wait exactly 2 seconds between two consecutive clicks, you can eliminate it.
This way you don't have to deal with Threads, which is good, since it's not a great idea to make the gui thread wait.