my goal is to dismiss the initial progressdialog if there's no internet connection (let's say after 10 seconds) and then trigger another alertdialog whice prompts the user to check his internet connection and try again.
here is my RemoteDataTask class :
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
/*
Create the progressdialog
*/
mProgressDialog = new ProgressDialog(MainActivity.this);
//title :
mProgressDialog.setTitle("SmartShop. Shopping made easy !");
//message :
mProgressDialog.setMessage("Chargement...");
mProgressDialog.setIndeterminate(false);
//show the progressdialog...Only if gpslocation is available !! :)
if (gps.canGetlocation()){
mProgressDialog.show();
}
//mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
long delayInMillis = 3000;
list_of_articles = new ArrayList<Articles>();
try {
timer.schedule(new TimerTask() {
#Override
public void run() {
mProgressDialog.dismiss();
}
},delayInMillis );
// Locate the class table named "Article" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Article");
// Locate the column named "ranknum" in Parse.com and order list
// by ascending
//query.orderByAscending("ranknum");
query.whereWithinKilometers("Localisation_Vendeur",device_location,rayon);
ob = query.find();
for (ParseObject article : ob) {
// Locate images in article_image column
ParseFile image = (ParseFile) article.get("Image_Article");
Articles map = new Articles();
map.setArticle_name((String) article.get("Nom_Article"));
map.setArticle_vendor((String) article.get("Nom_Vendeur"));
//map.setArticle_vendor((String) article.get("reduction"));
map.setArticle_image(image.getUrl());
list_of_articles.add(map);
}
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this,
list_of_articles);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
my progressdialog does not dismiss with this code. what's wrong with it ? and where should I call the second alertdialog "check internet connection and try again" ?
Thanks !
You should perform UI modifications only from the UI thread. Timer runs its tasks in its own thread, not in the UI thread. You can do something like this:
runOnUiThread(new Runnable() { public void run() {
mProgressDialog.dismiss();
}});
And start a new dialog in the same way.
Related
I'm new to android studio and in learning phase.
I'm able to get current user location and store it in Parse server. Now i have also stored the Geo location of some super markets in Parse database in a class "Hospitals". Now i'm trying to retrieve the Geo location of specific hospital and trying to compare the distance between current user and the hospital.
When i'm trying to fetch the value from Parse database, it is calculated in background, so i'm unable to use it in different function to get the difference in distance as the return value will be null.
Below code is used:
class RemoteDataTask extends AsyncTask<Void, Void, Void> {
ProgressDialog mProgressDialog;
private Context context;
List<ParseUser> object = new ArrayList<>();
final ParseGeoPoint[] parlourUser = new ParseGeoPoint[1];
RemoteDataTask(Context context) {
Log.i("info", "Enetred RemoteDataTask");
this.context = context;
}
#Override protected Void doInBackground(Void... params) {
Log.i("info", "Entered doInbackground");
ParseQuery<ParseUser> query = ParseUser.getQuery();
try{
Log.i("info", "value is " + query.get("aifg14PNKz"));
object.set(1, query.get("aifg14PNKz"));
Log.i("info", "Object value" + object.get(1));
parlourUser[0] = object.get(0).getParseGeoPoint("Location");
Log.i("info", "Location of parlour user " + parlourUser[0]);
} catch (ParseException e) {
e.printStackTrace();
}
}
First of all, this is a very wrong practice to make a function which depends on the background thread.
query.getInBackground
It will work on the background thread and
After Background Query completed, this callback method communicates with UI thread
new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
}
Your function will not work if query.getInBackground take some time.
Solution to your problem in 2 steps
1) You can call this in AsyncTask and handle the Query in background
// RemoteDataTask AsyncTask
ProgressDialog mProgressDialog;
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
private Context context;
List<ParseObject> object;
final ParseGeoPoint[] hospitalUser = new ParseGeoPoint[1];
RemoteDataTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(context);
// Set progressdialog title
mProgressDialog.setTitle("Title...");
// Set progressdialog message
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// Create the array
try {
ParseQuery<ParseObject> query = ParseQuery.getQuery("Lakme");
object = query.find();
if (ob != null) {
hospitalUser[0] = object.getParseGeoPoint("Location");
//calculate distance
}
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Close the progressdialog
mProgressDialog.dismiss();
// You can use "hospitalUser" Object here.
}
}
Call it from where you call this method
new RemoteDataTask(YourActivity.this).execute();
2) Calculate Distance once got a result from query
if it does not involve UI thread then you can calculate it in
"doInBackground" or
if it does involve UI thread you should use it in "onPostExecute" or
if you want to get notified after AsyncTask completed then you can
implement interface like this.
I have an AsyncTask that loads all my data on parse.com, then the user has a checkbox to select the categories he wants to display.
Once I get those choices (from a separate class via an interface), I reload the asyncTask, but It still lists everything (like if the array of choices gets erased/reloaded).
here is my code to get the selected categories :
#Override
public void onOkay(ArrayList<Integer> selected) {
StringBuilder stringBuilder = new StringBuilder();
if (selected.size() != 0) {
for (int i = 0; i < selected.size(); i++) {
String categories = selectedArray[selected.get(i)];
stringBuilder = stringBuilder.append(", " + categories);
}
//this is to display the content of the selectedArray :
Toast.makeText(this, "You have selected: "
+ stringBuilder.toString(), Toast.LENGTH_SHORT).show();
//reloading the AsyncTask class :
new RemoteDataTask().execute();
}
}
My AsyncTask :
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//timer and progressdialog...
}
#Override
protected Void doInBackground(Void... params) {
list_of_articles = new ArrayList<Articles>();
try {
// Locate the class table named "Article" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Article");
query.whereWithinKilometers("Localisation_Vendeur", device_location, rayon);
//this is the query I use :
query.whereContainedIn ("Category",Arrays.asList(selectedArray));
ob = query.find();
for (ParseObject article : ob) {
// Locate images in article_image column
ParseFile image = (ParseFile) article.get("label1");
Articles map = new Articles();
map.setArticle_label1((String) article.get("label2"));
map.setArticle_label2((String) article.get("label3"));
map.setArticle_category((String) article.get("Category"));
map.setArticle_label4((String) article.get("label4"));
map.setArticle_image(image.getUrl());
list_of_articles.add(map);
}
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this,
list_of_articles);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
How can I make that work ? Keep in mind that the query works, i've tested with an array that i filled manually and it works.
Thanks.
You should pass categories that user wants to display as arguments to AsyncTask through AsyncTask.execute(Params... params). They will be available in AsyncTask.doInBackground method as that method parameters. Use them inside doInBackgorund method to set your query appropriately.
private class RemoteDataTask extends AsyncTask<List<String>, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//timer and progressdialog...
}
#Override
protected Void doInBackground(List<String>... params) {
list_of_articles = new ArrayList<Articles>();
try {
// Locate the class table named "Article" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Article");
query.whereWithinKilometers("Localisation_Vendeur", device_location, rayon);
//this is the query I use :
query.whereContainedIn ("Category", params[0]);
ob = query.find();
for (ParseObject article : ob) {
// Locate images in article_image column
ParseFile image = (ParseFile) article.get("label1");
Articles map = new Articles();
map.setArticle_label1((String) article.get("label2"));
map.setArticle_label2((String) article.get("label3"));
map.setArticle_category((String) article.get("Category"));
map.setArticle_label4((String) article.get("label4"));
map.setArticle_image(image.getUrl());
list_of_articles.add(map);
}
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this,
list_of_articles);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
Then in code run AsyncTask by calling new RemoteDataTask().execute(Arrays.asList(selectedArray)). Make sure that selectedArray is updated properly before every call of AsyncTask.
I am new to android development.I have done some android application to cummounicate with webservice and get data from it into local database in android device.I used AsyncTask<,,> Method to transfer data from internet.
Then I used ProgressDialog to indecate the data transfering.What i am doing.checking how meny tables have to sync and getting all data with for loop and through the for loop call my AsyncTask().execute() Method. (code shows bellow)
Issue is when showing the progress dialog loop length is grater than 1 open several progress dialogs on top itselft and they are not close.But already i called close event
DataTransfering Method
private class NetworkTransfer extends AsyncTask<DataLocation, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(LocationFinder.this); // show ProgressDialog
pDialog.setMessage("Processing...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(DataLocation... arg0) {
NetworkUtil networkUtil = new NetworkUtil(); //my http connection class
DataLocation loc = arg0[0];
networkUtil.InsertDataEmp(loc.getC_device_modle(),
loc.getC_usercd(), loc.getC_brach());
DataSource dsx = new DataSource(getApplicationContext());
dsx.updateLocDt(loc.getC_brach()); // send data to webserver
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (pDialog.isShowing())
pDialog.dismiss(); // for dissmiss the ProgressDialog
}
Function to run execure() method in Button Click Event shows bellow.
public void sendAllUnSyncData() {
DataSource ds = new DataSource(getApplicationContext());
final List<DataLocation> data = ds.GetLocList();
for (int i = 0; i < data.size(); i++) {
final NetworkTransfer networkObject = new NetworkTransfer();
networkObject .execute(data.get(i)); // call AsyncTask Method
}
}
When Running this code if loop length is bigger than (i>1)one (1) Progress Dioalog not closed.But if it's equals to one (1) , (i==1)it's worked!
Also I was tryied with Thread,but result was same.
In your onPreExecute, try to add this:
protected void onPreExecute() {
super.onPreExecute();
if (pDialog == null || !pDialog.isShowing()){
pDialog = new ProgressDialog(LocationFinder.this); // show ProgressDialog
pDialog.setMessage("Processing...");
pDialog.setCancelable(false);
pDialog.show();
}
}
Then set 2 global variables: int dataSized and int dataDone=0.
Initiate dataSized in your sendAllUnSyncData like this:
public void sendAllUnSyncData() {
DataSource ds = new DataSource(getApplicationContext());
final List<DataLocation> data = ds.GetLocList();
dataSized=data.size();
for (int i = 0; i < data.size(); i++) {
final NetworkTransfer networkObject = new NetworkTransfer();
networkObject .execute(data.get(i)); // call AsyncTask Method
}
}
Then on your onPostExecute, do this:
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
dataDone++;
if(dataDone==dataSized){
if (pDialog.isShowing())
pDialog.dismiss(); // for dissmiss the ProgressDialog
}
}
Let me know if it's working.
im using the azure mobile service. I have some users in the db i want to authenticate, and in order to do that, I execute a query to get a User after you enter a username and a password and press OK. When OK is pressed, if all it's well an intent should be started. How can I display a ProgressDialog until the callback method of the executed query is completed?
EDIT: the problem is that i have a button(logIn button) and when you click it, it will build a query and execute it in an async task, hence my problem. If i just add a progress dialog the call flow will move on since from the onClickListener point of view, the action has finished.
Just show() it before you call the query and dismiss() it in the callback method.
As your using the AsyncTask to query the data , use the onPreExecute and onPostExecute methods to show/dismiss the ProgressDialog.
Create a class which extends the AsyncTask , like this . In the onPreExecute show the ProgressDialog and when your done with fetching the data in doInBackground , in onPostExecute dismiss the dialog
public class QueryTask extends AsyncTask<Void,Void,Object> {
private ProgressDialog progressDialog = null;
private final Context mContext;
public QueryTask(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(mContext);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// do your stuff to query the data
return null;
}
#Override
protected void onPostExecute(Object result) {
progressDialog.dismiss();
// do your other stuff with the queried result
}
#Override
protected void onCancelled(Object result) {
progressDialog.dismiss();
}
}
Finally, when button onClick execute the task
new QueryTask(YourActivity.this).execute();
This example code was used by me to load all the events from an SQL database. Until the app gets the data from the server, a progress dialog is displayed to the user.
class LoadAllEvents extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Just a moment...");
pDialog.setIndeterminate(true);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_events,
"GET", params);
try {
// Checking for SUCCESS TAG
int success = json.getInt(CONNECTION_STATUS);
if (success == 1) {
// products found
// Getting Array of Products
Events = json.getJSONArray(TABLE_EVENT);
// looping through All Contacts
for (int i = 0; i < Events.length(); i++) {
JSONObject evt = Events.getJSONObject(i);
// Storing each json item in variable
id = evt.getString(pid);
group = evt.getString(COL_GROUP);
name = evt.getString(COL_NAME);
desc = evt.getString(COL_DESC);
date = evt.getString(COL_DATE);
time = evt.getString(COL_TIME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(pid, id);
map.put(COL_GROUP, group);
map.put(COL_NAME, name);
map.put(COL_DESC, desc);
map.put(COL_DATE, date);
map.put(COL_TIME, time);
// adding HashList to ArrayList
eventsList.add(map);
}
} else {
// Options are not available or server is down.
// Dismiss the loading dialog and display an alert
// onPostExecute
pDialog.dismiss();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
getActivity().runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(getActivity(),
eventsList, R.layout.list_item, new String[] {
pid, COL_GROUP, COL_NAME, COL_DATE, COL_TIME },
new int[] { R.id.pid, R.id.group, R.id.name, R.id.header,
R.id.title2 });
setListAdapter(adapter);
}
});
}
hope this helps.
Am building application for company events , i got the events from database and fill it in the adapter for ListView, i need to display ProgressDialog during the retrieving data from database , this is my code
`
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.listlayout);
adapter = new MyArrayAdapter(this);
listView = (ListView) findViewById(R.id.list);
progressDialog = ProgressDialog.show(this, "Please wait....",
"Here your message");
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
//this is call the webservice to got filled adapter
adapter = new EventWebservice().getAdapter(this);
listView.setAdapter(adapter);
progressDialog.dismiss();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
`
What i say is make use of AsyncTask().. show ypur dialog in preExecute() and dismiss in postexecute();.. and the data fetching code u put in backGround task.. i mean like below.. this is a sample code i ve used in my project
class Backgrountask extends AsyncTask
{
#Override
protected void onPostExecute(Object result) {
dialog.dismiss();
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(Mwfa.this, "",
"Loading. Please wait...", true);
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... arg0) {
//your code
}
return null;
}
}
}
I would us a AsyncTask. Here is the structure of what should happen.
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(context, "", "Loading. Please wait...",
true);
}
#Override
protected EventWebservice doInBackground(Void... params) {
//call the webservice and return it
}
#Override
protected void onPostExecute(EventWebservice webservice) {
adapter = webservice.getAdapter(this);;
listView.setAdapter(adapter);
dialog.dismiss();
}
You need to read on unsynchronized ws calls and how to fill up data in a listview dynamically. Here is the code snippet below that works and will ensure that no mattter how much time the WS CAll takes there is no interruption on the GUI and the flow is smooth:
String wsResponse[];
public void sampleFunction()
{
progressDialog = ProgressDialog.show(this, "", "Getting backup list...");
new Thread() {
public void run() {
try {
//do the ws call and store the ws response in a string array
wsResponse=wsCall();
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
messageHandler.sendEmptyMessage(0);
// messageHandler.sendEmptyMessage(0);
}
}.start();
}
}
//inside the handler set the string array retrieved from the WS in sampleFunction to the adapter
private Handler messageHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
//here write the code to assign the string array to the adapter
}
};
Move your
listView.setAdapter(adapter);
progressDialog.dismiss();
adapter.notifyDataSetChanged();
into a Handler and call the method sendEmptyMessage() of Handler from the Thread.run() after you got the Adapter.
Consider this post for more information
Edit:
Your code should be look like something this.
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
//this is call the webservice to got filled adapter
adapter = new EventWebservice().getAdapter(this);
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Where your Handler will update the list. But devA's answer is best way to do such jobs.