I want to show listview from web directory file list. How to access web directory file list in android.
Ex:http://mp3.com/song/
this is the web directory.
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// JSONObject json = JSONfunctions
// .getJSONfromURL("http://selangorbn.fm/song/");
// Log.d("TAG", "json" + json);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
new Getparse().execute();
}
private void parse() throws IOException {
String line = null, response;
URL url = new URL("http://selangorbn.fm/song/");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
while (rd.readLine() != null) {
line += rd.readLine();
}
System.out.println(line);
}
public class Getparse extends AsyncTask<Void, Void, integer> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected integer doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
parse();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
getting null value.
This does not work for you because you try to talk with Internet on the main application thread. Doing so would stall the application till the reply is received. Hence Android has internal checks. You should get network on main thread exception from your code.
You need to launch a separate thread and talk with the server from there. After you get your list, use runOnUiThread to update your results (you cannot touch any GUI elements from your network thread).
Parsing HTML is only reasonable if this is all you can get from the uncooperative third party server. As kumar suggests, use JSON or XML if you can.
try {
org.jsoup.nodes.Document doc = Jsoup.connect("https://test.com/appdata/0131").get();
doc.select("img").remove();
Elements links = doc.select("a");
List<String> listmainlinks = new ArrayList<>();
List<String> listweblinks = new ArrayList<>();
for (org.jsoup.nodes.Element link : links) {
String linkInnerH = link.html();
String linkHref = link.attr("href");
System.out.println("linkHref: "+ linkHref);
System.out.println("linkInnerH: "+ linkInnerH);
if(linkInnerH.equals("") ||linkInnerH.equals(" ")||linkInnerH.equals(null) || linkHref.contains("?C=N;O=D")|| linkHref.contains("?C=M;O=A")||linkHref.contains("?C=S;O=A") ||linkHref.contains("?C=D;O=A")){ }
else if(linkHref.contains("/"))
{
if(!linkInnerH.contains("Parent Directory"))
listmainlinks.add(linkHref);
}
else{
listweblinks.add("https://test.com/appdata/0131" + linkHref);
}
}
System.out.println("listmainlinks "+ listmainlinks);
System.out.println("listweblinks "+listweblinks);
/* Elements img = doc.getElementsByTag("img");
int counter = 0;
for (org.jsoup.nodes.Element el : img) {
// If alt is empty or null, add one to counter
if(el.attr("alt") == null || el.attr("alt").equals("")) {
counter++;
}
System.out.println("image tag: " + el.attr("src") + " Alt: " + el.attr("alt"));
}
System.out.println("Number of unset alt: " + counter);*/
} catch (IOException e) {
e.printStackTrace();
}
https://test.com/appdata/
I/System.out: listmainlinks [0216/, 0128/, 0131/]
I/System.out: listweblinks []
https://test.com/appdata/0131/
I/System.out: listmainlinks []
I/System.out: listweblinks [https://test.com/appdata/0131/logo.png]
Using JSOUP you can list all the files in the remote directory. But one problem i faced is if there is home page(Ex: index.html) in that directory, then it is not reading beyond that file. This is one drawback.
You can use jsoup to get the href tags linking with folders with their names
Document doc = Jsoup.connect(urltod).timeout(0).get();
doc.select("img").remove();
Elements links = doc.select("a");
List<String> listmainlinks = new ArrayList<>();
List<String> listnumberslinks = new ArrayList<>();
List<String> listweblinks = new ArrayList<>();
for (Element link : links) {
// String linkOuterH = link.outerHtml(); //allhreaf incl name
String linkInnerH = link.html(); // foldername
String linkHref = link.attr("href"); //folderlink
// System.out.println("linkHref "+linkInnerH );
if(linkInnerH.equals("") ||linkInnerH.equals(" ")||linkInnerH.equals(null) ){ }
else{
if(linkInnerH.contains("size=\"2\"")){
String[] afterfonttagarray =linkInnerH.split("\">");
String afterfonttag = afterfonttagarray[1];
String[] beforefonttagarray =afterfonttag.split("</font>");
String beforefonttag = beforefonttagarray[0];
listmainlinks.add(beforefonttag);
listweblinks.add("http://www.abc.com/audio/"+linkHref);
}
}
System.out.println("listmainlinks "+ listmainlinks); "+listnumberslinks);
System.out.println("listweblinks "+listweblinks);
this will give you the folder name as well as the links associated with them later you can use
ArrayList> albumsList to store and iterate to list or anything
Related
I am storing the data that I parsed from the JSON that is returned by my API request into the Firebase database.
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String APIURL = "https://api.github.com/users/" + idInput.getText().toString();
String repoURL = "https://api.github.com/users/" + idInput.getText().toString() + "/repos";
new JSONTask().execute(APIURL);
//new JSONTask().execute(repoURL);
String parsedUserID = idInput.getText().toString();
SM.sendDataToProfile(parsedUserID);
viewPager.setCurrentItem(1);
//addUser(parsedUserID);
}
});
When the button is clicked, it calls a new JSONTask (asynctask) on the APIURL.
JSONTask
public class JSONTask extends AsyncTask<String, String, String> {
#Override
// Any non-UI thread process is running in this method. After completion, it sends the result to OnPostExecute
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
// Pass in a String and convert to URL
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
// Reads the data line by line
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer strBuffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
strBuffer.append(line);
}
// If we are able to get the data do below :
String retreivedJson = strBuffer.toString();
return retreivedJson;
// When we are not able to retreive the Data
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
// close both connection and the reader
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
And it does parsing in another function.
My question is, as you can see on my setOnClickListener, I tried to make two JSONTask on two different URLs because the first URL gives me the information of the user and the second URL (repoURL) gives me the information of the user's repositories. I tried to fetch the repo info of the user and store it into the DB, but it seems like this is a wrong approach.
What is a right way to call two separate AsyncTasks on two different URLs?
EDIT
private void addUserRepo(final String githubID, final String[] repoList) {
DatabaseReference users = databaseReference.child("users");
users.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List list = new ArrayList<String>(Arrays.asList(repoList));
databaseReference.child("users").child(githubID).child("Repos").setValue(list);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Using data parsed from
public void formatJSONArray(String results){
try {
JSONArray jsonArray = new JSONArray(results);
RepoInfo[] repoList = new RepoInfo[jsonArray.length()];
for(int i = 0; i < jsonArray.length(); i++){
JSONObject jsonObject=jsonArray.getJSONObject(i);
if(jsonObject.optString("name") != null) {
repoList[i].setRepoName(jsonObject.getString("name"));
//repoNameList.add(jsonObject.getString("name"));
}
if(jsonObject.optString("description") != null) {
repoList[i].setDescription(jsonObject.getString("description"));
//descriptionList.add(jsonObject.getString("description"));
}
if(jsonObject.optJSONObject("owner") != null){
JSONObject ownerObject=jsonObject.getJSONObject("owner");
if(ownerObject.optString("login")!=null) {
repoList[i].setOwner(ownerObject.getString("login"));
//userNameList.add(ownerObject.getString("login"));
}
}
}
} catch (JSONException jsonException){
}
}
The response of two different URLs will surely not be similar. So you need different parse methods for them.
One lazy way would be to use two different AsyncTasks subclasses for two different urls.
Another way would be to store a flag inside the asynctask indicating whether it is dealing with user or repo.
public class JSONTask extends AsyncTask <String , String , String> {
boolean fetchingRepo;
#Override
protected String doInBackground (String... params) {
fetchingRepo = params[0].endsWith("/repos");
//other statements
}
Now inside onPostExecute:
if(fetchingRepo){
//parse one way
} else {
//parse another way
}
I am currently working with the tab host and fragment. Currently I set fragment a to download json A and fragment B to download json B , the problem is when I switch fragment, the fragment A onPostExecute function will fall into the fragment B one , is there any way to fix this?
Thanks
Tab host:
tabHost = (FragmentTabHost) findViewById(R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), R.id.tabcontent);
tabHost.addTab(
tabHost.newTabSpec("Home").setIndicator("",
res.getDrawable(R.drawable.btn_about)), Home.class,
null);
tabHost.addTab(
tabHost.newTabSpec("About").setIndicator("",
res.getDrawable(R.drawable.btn_about)), About.class,
null);
The async task
public class JSONReader {
public static final String TAG = "JSONReader";
public ArrayList<Record> records;
public Record myRecordObj;
public ArrayList<GalleryImage> images;
public String url;
public int failCount = 0; // retry twice
public Context ctx;
public String readCase;
public JSONReader(String _url, Context _ctx , String _readCase) {
url = _url;
ctx = _ctx;
readCase = _readCase;
}
public void getJSON() {
new JSONDownload().execute(url);
}
private class JSONDownload extends AsyncTask<String, Void, JSONObject> {
// TODO Auto-generated method stub
StringBuilder builder = new StringBuilder();
String temp = "";
String json = ""; // json content
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
#Override
protected JSONObject doInBackground(String... params) {
// TODO Auto-generated method stub
try {
Log.d(TAG, "Start reading: " + url);
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
return null;
// return "Server returned HTTP " + connection.getResponseCode()
// + " " + connection.getResponseMessage();
input = connection.getInputStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(input));
while ((temp = reader.readLine()) != null) {
builder.append(temp);
}
json = builder.toString();
} catch (Exception e) {
return null;
} finally {
try {
if (input != null)
input.close();
if (output != null)
output.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
try {
return new JSONObject(json);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(JSONObject result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
onJSONDownloaded(result);
}
}
public void onJSONDownloaded(JSONObject result) {
// TODO Auto-generated method stub
if (result != null) {
failCount = 0;
if (readCase.equals("leaderBoard")){
records = new ArrayList<Record>();
try {
JSONObject myRecord = result.getJSONObject("myRecord");
if (myRecord != null) {
myRecordObj = new Record(myRecord.getString("pic"),myRecord.getString("name"),myRecord.getString("score"));
}
JSONArray topRecords = result.getJSONArray("topRecord");
for (int i = 0; i < topRecords.length(); i++) {
JSONObject topRecord = topRecords.getJSONObject(i);
String topName = topRecord.getString("name");
String topPic = topRecord.getString("pic");
String topScore = topRecord.getString("score");
records.add(new Record(topPic, topName, topScore));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
((LeaderBoardDetail)ctx).setData(records,myRecordObj);
} else if (readCase.equals("galleryList")){
images = new ArrayList<GalleryImage>();
try {
JSONArray imageList = result.getJSONArray("images");
for (int i = 0; i < imageList.length(); i++) {
JSONObject image = imageList.getJSONObject(i);
images.add(new GalleryImage(image.getString("url"),image.getString("thumbUrl"),image.getString("category"),image.getString("userPic"),image.getString("name")));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//exception
if (((FragmentActivity) ctx).getSupportFragmentManager().findFragmentById(R.id.tabcontent).getTag().equals("Gallery")) {
PhotoGallery galleryFragment = (PhotoGallery) ((FragmentActivity) ctx).getSupportFragmentManager().findFragmentById(R.id.tabcontent);
galleryFragment.setData(images);
}
}
} else {
if (failCount <= 1) { // check global_conf twice if fail
failCount++;
Log.d(TAG, "No of retry" + failCount);
new JSONDownload().execute(url); // Retry download json
} else {
failCount = 0;
}
}
}
}
I used it in my app this way which works for me and answer is a bit similar to another answer but few additions and more detail. Hope it help you too.
NOTE: This is just a idea, u need to try, it may vary as per your app architect.
At your activity make the task object global [make sure set task obj null once task is finish]
JSDownload js = null;
public void getJSON() {
if(js != null && js.getStatus() == AsyncTask.Status.RUNNING)
{
js.cancel(true);
if(js.isCancelled())
{
js = new JSONDownload();
js.execute(url);
}
else
{
js = new JSONDownload();
js.execute(url);
}
}
At the Async class side....[make sure u take care null result # onpostExcute]
class JSONDownload extends AsyncTask<String, Void, JSONObject>
{
protected JSONObject doInBackground(String... params) {
// TODO Auto-generated method stub
try {
if(!this.isCancelled())
{
//make http connection ..
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
//as we are in steps in bg check iscancel .. again
//if its a loop here we call break; and return null once only..
if(this.isCancelled())
return null;
// connection status check and get buffer etc .. code here
if(this.isCancelled())
return null;
//read data
return data;
}
} catch (Exception e) {
return null;
}
}
#Override
protected void onCancelled(){
// If you write your own implementation, do not call super.onCancelled(result).
}
}
Use the global async task variable
LongOperation LongOperationOdeme = new LongOperation();
and set:
LongOperationOdeme.cancel(true);
This will stop any async task running at that moment, it's what the back button does
If you are not looking for a simplest answer but for a maybe more interesting and elegant, have a peek at this article, especially if you find functional programming interesting.
It's easier than it looks, i was almost unfamiliar to FP before this article but it covers common problems related to AsyncTask and asynchronicity in Android in general, so I got the gist and consider to use Observables instead of AsyncTask in the future projects myself. It is RxJava and it can solve your problem gracefully: "The fromFragment call transforms the given source observable in such a way that events will only be emitted to the fragment if it’s still alive and attached to its host activity."
One more citation form the article: "What if the user decides to back out of the Activity that triggered the task, and we are holding on to a stale reference. This not only creates a substantial memory leak, but is also worthless because meanwhile it has been detached from the application window. A problem that everyone is well aware of."
This question already has an answer here:
how to fix getDataTask method error?
(1 answer)
Closed 9 years ago.
this is my code below which work perfectly only problem is not show toast mesage code is blast i want to display toast mesage if Status is 0 in this line if (status.equals("1"))
show toast message but code is blast if i comment Toast then code run perfectly help me what do i do??
public class thirdstep extends Activity {
ListView listCategory;
String status;
String message;
String MenuSelect;
ProgressBar prgLoading;
long Cat_ID;
String Cat_name;
String CategoryAPI;
int IOConnect = 0;
TextView txtAlert;
thirdstepAdapter cla;
static ArrayList<String> Category_ID = new ArrayList<String>();
static ArrayList<String> Category_name = new ArrayList<String>();
static ArrayList<String> Category_image = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category_list2);
ImageButton btnback = (ImageButton) findViewById(R.id.btnback);
listCategory = (ListView) findViewById(R.id.listCategory2);
prgLoading = (ProgressBar) findViewById(R.id.prgLoading);
txtAlert = (TextView) findViewById(R.id.txtAlert);
cla = new thirdstepAdapter(thirdstep.this);
new getDataTask().execute();
listCategory.setAdapter(cla);
btnback.setOnClickListener(new OnClickListener()
{
public void onClick(View arg0) {
// TODO Auto-generated method stub
finish();
}
});
Intent iGet = getIntent();
Cat_ID = iGet.getLongExtra("category_id", 0);
Cat_name = iGet.getStringExtra("category_name");
Toast.makeText(this, Cat_ID + Cat_name, Toast.LENGTH_SHORT).show();
MenuSelect = Utils.MenuSelect;
listCategory.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
// TODO Auto-generated method stub
Intent iMenuList = new Intent(thirdstep.this,
fourthscreen.class);
iMenuList.putExtra("Cat_ID",Cat_ID);
iMenuList.putExtra("Menuitem", Category_ID.get(position));
startActivity(iMenuList);
}
});
}
void clearData() {
Category_ID.clear();
Category_name.clear();
Category_image.clear();
}
public class getDataTask extends AsyncTask<Void, Void, Void>{
getDataTask(){
if(!prgLoading.isShown()){
prgLoading.setVisibility(0);
txtAlert.setVisibility(8);
}
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
parseJSONData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
prgLoading.setVisibility(8);
if((Category_ID.size() > 0) || IOConnect == 0){
listCategory.setVisibility(0);
listCategory.setAdapter(cla);
}else{
txtAlert.setVisibility(0);
}
}
}
public void parseJSONData() {
CategoryAPI = Utils.MenuList + Cat_ID;
clearData();
try {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams
.setConnectionTimeout(client.getParams(), 15000);
HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
HttpUriRequest request = new HttpGet(CategoryAPI);
HttpResponse response = client.execute(request);
InputStream atomInputStream = response.getEntity().getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(
atomInputStream));
String line;
String str = "";
while ((line = in.readLine()) != null) {
str += line;
}
JSONObject json = new JSONObject(str);
JSONObject json2 = new JSONObject(str);
status = json2.getString("status");
message = json2.getString("message");
if (status.equals("1")) {
JSONObject data = json.getJSONObject("data");
JSONArray school = data.getJSONArray("menu_groups");
for (int i = 0; i < school.length(); i++) {
JSONObject object = school.getJSONObject(i);
Category_ID.add(object.getString("id"));
Category_name.add(object.getString("title"));
Category_image.add(object.getString("image"));
}
}
else
{
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
IOConnect = 1;
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Your toast message is within the parseJsonData method which is called from the doInBackground method of your asynctask.
You can not update the user interface thread from a background thread.
You have two options here
1) You can publish the progress publishProgress(1) of the thread passing in an integer value to be used as a flag which you can pick up on in the onPublishProgress listener and show your toast there
or
2) As your method has finished by this point then make the parseJsonData set an integer variable global to the asynctask and in the onPostExecute method pass something back to the listener to indicate that a toast needs to be shown
Update based on comments
Replace
{
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
with
{
publishProgress(1);
}
Add the missing onProgressUpdate() method to your asynctask
#Override
protected void onProgressUpdate(Integer... percent) {
//Call your listeners.onProgressUpdate(percent) here and show the
//Or
super.onProgressUpdate(percent);
if (percent[0] == 1){
Toast.makeText(thirdstep.this, message, Toast.LENGTH_SHORT).show();
}
}
I'm not here to write your code for you. Do some research on how to properly write an async task and publish progress
Here is a good starting point
http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/
You should be aware of orientation changes and how that will effect your asynctask (I avoid the pitfals of this by using a fragment
This is the design pattern I use for async tasks
http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html
But for handling web services, be nice to your users and let the android system work out when to download data etc and don't drain their battery and use a sync adapter with an intentservice instead of an asynctask. There are already too many crappy apps out there that take the asynctask approach for consuming web services. Please don't add yours to the list
Do it this way
http://developer.android.com/training/sync-adapters/creating-sync-adapter.html
It's a lot of extra learning curve but your a programmer right? You should be giving your users the best possible experience.
BTW You are getting down votes because you are demanding code to be written for you. I'm hoping this is just a language barrier and not an attitude problem.
Surround your Toast with this
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getBaseContext(), message, Toast.LENGTH_SHORT).show();
}
});
I tried the code below and also tried the AsyncTaskLoader approach. The app crashes when I instantiate the AsyncTask. Pleas advise me on the best approach to load JSON in a list fragment inside tab host.
The code below is the tab fragment (I use action bar tabs in main activity):
public class TabTop extends ListFragment {
Context context = getActivity().getBaseContext();
String API_URL = "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json?apikey=crhhxb4accwwa6cy6fxrm8vj&limit=1";
ArrayList<Deal> deals;
DealsListAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
#SuppressWarnings("unused")
int a = 0;
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
GetTopDeals getTopDeals = new GetTopDeals(context);
getTopDeals.execute(API_URL);
super.onActivityCreated(savedInstanceState);
}
class GetTopDeals extends AsyncTask<String, Void, ArrayList<Deal>>{
ProgressDialog progressDialog;
public GetTopDeals(Context activity) {
this.progressDialog = new ProgressDialog(activity);
}
#Override
protected void onPostExecute(ArrayList<Deal> result) {
adapter = new DealsListAdapter(context, result);
setListAdapter(adapter);
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
progressDialog.setCancelable(true);
progressDialog.setProgress(0);
progressDialog.setMessage("loading Top deals...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
super.onPreExecute();
}
#Override
protected ArrayList<Deal> doInBackground(String... urls) {
String response = sendRequest(urls[0]); // make request for json
return processResponse(response); // parse the Json and return ArrayList to postExecute
}
private String sendRequest(String apiUrl) {
BufferedReader input = null; // get the json
HttpURLConnection httpCon = null; // the http connection object
StringBuilder response = new StringBuilder(); // hold all the data from the jason in string separated with "\n"
try {
URL url = new URL(apiUrl);
httpCon = (HttpURLConnection) url.openConnection();
if (httpCon.getResponseCode() != HttpURLConnection.HTTP_OK) { // check for connectivity with server
return null;
}
input = new BufferedReader(new InputStreamReader(httpCon.getInputStream())); // pull all the json from the site
String line;
while ((line = input.readLine()) != null) {
response.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpCon != null) {
httpCon.disconnect();
}
}
return response.toString();
}
}
public ArrayList<Deal> processResponse(String response) {
try {
JSONObject responseObject = new JSONObject(response); // Creates a new JSONObject with name/value mappings from the JSON string.
JSONArray results = responseObject.getJSONArray("movies"); // Returns the value mapped by name if it exists and is a JSONArray.
deals = new ArrayList<Deal>();
for (int i = 0; i < results.length(); i++) { // in this loop i copy the json array to movies arraylist in order to display listView
JSONObject jMovie = results.getJSONObject(i);
int api_id = jMovie.getInt("id");
String name = jMovie.getString("title");
String content = jMovie.getString("synopsis");
JSONObject posters = jMovie.getJSONObject("posters");
String image_url = posters.getString("profile");
}
}catch (JSONException e) {
e.printStackTrace();
}
return deals;
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(getActivity().getBaseContext(), DealInformation.class);
startActivity(intent);
super.onListItemClick(l, v, position, id);
}
}
Make your asynctask in his own file.
And when your asynctask is finish, implement OnPostExecute which is automatically call. Notify your adapter by a notifyDataSetChanged like that :
#Override
protected void onPostExecute(List<NewItem> list) {
Adapter.getListe().clear();
Adapter.getListe().addAll(list);
Adapter.notifyDataSetChanged();
}
thank you guys,
i want to post my answer. after some research i decided to go with AsyncTaskLoader.
this is my code
public class TabOurPicks extends ListFragment implements LoaderCallbacks<String[]> {
// when activity loads- onActivityCreated() calls the initLoader() who activate onCreateLoader()
#Override
public void onActivityCreated(Bundle savedInstance) {
super.onActivityCreated(savedInstance);
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, new String[]{}));
getLoaderManager().initLoader(0, null,this).forceLoad();
}
// onCreateLoader instantiate the asynctaskloaser who work in bg
#Override
public RSSLoader onCreateLoader(int arg0, Bundle arg1) {
return new RSSLoader(getActivity()); //
}
// after bg process invoke onLoadFinished() who work in ui thread
#Override
public void onLoadFinished(Loader<String[]> loader, String[] data) {
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, data
) );
}
#Override
public void onLoaderReset(Loader<String[]> arg0) {
// TODO Auto-generated method stub
}
and this is the inner class for the loader:
static public class RSSLoader extends AsyncTaskLoader<String[]>
{
public RSSLoader(Context context) {
super(context);
}
#Override
public String[] loadInBackground() {
String url = "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json?apikey=crhhxb4accwwa6cy6fxrm8vj&limit=1";
String response = sendRequest(url);
return processResponse(response);
}
private String sendRequest(String url) {
BufferedReader input = null; // get the json
HttpURLConnection httpCon = null; // the http connection object
StringBuilder response = new StringBuilder(); // hold all the data from the jason in string separated with "\n"
try {
URL apiUrl = new URL(url);
httpCon = (HttpURLConnection) apiUrl.openConnection();
if (httpCon.getResponseCode() != HttpURLConnection.HTTP_OK) { // check for connectivity with server
return null;
}
input = new BufferedReader(new InputStreamReader(httpCon.getInputStream())); // pull all the json from the site
String line;
while ((line = input.readLine()) != null) {
response.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpCon != null) {
httpCon.disconnect();
}
}
return response.toString();
}
private String[] processResponse(String response) {
String[] deals = null;
try {
JSONObject responseObject = new JSONObject(response); // Creates a new JSONObject with name/value mappings from the JSON string.
JSONArray results = responseObject.getJSONArray("movies"); // Returns the value mapped by name if it exists and is a JSONArray.
deals = new String[10];
for (int i = 0; i < 9; i++) { // in this loop i copy the json array to movies arraylist in order to display listView
JSONObject jMovie = results.getJSONObject(i);
String name = jMovie.getString("title");
deals[i] = name;
}
}catch (JSONException e) {
e.printStackTrace();
}
return deals;
}
}
}
It doesn't matter if your asynctask has its own file. You just don't want your activity to extends asynctask as this would make your activity asynchronous - but this is impossible to do anyways due to java's double inheritance rule.
Based on the architecture of your app and your programming style the asyntask can be an inner class in the activity. on the PostExecute method make sure you have given data to your adapter and that the adapter is set to the list, then just run notifyDataSetChanged().
Assuming your asynctask is loading data from cache or the network you are on the right track with your approach to this.
I use this code to load the nearby places of any particular location by setting the** data using an Array Adapter. There are two issues that I face:
1. The spinner doesn't stop even after the data is loaded. (There should be no spinner. But I am not sure how does Fragment when it comes to this.)
I'm going to implement AsyncTask to get the places so that it doesn't slow down the Activity. The mini problem I face is this: How do I notify the user (update the view) with new date when he/she has changed his location. Let's assume that that the user is walking. Thus the lat/lon will change. So, how can I use onChangeNotify() and change the value of the List.
public class FragmentMap extends ListFragment {
ArrayList<Place> places = new ArrayList<Place>();
//List<String> val = new List<String>()
//#InjectView(R.id.explorePlacesListView) ListView placesListView;
ListView listView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ListView listView = (ListView) getActivity().findViewById(R.id.explorePlacesListView);
getPlaces();
PlacesAdapter placesAdapter = new PlacesAdapter(getActivity(),R.layout.user_list_item, places);
listView.setAdapter(placesAdapter);
}
public void getPlaces(){
URL yahoo;
String key,latitude,longitude;
key = "AIzaSyAZgD01sj3jssaYCmkLL8c7Z4qPTEdt6xU";
latitude = "37.77264";
longitude ="-122.409915";
try {
yahoo = new URL("https://maps.googleapis.com/maps/api/place/search/json?location=-33.8670522,151.1957362&radius=500&sensor=false&key=AIzaSyB2SGEmOLDGB_f0bp1PGTjQqTw2VuDcaM8");
URLConnection yc = yahoo.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
yc.getInputStream()));
String inputLine;
String jsonLine = new String();
while ((inputLine = in.readLine()) != null) {
Log.d("inputLine",inputLine);
jsonLine = jsonLine + inputLine;
}
in.close();
Object jsonResponse = parseResponse(jsonLine);
parseJSONPlaces((JSONObject)jsonResponse);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected Object parseResponse(String responseBody) throws JSONException {
return new JSONTokener(responseBody).nextValue();
}
private void parseJSONPlaces(JSONObject json){
try {
JSONArray jsonArray = json.getJSONArray("results");
for (int j = 0; j < json.length(); j++) {
Place place = new Place();
place.name = jsonArray.getJSONObject(j).getString("name");
place.icon = jsonArray.getJSONObject(j).getString("icon");
// JSONObject locationObject = jsonArray.getJSONObject(j).getJSONObject("location");
// place.latitude = locationObject.getString("latitude");
// place.longitude = locationObject.getString("longitude");
Log.d("name",place.name);
places.add(place);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(json.optJSONObject("results") != null){
}
}
There are a few things in your code that looks a bit strange to me.
You never call setListAdapter() which binds an adapter to the internal ListView of the ListFragment. Instead, you are fetching another ListView and set an adapter to that one. That is probably why no data gets displayed in the list, and you will instead se a progress indicator.
I'm not sure I understand your second question, but you should put your UI updates in the onPostExecute method of AsychTask.