I'm still working on my application that has to store RSS data localy.
So far i managed to create a local database and parse the online RSS feed.
I also managed to put this information in the database so now the app will also be available while being offline.
However i can't seem to figure out how to do the following:
I have 2 buttons, one of them reads the database titles and will go to a detailed page of your selection (still working on that)
My current problem is that i can't seem to add a loading bar to pop up on the screen while the application is downloading the data from the internet. The screen is just blank for like 10 seconds and then the list pops up. here is the code that i'm using:
public class SynchDB_Activity extends ListActivity {
public List<Message> messages;
public List<String> titles;
//ProgressDialog dialog = ProgressDialog.show(SynchDB_Activity.this, "", "Downloading data...", true);
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.animal_list_view);
loadFeed();
}
private void loadFeed(){
try{
BaseFeedParser parser = new BaseFeedParser();
messages = parser.parse();
List<String> titles = new ArrayList<String>(messages.size());
DBAdapter db = new DBAdapter(this);
for (Message msg : messages){
titles.add(msg.getTitle());
db.addRow(
msg.getTitle(),
msg.getDescription(),
"bla",
"http:/",
msg.getLink());
}
//dialog.dismiss();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.row,titles);
this.setListAdapter(adapter);
} catch (Throwable t){
Log.e("AndroidNews",t.getMessage(),t);
}
}
So this code works and puts all the data in the local database. However i just cant make that loading bar working and it's driving me crazy.
If anyone could help me out i would be gratefull!!!
I've been googling all day and nothing seems to do the trick....
many thanks
edit: As you can see in the code i display the list when its done. This is not nececary, but from the moment i remove the ArrayAdapter the app won't work anymore.
Keep in mind that this all is quite new for me and i think that the main part where things are going wrong is useing the different layouts...
Use Async task and progress bar as shown here:
public void getrss()
{
try{
class test extends AsyncTask{
TextView tv_per;
int mprogress;
Dialog UpdateDialog = new Dialog(ClassContext);
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
mprogress = 0;
UpdateDialog.setTitle(getResources().getString(R.string.app_name));
UpdateDialog.setContentView(R.layout.horizontalprogressdialog);
TextView dialog_message = (TextView)UpdateDialog.findViewById(R.id.titleTvLeft);
tv_per = (TextView)UpdateDialog.findViewById(R.id.hpd_tv_percentage);
dialog_message.setText(getResources().getString(R.string.dialog_retrieving_data));
dialog_message.setGravity(Gravity.RIGHT);
UpdateDialog.setCancelable(false);
UpdateDialog.show();
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Object... values) {
// TODO Auto-generated method stub
ProgressBar update = (ProgressBar)UpdateDialog.findViewById(R.id.horizontalProgressBar);
update.setProgress((Integer) values[0]);
int percent = (Integer) values[0];
if(percent>=100)
{
percent=100;
}
tv_per = (TextView)UpdateDialog.findViewById(R.id.hpd_tv_percentage);
tv_per.setText(""+percent);
}
#Override
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
//your code
}
super.onPostExecute(result);
UpdateDialog.dismiss();
}
}
new test().execute(null);
}
catch(Exception e)
{
e.printStackTrace();
}
}
You probably want to use AsyncTask.
Related
Hi I just created app for loading data from the website once the button is clicked in android.I want to change the app for loading data when the application open.How will I do it?
Here is my code..
public class PrimaryActivity extends Activity {
private static final String URL = "http://livechennai.com/powershutdown_news_chennai.asp";
ProgressDialog mProgressDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_primary);
Button btnFetchData = (Button) findViewById(R.id.btnData);
btnFetchData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new FetchWebsiteData().execute();
}
});
}
private class FetchWebsiteData extends AsyncTask<Void, Void, String[]> {
String websiteTitle, websiteDescription,websiteDescription1,websiteDescription2,websiteDescription3,listValue,listValue1;
ProgressDialog progress;
#Override
protected void onPreExecute() {
super.onPreExecute();
//some code here
}
#Override
protected String[] doInBackground(Void... params) {
ArrayList<String> hrefs=new ArrayList<String>();
try {
// parsing here
}
} catch (IOException e) {
e.printStackTrace();
}
//get the array list values
for(String s:hrefs)
{
//website data
}
//parsing first URL
} catch (IOException e) {
e.printStackTrace();
}
//parsing second URL
} catch (IOException e) {
e.printStackTrace();
}
try{
List<String> listString = new ArrayList<String>(Arrays.asList(resultArray));
listString.addAll(Arrays.asList(resultArray1));
String [] outResult= new String[listString.size()];
int i=0;
for(String str: listString){
outResult[i]=str;
i++;
}
return outResult;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] result) {
ListView list=(ListView)findViewById(R.id.listShow);
ArrayAdapter<String> arrayAdapter=new ArrayAdapter<String>(getBaseContext(),android.R.layout.simple_list_item_1,result);
list.setAdapter(arrayAdapter);
mProgressDialog.dismiss();
}
}
}
How to load the list view when we open the app? help me to get the exact answer?
Just load it in onCreate. This is what will be called when the app is opened first. Then read about other events like onResume.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_primary);
new FetchWebsiteData().execute();
}
Call FetchWebsiteData().execute() from one of the activity lifecycle methods such as onStart, onCreate, or onResume - please refer to docs to determine which fits in your case.
Put the method which does the fetching i.e. new FetchWebsiteData().execute(); outside of the code of button click and in the activity.onResume() method.
onResume is called everytime an app comes to foreground, if you put it oncreate(), the method will be called only when the activity is created.
I am creating an Android application that runs three fragments that contain one listview in each. currently, I am trying to populate one of the listviews with content from a table that I created on Parse.com. I followed this tutorial: http://www.androidbegin.com/tutorial/android-parse-com-listview-images-and-texts-tutorial/ and applied it to work in my fragment. The problem is though, everytime I run my application, it loads the data for about 3 seconds and then suddenly crashes and gives me this error:
ddmlib: Broken pipe
java.io.IOException: Broken pipe
at sun.nio.ch.FileDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:29)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:69)
at sun.nio.ch.IOUtil.write(IOUtil.java:40)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:336)
at com.android.ddmlib.JdwpPacket.writeAndConsume(JdwpPacket.java:213)
at com.android.ddmlib.Client.sendAndConsume(Client.java:642)
at com.android.ddmlib.HandleHeap.sendREAQ(HandleHeap.java:348)
at com.android.ddmlib.Client.requestAllocationStatus(Client.java:488)
at com.android.ddmlib.DeviceMonitor.createClient(DeviceMonitor.java:835)
at com.android.ddmlib.DeviceMonitor.openClient(DeviceMonitor.java:803)
at com.android.ddmlib.DeviceMonitor.processIncomingJdwpData(DeviceMonitor.java:763)
at com.android.ddmlib.DeviceMonitor.deviceClientMonitorLoop(DeviceMonitor.java:652)
at com.android.ddmlib.DeviceMonitor.access$100(DeviceMonitor.java:44)
at com.android.ddmlib.DeviceMonitor$3.run(DeviceMonitor.java:580)
I have absolutely no idea why I am receiving this error. Here is the code from the fragment in which I am trying to populate my listview from. I am aslo using a custom adapter for the listview but I am using the same one from another project of mine so I am sure that is working fine. To fetch the data, I am calling new RemoteDataTask().execute(); in onCreateView . This is where I believe it is going wrong. I am also sure all my table names are correct in my parse database.
public class fraternitiesFragment extends Fragment {
private SwipeRefreshLayout swipeLayoutFraternities;
private ListView fratList;
List<ParseObject> objList;
ProgressDialog mProgressDialog;
fraternitiesAdapter fratAdapter;
private List<Frat> fraternitiesList = null;
public fraternitiesFragment()
{
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frat_fragment, null);
// Retrieve the SwipeRefreshLayout and ListView instances
swipeLayoutFraternities = (SwipeRefreshLayout)view.findViewById(R.id.swipe_refresh_fraternities);
swipeLayoutFraternities.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override public void run() {
swipeLayoutFraternities.setRefreshing(false);
}
}, 3000);
}
});
// Set the color scheme of the SwipeRefreshLayout by providing 4 color resource ids
swipeLayoutFraternities.setColorScheme(
R.color.tech_blue,
R.color.tech_gold,
R.color.tech_blue,
R.color.tech_gold);
new RemoteDataTask().execute();
return view;
}
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.setTitle("Loading Fraternities");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
fraternitiesList = new ArrayList<Frat>();
try{
ParseQuery<ParseObject> fraternitiesQuery = new ParseQuery<ParseObject>("Fraternities");
Log.i("Query", " Created");
fraternitiesQuery.orderByAscending("fratName");
objList = fraternitiesQuery.find();
for(ParseObject Fraternity : objList)
{
Frat fraternity = new Frat();
fraternity.setFratName((String) Fraternity.get("fratName"));
fraternity.setVoteCount((Integer) Fraternity.get("VoteCount"));
fraternitiesList.add(fraternity);
}
} catch (ParseException e)
{
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
fratList = (ListView)getActivity().findViewById(R.id.frat_list);
fratAdapter = new fraternitiesAdapter(getActivity(), fraternitiesList);
Log.d("Adapter Created", "Created");
mProgressDialog.dismiss();
fratList.setAdapter(fratAdapter);
}
}
}
I really need help figuring out what is going wrong here that is leading to this Broken Pipe error. Any help or feedback is greatly appreciated!
Parse has already async methods, Try this
ParseQuery<ParseObject> query = ParseQuery.getQuery("Fraternities");
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> fraternityList, ParseException e) {
// Do your work here
}
});
my screen when I click on a button is slow to load (because of downloading images? the image files are really small though) so I tried to use AsyncTask to help. The program works, but I moved the image loading to an AsyncTask to see if it would load faster and the app crashes every time. I'm guessing it has to do with the way I have it set up. How would I fix it? Would using a runnable thread be better instead? Thanks!
The class:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// no title
requestWindowFeature(Window.FEATURE_NO_TITLE);
// set full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// inflate listview
setContentView(R.layout.gmg);
**new Load.execute(); // executes AsyncTask**
...
gmgListView = (ListView) findViewById(R.id.gmg_list2);
GMGListViewAdapter adapter = new GMGListViewAdapter(this,
R.layout.gmg_list_row, rowItems);
gmgListView.setAdapter(adapter);
gmgListView.setOnItemClickListener(this);
}
The AsyncTask:
private class Load extends AsyncTask<String, Void, Void> {
private ProgressDialog Dialog = new ProgressDialog(GMGListViewActivity.this);
#Override
protected void onPreExecute() {
Dialog.setMessage("Doing something...");
Dialog.show();
}
#Override
protected Void doInBackground(String... params) {
SparseArray<Spanned> gmgText = null;
Integer[] right = null;
SparseArray<Drawable> appIcon = null;
try {
gmgText = ParseContent.queryGMGText();
right = ParseContent.queryGMGRight();
appIcon = ParseContent.queryDrawable();
} catch (ParseException e) {
e.printStackTrace();
}
// Inflate GMG's rows
rowItems = new ArrayList<GMGRowItem>();
for (int i = 0; i < gmgText.size(); i++) {
GMGRowItem item = new GMGRowItem(appIcon.get(i), gmgText.get(i), right[i]);
rowItems.add(item);
}
return null;
}
protected void onPostExecute(Void unused) {
Dialog.dismiss();
}
}
You need to apply some changes in your code like...
need to set list adapter in onPostExecute method and remove it from onCreate().
After completing background process it will interact with ui thread.
protected void onPostExecute(Void unused) {
Dialog.dismiss();
GMGListViewAdapter adapter = new GMGListViewAdapter(this,
R.layout.gmg_list_row, rowItems);
gmgListView.setAdapter(adapter);
}
Try this and let me know if you got any isssue.
I am unable to refresh my listview. I know there are lots of help available for this. But I am unable to get my listview refreshed.
Lemme edit my code a little bit showing the AsyncTask
There are two Activities. The first Activity is having the list view to see what is being shared and the second activity has an edit text box (to input inorder to share) and a button. On clicking the button, it returns me the string which is the json response and I need to add this in the previous activity.
Now the problem is, when I refresh the first page fully hitting the server it gets the response but this is not what I want. It should not go back to the server. It should simply add in the list view adapter.
I have commented the code in the PostExecute(). I have tried the everyway but it is not reflecting.
public class ShareAsyncTask extends AsyncTask<String, Void, ArrayList<EventsStreamBean>> {
public ProgressDialog pd = new ProgressDialog(EventStreamActivity.this);
String success_share_val;
#Override
protected ArrayList<EventsStreamBean> doInBackground(
String... result) {
// TODO Auto-generated method stub
JSONObject jsonobj = new JSONObject(result[0].toString());
success_share_val = jsonobj.getString(Constants.SUCCESS);
//checks the success value
if(success_share_val.equalsIgnoreCase("1")) {
JSONArray events_stream_share_array = jsonobj.getJSONArray("streamArray");
if(events_stream_share_array.length() > 0) {
for(int i=0; i<events_stream_share_array.length(); i++) {
EventsStreamBean events_stream_bean = new EventsStreamBean();
JSONObject events_stream_object = events_stream_share_array.getJSONObject(i);
events_stream_bean.setStreamId(events_stream_object.getString(Constants.STREAM_ID));
events_stream_bean.setStreamType(events_stream_object.getString(Constants.STREAM_TYPE));
events_stream_bean.setUserId(events_stream_object.getString(Constants.USER_ID));
events_stream_bean.setUserName(events_stream_object.getString(Constants.USER_NAME));
events_stream_bean.setUserType(events_stream_object.getString(Constants.USER_TYPE));
events_stream_bean.setUserAvatar(events_stream_object.getString(Constants.USER_AVATAR));
arraylist_events_stream.add(events_stream_bean);
}
}else {
Log.i("Test", "No Events Streams Available");
}
}
}catch(Exception e) {}
return arraylist_events_stream;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
this.pd.setMessage("Loading....");
pd.setCanceledOnTouchOutside(false);
pd.setCancelable(false);
this.pd.show();
}
#Override
protected void onPostExecute(final ArrayList<EventsStreamBean> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(this.pd.isShowing()) {
this.pd.dismiss();
}
Toast.makeText(EventStreamActivity.this, "Post shared successfully", Toast.LENGTH_SHORT).show();
new EventsStreamAsyncTask().execute(temp_val);
/*runOnUiThread(new Runnable() {
public void run() {
//EventStream_Customadapter adapter = (EventStream_Customadapter) list_view.getAdapter();
//adapter.clearData();
adapter.updateData(result);
//adapter = new EventStream_Customadapter(EventStreamActivity.this, arraylist_events_stream);
//list_view.setAdapter(adapter);
//adapter.notifyDataSetChanged();
}
});*/
}
}
You should call setAdapter() only once in your entire code.
Then add a method in your adapter that adds more data when you want to add more data or sets adapter item.
public void addMoreData(List<String> newItems) {
this.list.addAll(newItems);
}
public void setList(List<String> newList) {
this.list = newList;
}
Call notifyDataSetChanged() after you set new list or add more data.
as per what you want to achieve there is no need for you to use threads
have a look at the following link it shows how to do it in the same activity
http://wptrafficanalyzer.in/blog/dynamically-add-items-to-listview-in-android/
In this they have done it in a single activity. if you want to do it with 2 activities let me know i will tell you how to do it.
In my AsyncTask, I use Jsoup to pull all of the p tags from a web page, and I add them to an ArrayList that should then be used by an ArrayAdapter to fill the screen with the posts, but for some reason, the ArrayList is empty when I go to check it after the methods.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
newsItems = new ArrayList<String>();
fillNewsItems();
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
newsItems));
Log.d("news", Integer.toString(newsItems.size()));
}
private class GetNewsItemsTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
try {
Document doc = Jsoup.connect(URL).get();
for (Element e : doc.getElementsByTag("p")) {
newsItems.add(e.text());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Couldn't fetch articles, try again later.",
Toast.LENGTH_SHORT).show();
}
return null;
}
}
private void fillNewsItems() {
GetNewsItemsTask getNews = new GetNewsItemsTask();
getNews.execute(URL);
}
}
Does anyone know why the log statement in onCreate returns 0, and my list is empty?
AsyncTask has more possibilities than you are using right now. Basically the AsyncTask is a thread (which cannot change UI elements by default) but it provides a special feature: it synchronizes to the UI thread in the method onPostExecute().
So you can use this to set the ArrayAdapter inside the AsyncTask. Feel free to make use of onPreExecute() to show an information dialog.
This code should to the trick:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fillNewsItems();
Log.d("news", Integer.toString(newsItems.size()));
}
private class GetNewsItemsTask extends AsyncTask<Void, Void, ArrayList<String>> {
protected ArrayList<String> doInBackground(Void... urls) {
try {
ArrayList<String> items = new ArrayList<String>();
Document doc = Jsoup.connect(URL).get();
for (Element e : doc.getElementsByTag("p")) {
items.add(e.text());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Couldn't fetch articles, try again later.",
Toast.LENGTH_SHORT).show();
}
return items;
}
#Override
protected void onPostExecute(ArrayList<String> items) {
newsItems = items; // I assume that newsItems is used elsewhere.
// If that's not the case -> remove it
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
items));
}
}
private void fillNewsItems() {
GetNewsItemsTask getNews = new GetNewsItemsTask();
getNews.execute();
}
This a nice tutorial about asynchronous programming in Android: Android Threads, Handlers and AsyncTask
Most likely because the AsyncTask hasn't finished executing yet.
An AsyncTask is just that, async. It runs in the background at the same time.
It looks like you are expecting your code to block on fillNewsItems() until the AsyncTask
has finished, when in reality it returns almost immediately, right after starting the AsyncTask. So when you are trying to get the size of the list it still is zero, the AsyncTask hasn't finished yet.