How to send Time Triggered Notification using parse.com in Android? - android

I have implemented push notification using parse. But I want to send notification to user at specific time in their specific time-zones. I know that we can send notification to all devices at once from the dashboard. But can we trigger the notification from within the app?
Right now I just check the system date and display the data matching from my Parse class.
But I want to send a notification to the user at specific time!
Code to get system date!
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("ddMMyyyy");
final String formattedDate = df.format(c.getTime());
Code that checks date and displays relevant info!
ArrayList<HashMap<String, String>> _temparrayList = HelperFile
.loadArrayListFromFile(MainActivity.this, HelperFile.DAILYVERSE);
if (_temparrayList != null) {
for (int i = 0; i < _temparrayList.size(); i++) {
HashMap<String, String> map = _temparrayList.get(i);
if (formattedDate.equals(map.get("date"))) {
verse = map.get("verse");
book = map.get("book");
book_text.setText(book);
verse_text.setText(verse);
} else if (new_formattedDate.equals(map.get("date"))) {
verse = map.get("verse");
book = map.get("book");
book_text.setText(book);
verse_text.setText(verse);
}
else {
value = true;
new RemoteDataTask().execute();
}
}
} else {
verse_text.setText("Data Yet To Update, Please Refresh");
refresh.setVisibility(View.VISIBLE);
new RemoteDataTask().execute();
}
The Async task that makes the query from Parse!
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
if (value == false) {
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setTitle("Daily Verse Is Updating");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
}
#Override
protected Void doInBackground(Void... params) {
// Locate the class table named "Country" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"DailyVerse");
query.orderByDescending("date");
try {
ob = query.find();
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// Retrieve object "name" from Parse.com database
ArrayList<HashMap<String, String>> arrayList = new ArrayList<HashMap<String, String>>();
for (ParseObject country : ob) {
HashMap<String, String> map = new HashMap<String, String>();
String book = (String) country.get("book");
String verse = (String) country.get("verse");
String date = (String) country.get("date").toString();
map.put("book", book);
map.put("verse", verse);
map.put("date", date);
arrayList.add(map);
}
HelperFile.writeArrayListToFile(arrayList, MainActivity.this,
HelperFile.DAILYVERSE);
if (value == false) {
mProgressDialog.dismiss();
}
}
}
So the QUESTION is How will I send a notification to the user everyday at 8:00 AM?

You're going to build a kind of "worker" or "job" within your android application. I think it's not the best option. But to do a "kind" of this, you should implement +service and call startService method. I've already used Parse and I normally send user notifications by push firing by my webservice, and my worker/job is in my webservice(back-end application).
Hope it could be useful for you! =)

Related

Reload AsyncTask with new parameters

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.

keep a ProgessDialog until the callback is executed

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.

Application contacting web service more than necessary

I have an listview that contacts a web service whenever it is called and this is what it looks like
public class ListView extends ListActivity {
ArrayList<HashMap<String, String>> questionList;
final String TAG_DATA_WEB = "data";
private String stringxxx;
ProgressDialog pDialog;
LoadAllData mTask;
JSONArray question = null;
android.widget.ListView lv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.listview);
stringxxx = getIntent().getStringExtra("TAG_SEARCH");
questionList = new ArrayList<HashMap<String, String>>();
mTask = new LoadAllData();
mTask.execute();
}
#Override
protected void onListItemClick(android.widget.ListView l, View v, int pos, long id) {
super.onListItemClick(l, v, pos, id);
HashMap<String, String> item = questionList.get(pos);
Intent i = new Intent(ListView.this, SingleListItem.class);
i.putExtra(TAG_DATA_WEB, item.get(TAG_DATA_WEB));
startActivity(i);
}
#Override
public void onBackPressed()
{
/** If user Pressed BackButton While Running Asynctask
this will close the ASynctask.
*/
if (mTask != null && mTask.getStatus() != AsyncTask.Status.FINISHED)
{
mTask.cancel(true);
}
super.onBackPressed();
Intent i = new Intent(ListView.this, PREV.class);
startActivity(i);
finish();
}
#Override
protected void onDestroy() {
if (mTask != null && mTask.getStatus() != AsyncTask.Status.FINISHED)
{
mTask.cancel(true);
}
super.onDestroy();
}
#Override
protected void onPause() {
if (pDialog != null)
{
if(pDialog.isShowing())
{
pDialog.dismiss();
}
super.onPause();
}
}
class LoadAllData extends AsyncTask<String, Void, JSONObject> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ListView.this);
pDialog.setMessage("Loading Data. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected JSONObject doInBackground(String... args) {
pDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){
public void onCancel(DialogInterface dialog) {
mTask.cancel(true);
Intent i = new Intent(ListView.this, PREV.class);
startActivity(i);
finish();
}
});
JSONObject json = new JSONObject();
try {
String query = URLEncoder.encode(searchTerm, "utf-8");
String URL = "http://example.com";
JSONParsser jParser = new JSONParsser();
json = jParser.readJSONFeed(URL);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return json;
}
#Override
protected void onPostExecute(JSONObject json) {
try {
JSONArray questions = json.getJSONObject("all").getJSONArray("questions");
for(int i = 0; i < DT.length(); i++) {
JSONObject question = DT.getJSONObject(i);
String data = question.getString(TAG_DATA_WEB);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_DATA_WEB, data);
questionList.add(map);
pDialog.dismiss();
ListAdapter adapter = new SimpleAdapter(getBaseContext(), questionList,
R.layout.listelements,
new String[] { TAG_DATA_WEB }, new int[] {
R.id.Subject,});
setListAdapter(adapter);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
The problem I have is that when I click on an item on the listview to go to the next activity, it does as its suppose too with no problem its just when I pressed the back button to go back the listview, the listview activity restarts and it also contacts the web service again to retrieve the information like as if I put finish(); after startArtivity(I); in the onItemClick part of the code. Now normally this wouldn't be a problem if you web service didn't have a search limit but the one i am using does. So basically what Im saying is that when the user clicks on an listview item to go to the next activity and when they press the onBack button, I want the information to still be there instead of the application contacting the web service again to retrieve information and the end result will be the search limit being reached. Can anybody help me with this?
I have used XML parsing so I can probably give you help logically.
You can use bean class with get and set methods and store the results
you get from web service.
Use Set methods to store the values where you have written the
parsing code.
Use get methods in your activity's adapter code to retrieve those
values.
This way web service won't be called again when you reach that
activity using back button.
But remember, if you launch that activity with service again from its parent, web service will be called again.
You would have several options:
Replace the AsyncTask data loading with an AsyncTaskLoader data loading. Check the Loader developer article first. I dropped using AsyncTasks for data loading long time ago...
The scond option is to store the data you receive and don't call the webservice next time. For this, store the data somehow in onSaveInstanceState and in onCreate check if Bundle parameter is not null and if you have data set there for th same key you used in onSaveInstanceState. If true, you already have the data. If false, query.
Depending on data importance and volatility you could save it once in some kind of app persistence (shared preference or sqlite) once you downloaded it and use it every time the activity recreates or creates itself.

Managing the background thread within Android application

I currently have this class below which parses json urls and loads images and texts into a listview with the help of the Lazy Adapter Class and background thread.
Each list item consists of an image view and 2 text views.
I want to create pop up boxes (alert dialog) for each of the generated list items. The alert dialog will have options which will call other applications.
My question :
Would it be wise to code this alert dialog functionality in this class? I'm worried that there is a lot of stuff currently being done in the background and it might affect the app's functionality.
If not could anyone suggest another way to do it. thanks.
Json Activity Class :
public class JsonActivity extends SherlockActivity{
private ProgressDialog progressDialog;
// JSON Node names
static final String TAG_NAME = "name";
static final String TAG_IMAGEURL = "imageurl";
ListView list;
LazyAdapter adapter;
String chartUrl;
String[] urlNames = new String[] {
"urls..."
};
// chartItemList is the array list that holds the chart items
ArrayList<HashMap<String, String>> chartItemList = new ArrayList<HashMap<String,
String>>();
//Holds imageurls
ArrayList<String> imageurls = new ArrayList<String>();
JsonParser Parser = new JsonParser();
// JSONArray
JSONArray chartItems = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chart);
//Get the bundle
Bundle bundle = getIntent().getExtras();
//Extract the data from the bundle
int chartIndex = bundle.getInt("chartIndex");
String chartUrl = urlNames[chartIndex];
setTitle(bundle.getString("chartname"));
//url from where the JSON has to be retrieved
String url = chartUrl;
//Check if the user has a connection
ConnectivityManager cm = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null) {
if (!info.isConnected()) {
Toast.makeText(this, "Please check your connection and try again.",
Toast.LENGTH_SHORT).show();
}
//if positive, fetch the articles in background
else new getChartItems().execute(chartUrl);
}
//else show toast
else {
Toast.makeText(this, "Please check your connection and try again.",
Toast.LENGTH_SHORT).show();
}
}
class getChartItems extends AsyncTask<String, String, String> {
// Shows a progress dialog while setting up the background task
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(JsonActivity.this);
progressDialog.setMessage("Loading chart...");
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(false);
progressDialog.show();
}
//Gets the json data for chart items data and presents it in a list view
#Override
protected String doInBackground(String... args) {
String json = Parser.getJSONFromUrl(args[0]);
String imageurl;
String rank;
String name;
String url;
try{
chartItems = new JSONArray(json);
JSONObject json_data=null;
for(int i=0;i<chartItems.length();i++){
json_data = chartItems.getJSONObject(i);
//Retrieves the value of the name from the json object
name=json_data.getString("name");
//Retrieves the image url for that object and adds it to an arraylist
imageurl=json_data.getString("imageurl");
//imageurls.add(imageurl);
HashMap<String, String> hashMap = new HashMap<String, String>();
// adding each child node to HashMap key => value
//hashMap.put(TAG_RANK, rank);
hashMap.put(TAG_NAME, name);
hashMap.put(TAG_IMAGEURL, imageurl);
// adding HashMap to ArrayList
chartItemList.add(hashMap);
}
;
}
catch (JSONException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
list=(ListView)findViewById(R.id.list);
// Getting adapter by passing xml data ArrayList
adapter = new LazyAdapter(JsonActivity.this, chartItemList);
list.setAdapter(adapter);
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
}
});
}
});
return null;
}
//Removes the progress dialog when the data has been fetched
protected void onPostExecute(String args) {
progressDialog.dismiss();
}
}
}
My answer for this is Yes, it is wise enough to implement one more level network communication as far as your use case justifies it.
This depends on communication channel (EDGE/ 3G/ 4G/ WiFi) and use case of the application. Technically it is pretty much possible as far as you are doing this in background. It also depends on the size of the list which you are loading. Best way to check this is by implementing plug-able code and try it out.

Clear ListView Items and Refresh it in Android

I use internet service to fill a list view. I want to refresh the list view items when user press the refresh button. how can i do this?
In AsyncTask and postExecute i fill the list view:
protected void onPostExecute(String file_url) {
pDialog.dismiss();
try {
if (jSon.has(KEY_SUCCESS)) {
String success = jSon.getString(KEY_SUCCESS);
if (success.equals("1")) {
notes = jSon.getJSONObject("notes");
for (int i = 0; i < notes.length(); i++) {
JSONObject c = notes.getJSONObject(Integer
.toString(i));
Log.i("JSONObject c >>", c.toString());
String id = c.getString(KEY_NOTE_ID);
String subject = c.getString(KEY_NOTE_SUBJECT);
String date = c.getString(KEY_NOTE_DATE);
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_NOTE_ID, id);
map.put(KEY_NOTE_SUBJECT, subject);
map.put(KEY_NOTE_DATE, date);
noteList.add(map);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(AllNotes.this,
noteList, R.layout.list_item, new String[] {
KEY_NOTE_ID, KEY_NOTE_SUBJECT,
KEY_NOTE_DATE }, new int[] {
R.id.list_lbl_id, R.id.list_lbl_subject,
R.id.list_lbl_date });
setListAdapter(adapter);
}
});
}
The most basic approach is to empty noteList and run your AsyncTask again.
Inside onPreExecute() (or the first line of doInBackground()) call either:
noteList = new ArrayList<Map<String, String>>(); // or noteList.clear();
Call your AsyncTask's execute() method again.
Also I don't believe you need to use runOnUiThread() in onPostExecute() because it already has access to the main thread.

Categories

Resources