How to show array element through timer - android

I have a String type array. I want to show each element in a TextView after a little time slice that means after certain time the element of array is showing in a TextView again and again. So I am using timer, but it is showing only last element of array. Please solve my problem as soon as possible.
protected void onPostExecute(Void result) {
try {
super.onPostExecute(result);
listAdapter = new ExpandableListAdapter(getActivity(), listDataHeader, headerChild, expListView);
expListView.setAdapter(listAdapter);
int j=0, k=1;
if (prog.isShowing()) {
prog.dismiss();
expListView.setBackgroundColor(0xFFFFFFFF);
String af="";
String cf="";
for(int i=0; i<breakstore2.length; i++){
cf=breakstore2[j];
af= breakstore2[k];
new Handler().postDelayed(new Runnable() {
public void run() {
marquee.setText("Breaking News :" + af);
marquee.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent mainIntent = new Intent(getActivity(),h_nextpage2.class);
mainIntent.putExtra("listitem", cf);
startActivity(mainIntent);
}
});
}
}, DISPALY_LENGTH);
j=j+2;
k=k+2;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

The method is updating the UI faster than you wanted...what you can do is that you can create an IntentService and send that service the data that need to be put on your screen.
Create Messenger in your main activity where you need to update the UI and also create an Handler in the same. And from your AsyncTask post the updates to the intentService in that you can delay the updation by sleeping the intentServices' thread and then sending a message to the messenger on the main activity containing the data which you need to show (in your case breaking news) which in turn will do the updation for you.

Related

How to refresh listview AsyncTask

I have a json file and I want to check this json every minute because my json changes every minute.
I can parse json from an url in this way;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
runOnUiThread(new Runnable() {
#Override
public void run() {
new ReadJSON().execute("http://www.url.com/json1.json");
}
});
}
class ReadJSON2 extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
return readURL(params[0]);
}
#Override
protected void onPostExecute(String content) {
try {
JSONObject jsonObject = new JSONObject(content);
JSONArray jsonArray = jsonObject.getJSONArray("level");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject c = jsonArray.getJSONObject(i);
JSONArray server = c.getJSONArray("server");
for(int j=0; j<server.length(); j++){
JSONObject serverObject = server.getJSONObject(j);
String name = serverObject.getString("name");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
How can I check this json every minute?
I did everything, but I didn't it.
Thank you for your help.
Use listview.invalidateViews(); or adapter.notifyDataSetchanged(); method in onPostExecute method after parsing your json.
This method works if some of the contents have been changes/added/removed in the list that is attached to the adapter.
So whenever you parse your data . make sure the object of adapter and the List/JsonArray remain same. Means dont initialize it every time on web service result. Just use it like this -> list.add(some data); and jsonArray.put(some data);
Let me know if i misunderstood.
We can use TimerTask to solve this problem:
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
//use a handler to run a toast that shows the current timestamp
handler.post(new Runnable() {
public void run() {
new ReadJSON().execute("http://www.url.com/json1.json");
}
});
}
};
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, after the first 0ms the TimerTask will run every 1m
timer.schedule(timerTask, 0, 60 * 1000); //
}
An on ur postExe, after parse JSON, u should check Adapter here, if it's was empty for first time, you set adapter by this json, and if it's already has data, please call adapter.notifyDataSetChanged()

Making an app Truly Async (Android)

I am building an application that is pretty dependent on async requests to function.
I have the main Activity called MainActivity. This really doesn't do much apart from contain layouts, however it does have a recycleviewer.
I then have a couple of http requests that are done to populate the recycle viewer.
To do this I have wrote a java class as follows:
public class dataforUi extends AsyncTask<String, String, JsonObject> {
private ArrayList<UiElements> els;
protected void onPreExecute() {
progressDialog.setMessage("Downloading your data...");
progressDialog.show();
progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface arg0) {
RedditRequests.this.cancel(true);
}
});
}
protected JsonObject doInBackground(String... params) {
Do the http request here, get the result and populate uiElements with it
}
#Override
protected void onPostExecute(JsonObject jsonObject) {
super.onPostExecute(jsonObject);
progressDialog.hide();
}
I have a few more classes like this but hopefully it serves as an example of what I'm trying to do.
Then back in Main Activity, I have this code:
public void getUiElements() {
dataforUi ui = new dataforUi(findViewById(android.R.id.content));
try {
ui.execute("https://t").get();
ArrayList<UiElements> r = ui.getEls();
Log.d("MainFeedScreen", "Size of r is:" + r.size());
UiAdapter = new UiAdapter(r);
mRecyclerView.setAdapter(UiAdapter);
} catch (Exception e) {
}
}
This works fine, but it is very jolty due to the use of .get() on execute to make it blocking. If i remove .get() the progress bar shows up and disappears when the task is done, but my ui thread has progressed past this and ha tried to populate my view with an Empty Array and therefore nothing shows.
I have done a bit of looking into it but cant find a conclusive way of managing the notification of the UI thread that an activity is done.
Would really appericiate any advice on this one.
You need to fix your design.
On post execute, use local broadcast to notify your MainActivity that the AsyncTask is done.
Try using a separate thread to process your data. I use a ListView in stead of a RecyclerView, but the principle is the same.
I have no problems with jolting views.
protected void onPostExecute(String result) {
final String value = result;
// dismiss the dialog after getting all data
progressDialog.dismiss();
if (!value.isEmpty()) {
// updating UI from a new thread
runOnUiThread(new Runnable() {
public void run() {
// ListData is my custom class that holds my data
ArrayList<ListData> arrayDriverListData = new ArrayList<ListData>();
ListDataAdapter adapter = new ListDataAdapter(ListActivity.this, arrayListData);
ListData data;
boolean b = true;
try {
// My data is from a Json source from node 'history'
JSONObject object = new JSONObject(value);
JSONArray array = object.getJSONArray("history");
int len = array.length();
if (len > 0) {
for (int i = 0; i < len; i++) {
final JSONObject o = array.getJSONObject(i);
// Parse my data and add it to my adapter
adapter.add(data);
}
}
} catch (JSONException jex) {
Log.e(TAG, "" + jex.getMessage());
}
// setListAdapter is my call to update my list view
setListAdapter(adapter);
}
});
}
}
Now just update the UI thread
private void setListAdapter(ListDataAdapter adapter){
// my ListView
lvHistory.setAdapter(adapter);
}

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.

Queue-ing image paths for later upload

I'm having difficulties keeping track of my queue and uploading them at a later moment.
The upload image is a asynctask and in the postexecute a mail is going out to send the uploaded picture.
This is my UploadImage AsyncTask. I think i'm doing way too difficult and that it can be done much easier than it is right now.
private class UploadImageTask extends AsyncTask<Void, Void, Integer> {
ProgressDialog dialog;
/**
* Private integer which counts how many times we've tried to upload the
* Image.
*/
private int _counter = 0;
private List<String> imageUploadList = new ArrayList<String>();
#Override
protected void onPreExecute() {
super.onPreExecute();
if(AppStatus.haveNetworkConnection(_context)){
if(isPhotoTaken()){
dialog = new ProgressDialog(Step4.this);
dialog.setCancelable(false);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(getString(R.string.uploadingMessage));
dialog.setTitle(getString(R.string.uploadingTitle));
dialog.show();
}
}
}
protected Integer doInBackground(Void... params) {
init();
postData();
return null;
}
public void init(){
_counter = 0;
_beenHere = true;
for(String path : imageUploadList){
Debug.out("Path: "+path);
}
}
public void postData() {
if (isPhotoTaken()) {
if(AppStatus.haveNetworkConnection(_context)){
if(_beenHere){
ImageUploader.uploadFile(getPhotoPath(),
"http://obo.nl/android-upload-image.php", Step4.this);
} else {
for(String path : imageUploadList){
Debug.out(path);
ImageUploader.uploadFile(path,
"http://obo.nl/android-upload-image.php", Step4.this);
}
}
} else {
if (_counter == 0) {
_counter++;
_activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(_context,
getString(R.string.noInternetImageNotUploaded),
Toast.LENGTH_LONG).show();
}
});
imageUploadList.add(getPhotoPath());
}
try {
if(_beenHere){
_beenHere = false;
goToNextIntent();
}
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
postData();
}
}
}
private void goToNextIntent(){
Intent intent = new Intent(Step4.this, Step5.class);
intent.putExtra(EXTRA_MESSAGE, (Serializable) _user);
intent.putExtra(EXTRA_MESSAGE2, _isRepairable);
intent.putExtra(EXTRA_MESSAGE3, _injury);
intent.putExtra(EXTRA_MESSAGE4, _category);
intent.putExtra(EXTRA_MESSAGE5, _inch);
intent.putExtra(EXTRA_MESSAGE6, _size);
startActivity(intent);
}
protected void onPostExecute(Integer result) {
if(isPhotoTaken()){
if(dialog != null){
dialog.dismiss();
}
}
mailing(_isRepairable);
new MyAsyncTask().execute(_mail);
}
}
The line:
if(AppStatus.haveNetworkConnection(_context))
returns a boolean true if the user has a working internet connection. false otherwise.
What I want is to queue all the image paths (and mails sent afterwards) in the desired ArrayList so i can send them all at a later moment when the user has a working internet Connection. Please help me out!
You could store your image paths in a list (or something similar) and persist the list, let's say in Shared Preferences. As you finish uploading a picture, you will remove it from that list and continue to the next one, and so on until your list is empty.
While uploading, if the internet connection drops it will not affect you, you will always have persisted the list of images that are still to be uploaded.
Register a broadcast receiver to listen for wi-fi connection, when it gets connected it could automatically continue the upload - this is just a suggestion.

AsyncTask displaying progress bar

I am very new to android. I got two activities A, B . Activity A parse the data from the sever and iterate through the levels. and calls the activity B through intent. Activity B takes some time to display the data so I am trying to display the progress bar. Here is my code.
public class Display extends Activity {
ProgressDialog dialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.attributequestions);
new asynctask().execute();
}
class asynctask extends AsyncTask<Context,Void,Void>{
Survey[] surveyque=null;
// i hace created seperated class forsurvey that has info about data
String list[];
private ProgressDialog Dialog;
#Override
protected void onPreExecute()
{
Dialog=ProgressDialog.show(Display.this, "Parsing Data", "Please wait..........");
}
#Override
protected void onPostExecute(Void unused)
{
try
{
if(Dialog.isShowing())
{
Dialog.dismiss();
}
Intent intent=getIntent();
}
catch(Exception e)
{
Log.d("Onsitev4", "error");
}
}
#Override
protected Void doInBackground(Context... params) {
try {
LinearLayout layout1 = (LinearLayout) findViewById(R.id.linearLayout1);
//getting exception here. I dont understant why
// I have declared layout params and displaying activities in another class
ButtonView c = new ButtonView();
c.layout=layout1;
c.context =getBaseContext();
DbCoreSqlSurveys surveys=new DbCoreSqlSurveys(getBaseContext());
Document doc =surveys.getSurveySet();
surveyquestions= GetSurveyLevels(doc,c );
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
}
return null;
}
}
public SurveyObject[] GetSurveyLevels(Document doc, ButtonView c) {
NodeList nlQuestions = doc.getElementsByTagName("Survey");
SurveyObject[] allsurveys = new SurveyObject[nlQuestions.getLength()];
for (int i = 0; i < nlQuestions.getLength(); i++){
Node survey = nlQuestions.item(i);
String f =survey.getNodeName();
Log.d("OnsiteV4", "survey " + f);
NodeList surveyChildNodes = survey.getChildNodes();
SurveyObject s=new SurveyObject();
for (int j = 0; j < surveyChildNodes.getLength(); j++){
Node surveyChild = surveyChildNodes.item(j);
String h =surveyChild.getNodeName();
Log.d("OnsiteV4", "survey child node = " + h);
if (h !="#text"){
Surveys t = Surveys.valueOf(h);
switch(t){
case KeySurvey:
s.KeySurvey=surveyChild.getTextContent();
displaySurveyLink(s.SurveyDescription,"",c,0,s.SurveyDescription,"","","","");
break;
case SurveyDescription:
s.SurveyDescription=surveyChild.getTextContent();
displaySurveyLink(s.SurveyDescription,"",c,0,s.SurveyDescription,"","","","");
break;
case SurveyUserCode:
s.SurveyUserCode=surveyChild.getTextContent();
break;
case Level1:
if(surveyChild.hasChildNodes()){
s.Level1= processLevel1Nodes(surveyChild,c,s.SurveyDescription);
}
break;
default:
break;
}
}
allsurveys[i]=s;
}
}
return allsurveys;
}
// methods iterating through levels that is not showed
private void displaySurveyLink(final String description, String tag, ButtonView c, int indentation, final String surveyDescription, final String level1description, final String level2description, final String level3description, final String level4description)
{
if (description == null || tag == null){
return;
}
final TextView tv = c.addButton(description,tag,indentation);
tv.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
final Intent intent = new Intent();
intent.setClass(v.getContext(),ActivityB.class);
intent.putExtra("KeyLevel",tv.getTag().toString());
intent.putExtra("SurveyDescription",surveyDescription);
intent.putExtra("level1description",level1description);
intent.putExtra("level2description",level2description);
intent.putExtra("level3description",level3description);
intent.putExtra("level4description",level4description);
intent.putExtra("Description",description);
if (tv.getTag() != null){
if (tv.getTag().toString() != ""){
startActivity(intent);
}
}
}
});
}
}
I am getting exception in doinbackground. I am confused . please help me..
You are getting an exception because you are accessing UI elements on a non-UI thread. The main thread that the application creates is the UI thread, and that's where all of your visual elements are created and therefore the only thread in which you should access them.
To appropriately use AsyncTask, you run your long-running operations in doInBackground, and you use onPreExecute, onPostExecute and onProgressUpdated to work with the UI (show/hide progress dialogs, update views, etc). Whenever I use an AsyncTask and I want to show progress, I override onProgressUpdated giving it parameter type Integer and I call publishProgress from doInBackground. This would require a change of the base class signature from AsyncTask<Context,Void,Void> to AsyncTask<Context,Integer,Void>. You can use other object types for this as well...I just use Integer as an example if you want to show the percentage of the task that is complete, for example.
It's becoz your code should throwing exception as you are doing UI stuff in the doinbackgound of asyc task. Please remove all the UI related work from doingbackgound method.

Categories

Resources