-1

I found this code that I have modified to suit my needs. However I am facing a bit of an issue. It appears that the data is obtained from the remote host but cannot be parsed into adapter.

I have reviewed my entire code structure to ensure that everything is in place but I cant seem to find the problem. The ListView is inside of a Fragment that is part of a TabbedActivity.

This my code:

Fragment inside a Tabbed Activity

public class shops extends Fragment {
String url="http://link to remote webservice";

//FragmentManager fm;

//newInstance() method return reference to fragment
public static shops newInstance(){
    shops fragment = new shops();
    return fragment;
}


public shops() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    //fm = getFragmentManager();

    View view = inflater.inflate(R.layout.fragment_shops, container, false);


    final ListView listView = (ListView)view.findViewById(R.id.shops_info);
    final Downloader d =new Downloader(getActivity(),url,listView);
    d.execute();


//calls DialoFragment
    FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fab_edset);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            DialogFragment newEdQua = new createNewEdQua();
            newEdQua.show(getActivity().getFragmentManager(), "createNewEdQua");

        }
    });

    // Inflate the layout for this fragment
    return view;
}

}

Downloader(receives data and parses in the same class)

public class Downloader extends AsyncTask<Void,Integer,String> {
Context c;
String retredq_url;
ListView listView;

String data;
ArrayList<String> shopl=new ArrayList<String>();//its the ArrayList that we bind to ListView

ProgressDialog pd;

public Downloader(Context c, String retredq_url, ListView listView){
    this.c=c;
    this.retredq_url=retredq_url;
    this.listView=listView;
}

//Before job starts
@Override
protected void onPreExecute(){
    super.onPreExecute();
    pd=new ProgressDialog(c);
    pd.setTitle("Refreshing List");
    pd.setMessage("Please Wait...");
    pd.show();
}
@Override
protected String doInBackground(Void... params) {
    data=downloadData();
    return data;
}

@Override
protected void onPostExecute(String s){
    super.onPostExecute(s);

    pd.dismiss();

    if (s !=null){

        try{

            JSONArray ja=new JSONArray(data);
            //JSONObject jo=null;

            shopl.clear();//we need to add the data to ArrayList, so clear list first to avoid duplicates

            for (int i=0;i<ja.length();i++){

                String shops=ja.getJSONObject(i).getString("Qualification")+ ja.getJSONObject(i).get("eq_end_date")+
                        ja.getJSONObject(i).get("eq_loc_shops");//retrieve the column name into a string
                shopl.add(shops);

                ArrayAdapter<String> adapter=new ArrayAdapter<String>(c,R.layout.list_item_shopl,shopl);
                listView.setAdapter(adapter);

                listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                        Snackbar.make(view,shopl.get(i),Snackbar.LENGTH_LONG).show();
                    }
                });

            }

        } catch (JSONException e) {
            Log.e("Downloader", "Error", e);
        }


        /*
        //call the Parser here to parse the JSON after we confirm string writer is not null
        Parser p=new Parser(c,s,listView);
        p.execute();*/

    }else {
        Toast.makeText(c,"Unable to download data", Toast.LENGTH_SHORT).show();
    }

}

private  String downloadData(){
    //connect and get a stream
    InputStream inputStream=null;
    String line=null;

    try{
        URL url=new URL(retredq_url);
        HttpURLConnection con=(HttpURLConnection) url.openConnection();
        inputStream=new BufferedInputStream(con.getInputStream());
        BufferedReader br=new BufferedReader(new InputStreamReader(inputStream));

        StringBuffer sb=new StringBuffer();

        if (br !=null){

            while ((line=br.readLine()) !=null){
                sb.append(line+"\n");

            }

        }else{return null;}

        return sb.toString();

    } catch (MalformlocRLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if (inputStream !=null){
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
    return null;

}
}

JSON output (Checked with ARC plugin on Chrome)

{"qualifications":[{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"}],"success":1}

A slight difference from what ADM sees (The success message comes first here)

{"success":1,"qualifications":[{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"},{"eq_edu_Institution":"Oracle","eq_start_Date":"1998-06-14","eq_end_date":"2005-08-23","Qualification":"Software Engineer"}]}

I defined the success message while struturing the array in php webservice

I intend use the Downloader class in several tabs for the same purpose(retrieve data from url parse and display in ListView). The urls and data are independent ot each other so I guess it should work...

Shaishav Jogani
  • 2,111
  • 3
  • 23
  • 33
user3650467
  • 173
  • 1
  • 1
  • 9

3 Answers3

0

Going over LogCat and reviewing JSON data obtained from server I was able to figure the problem. My previous code would have worked without any issues if the data was an Array with Objects in it. But I checked and the structure of the JSON was an Object with the Array inside.

What I had to do was get the Object with JSONObject then that Object retrieve the Array with JSONArray.. Like this:

            JSONObject jsonObject=new JSONObject(data);
            JSONArray jsonArray= jsonObject.getJSONArray("qualifications");

//now this Array has Objects needed

            for (int i=0;i<jsonArray.length();i++){

                String institution=jsonArray.getJSONObject(i).getString("Qualification");
                edqua.add(institution);
            }

            //provide the ArrayAdapter<> needed
            ArrayAdapter<String> adapter=new ArrayAdapter<String>(c,R.layout.list_item_edqua,edqua);
            listView.setAdapter(adapter);

It should be in a try-catch block.. It is good to know the structure of the JSON that is expected. I was rather asking for an Array when Object was being offerd, hence the type mis-match error. I also realised that I will be unable to use the same class for different data sources, as the tables are completely. Any suggestions of how to use one class for different data urls will appreciated.

user3650467
  • 173
  • 1
  • 1
  • 9
  • Why are you setting the adapter again and again in the loop? – OneCricketeer Sep 03 '16 at 17:18
  • And you shouldn't ask for suggestions in your answers - you can either make a new post or edit the original question – OneCricketeer Sep 03 '16 at 17:20
  • point noted.. @cricket_007.. the first Object gets the data now inside it is an Array that has other Objects. So get the Object reach the Array, then loop through to retrieve the Objects inside it.. See the JSON structure – user3650467 Sep 03 '16 at 18:42
  • Right, but you only need one adapter. You can create and set that before or after the loop, just once. No need to continously set within the loop – OneCricketeer Sep 03 '16 at 19:02
  • Replace your old code that invoke `listView.setAdapater()` in loop with your new code or someone is confused. – Lym Zoy Sep 04 '16 at 08:33
0

As the ArrayList<String> shows, the list item will be like
Qualification eq_end_date eq_loc_shops as a single string, so initialize the adapter like
adapter = new ArrayAdapter<>(context,android.R.layout.simple_list_item_1,shopl);

isamirkhaan1
  • 749
  • 7
  • 19
0

Most of your code can be reused but the part which starts from data generated by downloadData() to the JSONArrayObject that your listview needs.

So you can extract these code to an Interface(here called IPreParser)'s method (called JSONArrayObject arrayFromData(String)), like this:

public interface IPreParser{
    JSONArrayObject arrayFromData(String data);
}

Your Downloader need hold a reference to IPreParser, and invoke its method in onPostExecute(). And you can initialize this reference by declaring doInBackground(IPreParser).

In anywhere you what download and parse your data, just implement IPreParser, and then execute your downloader with downloader.execute(yourImplementor);

Lym Zoy
  • 951
  • 10
  • 16