0

I'm working on an app in which I need to retrieve data from two different json and I have to populate a listview in android. In the first Json I have an array of object and I have the id object and an url that need to retrieve data for that object.

How can I do that? I can retrieve the object and populate listview with this object but I don't know how to take the data for the single object and show it in the same row.

The list view should be like this:

enter image description here

This is Json1:

[
    {
        "id": "S1",
        "url": "MyUrl1"
    },
    {
        "id": "S2",
        "url": "MyUrl2"
    },
    {
        "id": "S3",
        "url": "MyUrl3"
    }
]

It's different for every object. This is Json2:

{
    "id": "S1",
    "temp": "20.03",
    "time": "28 June 2018, 9:12:13"
}

So, I can retrieve id and show all id object in listView, but I cannot retrieve for every object the "temp" and "time" values.

This is my code:

Adapter

public class SensorAdapter extends BaseAdapter{
ArrayList<String> id= new ArrayList<String>();
ArrayList<String> labelno_array = new ArrayList<String>();
Context context;
LayoutInflater inflater;


public SensorAdapter2(Context c, ArrayList<String> label_array)
{
    context = c;
    id= label_array;
   // temp=temp_array;
   // time=time_array;
    //labelno_array = no_array;
    inflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return id.size();
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public long getItemId(int position)
{
    // TODO Auto-generated method stub
    return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    View v = convertView;
    Holder holder;
    // TODO Auto-generated method stub
    if (v == null) {
        v = inflater.inflate(R.layout.columns_sensor, null);
        holder = new Holder();
        holder.tv_labelname = (TextView)v.findViewById(R.id.idsensor);

        v.setTag(holder);
    } else {
        holder = (Holder) v.getTag();
    }


    holder.tv_labelname.setText(id.get(position));

    return v;
}
public class Holder
{
    TextView tv_labelname,tv_labelno, tv_temp, tv_time;
}

And this is my code to retrieve the number of sensor:

Code

 class RetrieveFeedTask2 extends AsyncTask<Void, Void, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }



    protected String doInBackground(Void... urls) {
        String API_URL = "MyUrl";

        try {
            URL url = new URL(API_URL);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                StringBuilder stringBuilder = new StringBuilder();
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    stringBuilder.append(line).append("\n");
                }
                bufferedReader.close();
                return stringBuilder.toString();
            }
            finally{
                urlConnection.disconnect();
            }
        }
        catch(Exception e) {
            Log.e("ERROR", e.getMessage(), e);
            return null;
        }
    }

    protected void onPostExecute(String response) {
        if(response == null) {
            response = "THERE WAS AN ERROR";
        }
        //            progressBar.setVisibility(View.GONE);
        Log.i("INFO", response);

        try
        {

            JSONArray array=new JSONArray(response);

            for(int i = 0; i < array.length(); i++)
            {
                JSONObject obj = array.getJSONObject(i);

                String mysenso=obj.getString("id");
                String myurl=obj.getString("url");
                //partire nuova chiamata con l'url.
                label_no.add(myurl);
                label_name.add(mysenso);


            }


        }
        catch (JSONException e)
        {
            e.printStackTrace();
        }
        SensorAdapter2 adapter = new SensorAdapter2(Principale.this, label_name);
        listView.setAdapter(adapter);


    }

}

So, how can I connect at the object url and update data for that object in the same row?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
PaoloPaul
  • 11
  • 4

2 Answers2

0

First of all, create two POJOs like this

First.java

public class First {
    String id,url;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

Second.java

public class Second{
    String id,temp,time;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTemp() {
        return temp;
    }

    public void setTemp(String temp) {
        this.temp = temp;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }
}

Then in your asynctask class RetrieveFeedTask2 extends AsyncTask {

@Override
protected void onPreExecute() {
    super.onPreExecute();
}



protected String doInBackground(Void... urls) {
    String API_URL = "MyUrl";

    try {
        URL url = new URL(API_URL);
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line).append("\n");
            }
            bufferedReader.close();
            return stringBuilder.toString();
        }
        finally{
            urlConnection.disconnect();
        }
    }
    catch(Exception e) {
        Log.e("ERROR", e.getMessage(), e);
        return null;
    }
}

protected void onPostExecute(String response) {
    if(response == null) {
        response = "THERE WAS AN ERROR";
    }
    //            progressBar.setVisibility(View.GONE);
    Log.i("INFO", response);
     ArrayList<First> firstList = new ArrayList<>();
    try
    {

        JSONArray array=new JSONArray(response);

        for(int i = 0; i < array.length(); i++)
        {
            JSONObject obj = array.getJSONObject(i);

            String mysenso=obj.getString("id");
            String myurl=obj.getString("url");
            First first = new First();
            first.setId(mysenso);
            first.setUrl(myurl);
            firstList.add(first);

        }


    }
    catch (JSONException e)
    {
        e.printStackTrace();
    }
    SensorAdapter2 adapter = new SensorAdapter2(Principale.this, firstList);
    listView.setAdapter(adapter);


}

}

Then in your adapter

public class SensorAdapter extends BaseAdapter{
ArrayList<FirstList> firstList;

Context context;
LayoutInflater inflater;


public SensorAdapter2(Context c, ArrayList<FirstList> firstList)
{
    context = c;
    this.firstList=firstList;
   // temp=temp_array;
   // time=time_array;
    //labelno_array = no_array;
    inflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return firstList.size();
}

@Override
public Object getItem(int position) {
    // TODO Auto-generated method stub
    return position;
}

@Override
public long getItemId(int position)
{
    // TODO Auto-generated method stub
    return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    View v = convertView;
    Holder holder;
    // TODO Auto-generated method stub
    if (v == null) {
        v = inflater.inflate(R.layout.columns_sensor, null);
        holder = new Holder();
        holder.tv_labelname = (TextView)v.findViewById(R.id.idsensor);

        v.setTag(holder);
    } else {
        holder = (Holder) v.getTag();
    }


    holder.tv_labelname.setText(firstList.get(position).getId());

    return v;
}
public class Holder
{
    TextView tv_labelname,tv_labelno, tv_temp, tv_time;
}

This way your first part is setup. Now you need to get the value of clicked item and from there you need to get the url and then pass that url to another asyntask and set its value in Second.java class and show it from there. To get the clicked item you need to use the following code in the class where you are findViewById-ing the listview.

listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
        String url = (String) listView.getItemAtPosition(position);
        Toast.makeText(this,"You selected : " + url,Toast.LENGTH_SHORT).show();         
//here you will get the url and then now send it to another asynctask and parse it and set the value to Second.java and start another activity or fragment to display data from Second.java


    }
});
theanilpaudel
  • 3,348
  • 8
  • 39
  • 67
0

If I was in your scenario, I'd first retrieve the data (if the data is small in size), then worry about displaying them.

If the data is to be large, I'd attempt to retrieve the extra info, while trying to view it

So lets proceed.

Hint: I am going to assume you already know how to fetch your data (based on 'class RetrieveFeedTask2' - although you should probably disconnect your connection before returning)

GENERAL CASE:

In all cases you need
1. a class say

class MyObject {
   String id,time,temp,url;
}

2. A method to fetch your First JSON and store it in a list say

public List&#60;MyObject&#62; fetchThenParseIntoList() {
   . . .
}

and now you'll use it to fetch your first JSON and parse it into a list

List&#60;MyObject&#62; myObjects = fetchThenParseIntoList()

So, now you will have a list of "MyObject" objects with Ids and urls only

3. A thread that can be given an object to fetch extra info of the object. say

class ExtraInfoThread extends Thread {
    private MyObject myObject;
    public ExtraInfoThread(final MyObject myObject) {
        this.myObject = myObject
    }

    @Override
    public void run() {
        . . .
    }
}

CASE 1: Small data (Say less that 1000 objects)

Loop in every object and fetch the extra info

for(MyObject myObject: myObjects) {
    new ExtraInfoThread(myObject).start()
}

Now you have an object, with all the data, and you can display it as you want

Case 2: Large Data

Call the thread to fetch extra info only while you are trying to display it

public View getView() {
  new ExtraInfoThread(myObject).start()
  . . .
}

if you can implement the views and the fetching of the JSON, you defenetly will achieve what you are looking for

andylamax
  • 1,858
  • 1
  • 14
  • 31