0

Me and my budy are trying to create a refresh that could refresh our ListView data from MySQL, is there any way to refresh my ListView? I know there is the mothods Handler and things like that but can't seem to putting that to work.

This is my code :

package com.example.temperatura;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MainActivity extends AppCompatActivity {
    ListView listView;
    String[] sensor;
    ArrayAdapter arrayAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main );

        listView = (ListView) findViewById( R.id.listView );

        downloadJSON( "http://pillsmanager.com/temperatura/conn_app.php" );
    }

    private void downloadJSON(final String urlWebService) {
        class DownloadJSON extends AsyncTask<Void, Void, String> {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
                try {
                    loadIntoListView(s);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            protected String doInBackground(Void... voids) {
                try {
                    URL url = new URL(urlWebService);
                    HttpURLConnection con = (HttpURLConnection) url.openConnection();
                    StringBuilder sb = new StringBuilder();
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
                    String json;
                    while ((json = bufferedReader.readLine()) != null) {
                        sb.append(json + "\n");
                    }
                    return sb.toString().trim();
                } catch (Exception e) {
                    return null;
                }
            }
        }
        DownloadJSON getJSON = new DownloadJSON();
        getJSON.execute();
    }

    private void loadIntoListView( String json) throws JSONException {
        JSONArray jsonArray = new JSONArray(json);
        sensor = new String[jsonArray.length()];
        for (int i = 0; i < jsonArray.length(); i++) {
            final JSONObject obj = jsonArray.getJSONObject(i);

            sensor[i] = obj.getString("temperature") + " " + obj.getString("humidity");
        }

        arrayAdapter = new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, sensor );
        listView.setAdapter(arrayAdapter);
    }
}

I tried everything but nothing worked, much apreciated all the help :)

hata
  • 11,633
  • 6
  • 46
  • 69
filipe
  • 139
  • 2
  • 17
  • What do you mean by refresh not working? Do you have button for refreshing? You only call `downloadJSON` in onCreate ...? – morpheus05 Feb 05 '20 at 10:48
  • First of all, dont use ListView, use Recyclerview. Second, try to implement PullDownRefresh to trigger the action of REFRESH and then clear your fetched data and populate again. – kevoroid Feb 05 '20 at 10:48
  • @kevoroid i already tried the stipe to refresh but it appears the animation but doesnt refresh – filipe Feb 05 '20 at 10:51
  • Also, dont use AsyncTask! There are much better updated APIs available. Make sure when you fetched the new data, for instance, set your old dataset to null, add the new one to it and then call to refresh your adapter by `notifyDataSetChanged()` – kevoroid Feb 05 '20 at 10:53

1 Answers1

0

You need to call notifyDataSetChanged() on ur loadIntoListView method after updating data. Don't forget to call it in UIThread to avoid exeception :

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // INSERT YOUR UPDATE MECHANISM HERE
        // THEN CALL :
        listView.notifyDataSetChanged();
    }
});

EDIT :

ListView listView;
List<String> sensor= new ArrayList<>();
ArrayAdapter arrayAdapter;
boolean needRefresh;        // whether refresh is needed


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.activity_main );

    final SwipeRefreshLayout pullToRefresh = findViewById( R.id.pullToRefresh );

    listView = (ListView) findViewById( R.id.listView );
    downloadJSON( "http://pillsmanager.com/temperatura/conn_app.php" );

    pullToRefresh.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            downloadJSON( "http://pillsmanager.com/temperatura/conn_app.php" );
            pullToRefresh.setRefreshing( false );
            needRefresh = true;
        }
    } );
}


private void downloadJSON(final String urlWebService) {

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

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


        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute( s );
            Toast.makeText( getApplicationContext(), s, Toast.LENGTH_SHORT ).show();
            try {
                if( needRefresh )
                    {
                    updateAndLoadIntoListView( s );
                    }
                else
                    {
                    loadIntoListView( s );
                    }
            } catch ( JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected String doInBackground(Void... voids) {
            try {
                URL url = new URL( urlWebService );
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                StringBuilder sb = new StringBuilder();
                BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( con.getInputStream() ) );
                String json;
                while ((json = bufferedReader.readLine()) != null) {
                    sb.append( json + "\n" );
                }
                return sb.toString().trim();
            } catch (Exception e) {
                return null;
            }
        }
    }
    DownloadJSON getJSON = new DownloadJSON();
    getJSON.execute();

}

private void updateAndLoadIntoListView(String json) throws JSONException{
    JSONArray jsonArray = new JSONArray( json );
    sensor.clear();
    for (int i = 0; i < jsonArray.length(); i++) {
        final JSONObject obj = jsonArray.getJSONObject( i );
        sensor.add(obj.getString( "temperature" ) + " " + obj.getString( "humidity" ));

    }


    arrayAdapter.notifyDataSetChanged();
    needRefresh = false;
}





private void loadIntoListView(String json) throws JSONException {


        JSONArray jsonArray = new JSONArray( json );
        for (int i = 0; i < jsonArray.length(); i++) {
            final JSONObject obj = jsonArray.getJSONObject( i );
            sensor.add(obj.getString( "temperature" ) + " " + obj.getString( "humidity" ));



        }

        arrayAdapter = new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, sensor);
        listView.setAdapter( arrayAdapter );


    }
Kévin Giacomino
  • 487
  • 4
  • 11
  • what do you mean by calling it on the UIThread to avoid exception – filipe Feb 05 '20 at 10:52
  • Because u fetch your data in async task so you need to notifiy the main thread to make UI changes. As example simply call the notifyDataSetChanged() in "runOnUiThread" method – Kévin Giacomino Feb 05 '20 at 13:16
  • thanks for your help, so where should i put this code then – filipe Feb 06 '20 at 14:34
  • You should put it after updating your string array "sensor". – Kévin Giacomino Feb 06 '20 at 14:43
  • you are beeing really helpfull, im new to doing android apps, what is the update mecanism? – filipe Feb 06 '20 at 14:58
  • So when you need to update our data simply re-call your downloadJSON() method then u can create a new method for updating date for example updateAndLoadIntoListView() and call it if u need to update data. In this method u can apply same code as ur loadIntoListView() but u need to replace listView.setAdapte()... by the notifyDataSetChanged process – Kévin Giacomino Feb 06 '20 at 15:04
  • this is really helping me having an idea of what to do, how can i call my download json 1st of all. because i created on method oncreate where should i call it now? – filipe Feb 06 '20 at 15:37
  • Depends on what you desired. You can make a service who call the method each 24h or simply re-call it when user action is done like button click, pull refresh.. – Kévin Giacomino Feb 06 '20 at 15:56
  • i would like to have a pull refresh but i dont know how to make the refresh mechanism right – filipe Feb 06 '20 at 15:58
  • look at this post : https://stackoverflow.com/questions/4583484/how-to-implement-android-pull-to-refresh – Kévin Giacomino Feb 06 '20 at 16:39
  • i´ve created the swipe refresh, by logic i should put the method downloadJSON inside this isn´t it? `pullToRefresh.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { } } );` – filipe Feb 06 '20 at 16:50
  • Yes you can but dont forget to update our "sensor" array and call listView.notifyDataSetChanged() ( that replace the setAdapter().. ). For more clarity do it inside a new method instead of "downloadJSON" – Kévin Giacomino Feb 06 '20 at 17:02
  • ok much apreciated i will try that and give you feedback on that – filipe Feb 06 '20 at 17:04
  • hello i tried that method but somehow when i call `updateAndLoadIntoListView();` it gives me an error like this, `error: method updateAndLoadIntoListView in class MainActivity cannot be applied to given types; required: String found: no arguments reason: actual and formal argument lists differ in length` – filipe Feb 10 '20 at 14:52
  • Could you please post your updateAndLoadIntoListView() code – Kévin Giacomino Feb 10 '20 at 15:15
  • `private void updateAndLoadIntoListView(String json) throws JSONException{ JSONArray jsonArray = new JSONArray( json ); sensor = new String[jsonArray.length()]; for (int i = 0; i < jsonArray.length(); i++) { final JSONObject obj = jsonArray.getJSONObject( i ); sensor[i] = obj.getString( "temperature" ) + " " + obj.getString( "humidity" ); } arrayAdapter = new ArrayAdapter( this, android.R.layout.simple_list_item_1, sensor); listView.setAdapter( arrayAdapter ); }` – filipe Feb 10 '20 at 15:29
  • Could you please post your all your class code ? I tried but i dont have this error – Kévin Giacomino Feb 10 '20 at 15:55
  • i posted now the class – filipe Feb 10 '20 at 15:58
  • i tried and it refreshed the toast appears always when i refresh but doesnt appear nothing in listview im trying but cant seem to see – filipe Feb 10 '20 at 16:28
  • Which toast are u asking ? Nothing happens when u pull to refresh your view ? – Kévin Giacomino Feb 10 '20 at 16:31
  • when i execute the app doesnt appear nothing not even when i refresh, but is refreshing because when i pull to refresh the toast appears with data but listview doesnt – filipe Feb 10 '20 at 16:34
  • Could you please post your xml activity code ? I will try in my side – Kévin Giacomino Feb 10 '20 at 16:39
  • See my edited code.I just add a call to downloadJSON() before the the pull to refresh listener. So we download json first time and display it into list view then when user refresh we call the refresh method. I received null as data from the WS, i can't test. Could u please test ? – Kévin Giacomino Feb 10 '20 at 16:51
  • Ok i add internet permission and now it's working in my side. I see the list and the toast – Kévin Giacomino Feb 10 '20 at 16:55
  • i tried and now appears the data but doesnt change in listview buttt the toast shows the data that is in database but listview doesnt change – filipe Feb 10 '20 at 16:57
  • Hello, i found a solution. Please check the EDIT. I replace your String[] by an ArrayList and it's work on my side. Could u please test ? – Kévin Giacomino Feb 11 '20 at 09:16
  • yea i will give it a try rn – filipe Feb 11 '20 at 09:27
  • its working everything just fine, thx for your help you really made me understand better this type of codding much aprecciated! one luv bru <3 – filipe Feb 11 '20 at 09:33
  • No problem bro, enjoy ! Could u please accept my answer ? – Kévin Giacomino Feb 11 '20 at 09:36
  • yeaa i was just about to do that heheheh – filipe Feb 11 '20 at 09:47