Unable to use Toast message in loop in android - java

I am making an android application in which
1) A loop begins and it checks whether connection is present
2)If it is, it performs TASK A and exits
3)if it isn't, it displays a TOAST message
and then goes to step 1
To implement this, I tried putting my Toast message in a loop and trying
1)Creating a class which extended Asynch Tasks and displaying the Toast in doBackground()
2)Creating a handler . I displayed the Toast message in postDelayed
3)Displaying toast within runOnUiThread()
All of them met the same fate
For a small value (<10s), the App would halt indefinitely
For a large value (=30s), the App would force close
int t=0;
while (!t=1)
{
ConnectionCheck2 cd = new ConnectionCheck2(mContext);
Boolean isInternetPresent = cd.isConnectingToInternet();
if (isInternetPresent)
{
//TASK A
t=1;
}
else
{
//made call to Handler, Asynch Tasks and runOnUiThread here to display the Toast message below
Toast.makeText(MainActivity.this,"Internet is NOT connected",
Toast.LENGTH_SHORT).show();
}
}
The class ConnectionCheck constructor is initialized with the context of the class displaying the toast message. It has a method called isConnectingToInternet(), which checks whether internet connection is there. Authenticity of this class and function has been confirmed.
I tried
public void doSomeWork()
{
final Timer someTimer= new Timer ();
someTimer.schedule (new TimerTask () {
#Override
public void run()
{
ConnectionCheck2 cd = new ConnectionCheck2(MainActivity.this.getApplicationContext());
final Boolean isInternetPresent = cd.isConnectingToInternet();
runOnUiThread (new Thread(new Runnable() {
public void run()
{
if (isInternetPresent)
{
Change();
someTimer.cancel();
}
Toast.makeText(MainActivity.this.getApplicationContext(),"NOT Connected",Toast.LENGTH_SHORT).show();
}
}));
}
}, 1000, 5000);
if (g==1)
{
Toast.makeText(MainActivity.this.getApplicationContext(), "Internet is connected", Toast.LENGTH_SHORT).show();
}
}//doSomeWork
public void Change()
{
g=1;
}
//g is declared as a global variable
However, if i initially put the net off and turn it on, Internet is connected doesn't get displayed
I put the toast message in the runOnUithread() But my problem is that , if i remove the control condition then, the control first goes to, the toast message which says "internet is connected" (the statement following the timer) and then to the "NOt connected" one. Also, when , Internet connectivity is found, and timer.cancel() is executed, the control doesn't go to the statement following the timer,instead it exits. As per my thinking, first the timer module should have been executed and then the statement succeeding it should have been executed, iff timer.cancel() condition was true

While loops is not a good way to go, you can run TimerTask to run after every specified value of time.
Timer someTimer= new Timer ();
someTimer.schedule (new TimerTask () {
#Override
public void run () {
// do your Checking here, for toast use runOnUIThread() or handler.
}
}, 0, 100);
Notes:
0 is for run on call
100 is to run every 100 of a second.
Update
final Timer someTimer = new Timer ();
someTimer.schedule (new TimerTask () {
#Override
public void run () {
ConnectionCheck2 cd = new ConnectionCheck2 (MainActivity.this.getApplicationContext ());
final Boolean isInternetPresent = cd.isConnectingToInternet ();
runOnUiThread (new Thread (new Runnable () {
public void run () {
if (isInternetPresent) {
Change ();
someTimer.cancel ();
return;
}
Toast.makeText (MainActivity.this.getApplicationContext (), "NOT Connected", Toast.LENGTH_SHORT).show ();
}
}));
}
}, 0, 5000);
if (g == 1) {
Toast.makeText (MainActivity.this.getApplicationContext (), "Internet is connected", Toast.LENGTH_SHORT).show ();
}
}

Related

Waiting for X time in loop using JAVA/Android

In my code i want to check longitude and latitude value. If values are empty, code will check for 15 seconds. If values are received , while loop will break and will show "You win". If they are still empty, it should show "error in gps" after 15 seconds.
The problem is that code is waiting perfectly but Progress Bar is not showing in the screen because screen got stuck during wait time. After 15 seconds screen is free. Please tell me how to resolve this issue. Thanks
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Toast.makeText(getBaseContext(), longitude.getText(), Toast.LENGTH_LONG).show();
Toast.makeText(getBaseContext(), latitude.getText(), Toast.LENGTH_LONG).show();
pBar = new ProgressDialog(oproprietor.this);
pBar.setCanceledOnTouchOutside(false);
pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pBar.setMessage("Waiting 15 seconds");
pBar.show();
long t= System.currentTimeMillis();
long end = t+15000;
while(System.currentTimeMillis() < end) {
if(!longitude.getText().equals("") || !latitude.getText().equals("") ){
pBar.dismiss();
break;
}
else continue;
}
if(longitude.getText().equals("") || latitude.getText().equals("")){
pBar.dismiss();
Toast.makeText(oproprietor.this, "Error in gps", Toast.LENGTH_LONG).show();
}
else if(!longitude.getText().equals("") || !latitude.getText().equals("") ){
pBar.dismiss();
Toast.makeText(oproprietor.this, "You win", Toast.LENGTH_LONG).show();
}
}
});
Since this is Android, I would definitely recommend using an AsyncTask over a thread. This question has all the relevant details on how to do this safely. Using a Java thread/Runnable introduces some UI issues in android when you are interacting with the UI thread from the external thread.
Try running it in a thread.
// Note: declare ProgressDialog progress as a field in your class.
progress = ProgressDialog.show(this, "dialog title",
"dialog message", true);
new Thread(new Runnable() {
#Override
public void run()
{
// do the thing that takes a long time
runOnUiThread(new Runnable() {
#Override
public void run()
{
progress.dismiss();
}
});
}
}).start();

Android Runnable won't repeat

I wan't to refresh a list of website every X Minutes.
After reading this thread: nested postDelayed / Runnable / Handler Android
I decided to use a Runnable + Handler instead of a TimerTask.
Unfortunately my Runnable won't run a second time. It will refresh the data once, then nothing happens.
my onCreate() Method looks like this:
...
fooWebsitesListView = (ListView) findViewById(R.id.fooWebsitesListView);
fooWebsitesAdapter = new ArrayAdapter<fooWebsite>(
getApplicationContext(), R.layout.list_black_text,
R.id.list_content, websiteList);
fooWebsitesListView.setAdapter(fooWebsitesAdapter);
final fooWebsitesActivity fooWebsitesRefreshActivity = new fooWebsitesActivity();
mHandler = new Handler();
refreshfooWebsitesRunnable = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Log.d("scheduled task", "---Scheduled Task: Refresh fooWebsites");
try {
fooWebsitesRefreshActivity.execute();
//mHandler.postDelayed(refreshfooWebsitesRunnable,3000);
mHandler.postDelayed(this, 3000);
} catch (Exception e) {
// Toast.makeText(getApplicationContext(),
// "Unable to receive Data", Toast.LENGTH_SHORT)
// .show();
}
}
};
startRepeatingTask();
}
void startRepeatingTask() {
refreshfooWebsitesRunnable.run();
}
LOG:
12-14 14:56:47.624: D/scheduled task(7995): ---Scheduled Task: Refresh fooWebsites
And there has been no chance since yet. The UI Thread is working fine, the app won't freeze or anything like that. Why won't my runnable loop?
Try to call mHandler.post() instead of refreshfooWebsitesRunnable.run() and call a mHandler.removeCallbacks() in the beginning of your run() method.

Android Timer/Clock

i want a clock/timer that's not insanely fast and force closes like a while loop.
This force closes:
while(loopEnabled == true)
{
//Do stuff
Toast toast Toast.makeText(this, "Hi!", 10000);
toast.show();
}
And so does this:
public void loop()
{
//Do stuff
Toast toast Toast.makeText(this, "Hi!", 10000);
toast.show();
resetLoop();
}
public void resetLoop()
{
Thread.sleep(100);
loop();
}
Any alternatives to stop this? I'm meaning for code to happen rapidly over and over.
Look at Handler especially the postAtTime or postDelayed methods.
For example:
private int mInterval = 1000; // in ms, so 1s here
private Handler mHandler;
#Override
protected void onCreate(Bundle bundle)
{
mHandler = new Handler();
}
Runnable mRepeatingTask = new Runnable()
{
#Override
public void run() {
// do something here
// schedule run again for mTnterval ms from now
mHandler.postDelayed(mRepeatingTask , mInterval);
}
};
void startRepeatingTask()
{
mRepeatingTask.run();
}
void stopTask()
{
mHandler.removeCallbacks(mRepeatingTask);
}
Are you doing this in the UI thread? If so, avoid it as there is a high chance that you will get a Application Not Responding dialog.
In android timers can be implemented using TimerTask and also by Handlers.
Check this link for all sample codes. Async task, handler and timer

Java / Android wait until a thread has finished before running a new method

I have an android application (written in java) which has two buttons (connect and request data).
When each button is clicked, a task is performed and a progress dialog appears to display how much the task has completed.
In order to show the progress dialog, when each button is clicked, the task is run on a thread.
The connect button just has one task - run on the thread. However, the request data button executes two tasks - the first task on the thread similar to the connect button but also a second task, refreshInfo() which must be run after the first task on the thread, progThread is finished.
private Button connectButton;
private Button requestDataButton;
private ProgressDialog connectionDialog;
private ProgressDialog requestDataDialog;
private ProgressThread progThread;
private int currentDialog;
public void connectClick(View view) //When the connect button is clicked
{
performAction(1); //Run the thread to perform the action
}
public void requestDownloadClick(View view) //When the request data button is clicked
{
performAction(2); //Run the thread to perform the action
refreshInfo(); //Do something else
}
private void performAction(int type)
{
currentDialog = type;
showDialog(type);
try
{
progThread.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
The key method here is performAction(int type). I basically don't want this method to complete until progThread has finished running.
As you can see, I've tried progThread.join() to prevent the method from continuing until progThread has finished running, however as progThread involves displaying a Progress Dialog, running progThread.join() seems to prevent the Progress Dialog from showing, as currently when you click the button, the first task is performing but the dialog only flashes up at the end.
Can anyone think of a way to run the thread, showing the Progress Dialog as normal and then running the second method (if there is one).
I've included the thread code below incase it is needed.
private class ProgressThread extends Thread
{
final static int DONE = 0;
final static int RUNNING = 1; // Class constants defining state of the thread
private Handler progressHandler;
int mState;
int total;
ProgressThread(Handler _handler) // Constructor with an argument that specifies Handler on main thread to which messages will be sent by this thread.
{
progressHandler = _handler;
}
public void run() // Invoked automatically when the Thread starts.
{
mState = RUNNING;
updateProgressBar();
connectButton = (Button) findViewById(R.id.btnConnect);
requestDataButton = (Button) findViewById(R.id.btnRequestDownload);
while (mState == RUNNING)
{
if (currentDialog == 1)
{
try
{
doSomething();
if (something)
{
setState(DONE);
total = 100;
updateProgressBar();
removeDialog(1);
connectButton.setEnabled(false);
}
else
{
total = total + 20;
if (something has reached a limit)
{
setState(DONE);
total = 0;
updateProgressBar();
removeDialog(1);
}
}
updateProgressBar();
}
catch (Exception e)
{
}
}
if (currentDialog == 2)
{
try
{
doSomething();
total = 10;
updateProgressBar();
doSomething();
total = 70;
updateProgressBar();
if (something) //If the download info has not been got
{
setState(DONE);
total = 0;
updateProgressBar();
removeDialog(2);
runOnUiThread(new Runnable()
{
public void run()
{
connectButton.setEnabled(true);
requestDataButton.setEnabled(true);
}
});
}
else
{
total = 100;
updateProgressBar();
setState(DONE);
removeDialog(2);
runOnUiThread(new Runnable()
{
public void run()
{
requestDataButton.setEnabled(false);
}
});
}
}
catch (Exception e)
{
removeDialog(2);
setState(DONE);
runOnUiThread(new Runnable()
{
public void run()
{
connectButton.setEnabled(true);
requestDataButton.setEnabled(true);
}
});
}
}
}
}
// Set current state of thread (use state=ProgressThread.DONE to stop thread)
public void setState(int state)
{
mState = state;
}
public void updateProgressBar()
{
Message msg = progressHandler.obtainMessage(); // Send message (with current value of total as data) to Handler on UI thread so that it can update the progress bar
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
progressHandler.sendMessage(msg);
}
}
final Handler handler = new Handler() // Handler on the main (UI) thread that will receive messages from the second thread and update the progress.
{
public void handleMessage(Message msg)
{
int total = msg.getData().getInt("total"); // Get the current value of the variable total from the message data and update the progress bar
switch (currentDialog)
{
case 1 :
connectionDialog.setProgress(total);
break;
case 2 :
requestDataDialog.setProgress(total);
break;
}
}
};
protected Dialog onCreateDialog(int id)
{
switch (currentDialog)
{
case 1 :
connectionDialog = new ProgressDialog(this);
connectionDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
connectionDialog.setMax(100);
connectionDialog.setProgress(0);
connectionDialog.setMessage("Connecting To The Device");
progThread = new ProgressThread(handler);
progThread.start();
return connectionDialog;
case 2 :
requestDataDialog = new ProgressDialog(this);
requestDataDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
requestDataDialog.setMax(100);
requestDataDialog.setProgress(0);
requestDataDialog.setMessage("Requesting Download Data");
progThread = new ProgressThread(handler);
progThread.start();
return requestDataDialog;
default :
return null;
}
}
Android API provides an AsyncTask class which has two methods doInBackground and onPostExecute. You'll have to override both of them, do whatever you have to do in doInBackground and when the job is done onPostExecute callback will be run.
There's also an onProgressUpdate callback which is exactly what you need.
Look at AsyncTask class. It should be able to do what you want.
http://developer.android.com/reference/android/os/AsyncTask.html
Seems other answers have you covered. AsyncTask is the way to go.
However if you want to push through with your Thread implementation, just start() the next thread at the end of the first thread's run method.
Sounds like you need to use a CountdownLatch of size 1

Android - Setting a Timeout for an AsyncTask?

I have an AsyncTask class that I execute that downloads a big list of data from a website.
In the case that the end user has a very slow or spotty data connection at the time of use, I'd like to make the AsyncTask timeout after a period of time. My first approach to this is like so:
MyDownloader downloader = new MyDownloader();
downloader.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run() {
if ( downloader.getStatus() == AsyncTask.Status.RUNNING )
downloader.cancel(true);
}
}, 30000 );
After starting the AsyncTask, a new handler is started that will cancel the AsyncTask after 30 seconds if it's still running.
Is this a good approach? Or is there something built into AsyncTask that is better suited for this purpose?
Yes, there is AsyncTask.get()
myDownloader.get(30000, TimeUnit.MILLISECONDS);
Note that by calling this in main thread (AKA. UI thread) will block execution, You probably need call it in a separate thread.
Use CountDownTimer Class in side the extended class for AsyncTask in the onPreExecute() method:
Main advantage, the Async monitoring done internally in the class.
public class YouExtendedClass extends AsyncTask<String,Integer,String> {
...
public YouExtendedClass asyncObject; // as CountDownTimer has similar method -> to prevent shadowing
...
#Override
protected void onPreExecute() {
asyncObject = this;
new CountDownTimer(7000, 7000) {
public void onTick(long millisUntilFinished) {
// You can monitor the progress here as well by changing the onTick() time
}
public void onFinish() {
// stop async task if not in progress
if (asyncObject.getStatus() == AsyncTask.Status.RUNNING) {
asyncObject.cancel(false);
// Add any specific task you wish to do as your extended class variable works here as well.
}
}
}.start();
...
change CountDownTimer(7000, 7000) -> CountDownTimer(7000, 1000) for example and it will call onTick() 6 times before calling onFinish(). This is good if you want to add some monitoring.
Thanks for all the good advice I got in this page :-)
In the case, your downloader is based upon an for an URL connection, you have a number of parameters that could help you to define a timeout without complex code:
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(15000);
urlc.setReadTimeout(15000);
If you just bring this code into your async task, it is ok.
'Read Timeout' is to test a bad network all along the transfer.
'Connection Timeout' is only called at the beginning to test if the server is up or not.
I don't think there's anything like that built into AsyncTask. Your approach seems to be a good one. Just be sure to periodically check the value of isCancelled() in your AsyncTask's doInBackground method to end this method once the UI thread cancels it.
If you want to avoid using the handler for some reason, you could check System.currentTimeMillis periodically within your AsyncTask and exit on timeout, although I like your solution better since it can actually interrupt the thread.
Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
//async task
final RunTask tsk = new RunTask ();
tsk.execute();
//setting timeout thread for async task
Thread thread1 = new Thread(){
public void run(){
try {
tsk.get(30000, TimeUnit.MILLISECONDS); //set time in milisecond(in this timeout is 30 seconds
} catch (Exception e) {
tsk.cancel(true);
((Activity) mContext).runOnUiThread(new Runnable()
{
#SuppressLint("ShowToast")
public void run()
{
Toast.makeText(mContext, "Time Out.", Toast.LENGTH_LONG).show();
finish(); //will close the current activity comment if you don't want to close current activity.
}
});
}
}
};
thread1.start();
}
You can put one more condition to make cancellation more robust. e.g.,
if (downloader.getStatus() == AsyncTask.Status.RUNNING || downloader.getStatus() == AsyncTask.Status.PENDING)
downloader.cancel(true);
Inspiring from question I have written a method which do some background task via AsyncTask and if processing takes more then LOADING_TIMEOUT then an alert dialogue to retry will appear.
public void loadData()
{
final Load loadUserList=new Load();
loadUserList.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (loadUserList.getStatus() == AsyncTask.Status.RUNNING) {
loadUserList.cancel(true);
pDialog.cancel();
new AlertDialog.Builder(UserList.this)
.setTitle("Error..!")
.setMessage("Sorry you dont have proper net connectivity..!\nCheck your internet settings or retry.")
.setCancelable(false)
.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
loadData();
}
})
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
System.exit(0);
}
})
.show();
}
}
}, LOADING_TIMEOUT);
return;
}

Categories