0

I am trying to get a JSON string from a url and save it into SQLite in my android app.

I was trying some tutorials then realize the suggested methods has a void return type. Are there a more simple straight forward way of getting a JSON String and putting it into an arraylist ready to be saved into SQLite?

Below is what I was stuck at a helper class that gets the data from the url as they said that the main thread OnCreate does not allow a background process like this. Is there a way to change the return type of AsyncTask or is there a more simple way to fetch JSON String with android?

public class FetchData extends AsyncTask<Void, Void, Void> {
    @Override
    protected void doInBackground(ArrayList<String>... voids) {
        try {
            URL url = new URL("http://192.168.403.211/api/wordsupdate.php");


            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            InputStream inputStream = httpURLConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader (new InputStreamReader(inputStream));
            String line ="";
            while (line != null) {
                line = bufferedReader.readLine();
            }       

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
TwoThumbSticks
  • 1,086
  • 3
  • 23
  • 38
  • Have a look at this: http://square.github.io/okhttp/ – 3iL Jan 30 '18 at 07:43
  • so you want to do it without any 3rd party library? if so, your code is ok, if not, use [retrofit](http://square.github.io/retrofit/) – pskink Jan 30 '18 at 07:45
  • No, the code is **not** ok, see my answer below – Twometer Jan 30 '18 at 07:48
  • 1
    You can use Retrofit or Volley to download the JSON file, then in can be easily parsed with Gson. I would go with Retrofit and Gson, but this is just my preference – Iulian Popescu Jan 30 '18 at 07:54
  • `most simple straight forward` is completely opinion-based. Nobody knows which way is `most simple straight forward` for **you**. – Vladyslav Matviienko Jan 30 '18 at 08:41
  • @lulian Popescu I ended up using Volley. Thanks for the suggestion. Retrofit is too complicated for me at the moment I want a simpler way just to grasp the concept in practice. – TwoThumbSticks Feb 01 '18 at 05:49

6 Answers6

2

Go with Volley API. Check the code below which demonstrate POST request. Hope you'll get useful information.

public void getAddress(final String uid) {

    String url = "Add Url Here"; // Request a string response from the provided URL.
    StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {

                    JSONArray dataArray;
                    JSONObject jsonObject;

                    address_ids = new ArrayList<>();
                    address_names = new ArrayList<>();
                    address_line1 = new ArrayList<>();
                    address_line2 = new ArrayList<>();
                    address_state = new ArrayList<>();
                    address_district = new ArrayList<>();
                    address_taluka = new ArrayList<>();
                    address_pincode = new ArrayList<>();
                    address_status = new ArrayList<>();
                    address_default = new ArrayList<>();


                    try {
                        jsonObject = new JSONObject(response);
                        dataArray = jsonObject.getJSONArray(JSON_ARRAY);

                        //adding response values to respective array
                        for (int i = 0; i < dataArray.length(); i++) {
                            //Creating a json object of the current index
                            JSONObject obj;
                            try {
                                //getting json object from current index
                                obj = dataArray.getJSONObject(i);
                                address_ids.add(obj.getString(TAG_ADDRESS_ID));
                                address_names.add(obj.getString(TAG_ADDRESS_NAME));
                                address_line1.add(obj.getString(TAG_ADDRESSLINE_FIRST));
                                address_line2.add(obj.getString(TAG_ADDRESSLINE_SECOND));
                                address_state.add(obj.getString(TAG_STATE));
                                address_district.add(obj.getString(TAG_DISTRICT));
                                address_taluka.add(obj.getString(TAG_TALUKA));
                                address_pincode.add(obj.getString(TAG_PINCODE));
                                address_status.add(obj.getString(TAG_ADDRESS_STATUS));

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }


                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    //setting up response values to the fragment
                    //Toast.makeText(getActivity(), "Error:"+response, Toast.LENGTH_LONG).show();
                    Log.e(TAG, "onResponse: " + response);
                    address_name.setText("Name : " + address_names.get(0));
                    address.setText("Address : " + address_line1.get(0) + "," + address_line2.get(0) + "-" + address_pincode.get(0));
                    taluka.setText("Taluka : " + address_taluka.get(0));
                    district.setText("District : " + address_district.get(0));
                    state.setText("State : " + address_state.get(0));
                    mCircularProgressBar.setIndeterminate(false);
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(getApplication(), "Taking bit longer", Toast.LENGTH_LONG).show();
        }

    }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("mk_address_id", address_id);
            return params;
        }
    };
    queue.add(stringRequest);
}
Mayur Dusane
  • 367
  • 1
  • 8
  • 17
  • I ended up using Volley but starting with a more simple code. I will try you code and come back here after I get familiar with Volley. – TwoThumbSticks Feb 01 '18 at 05:51
2

Check this link from Android developer, you can find more info their.

In your code change the "extends" from

AsyncTask<Void, Void, Void>

to

AsyncTask<Void, Void, String>

and the doInBackground method to

protected String doInBackground(ArrayList<String>... voids) 

and you will get the string back in the onPostExecute method

Sergey
  • 394
  • 1
  • 12
1

Yes there is a way to change the return types: Have a look at your extends AsyncTask: It says AsyncTask<Void, Void, Void>.

According to Android Developers, this means <Params, Progress, Result>.

This means that your ArrayList<String>... voids won't work too, because you have the Params part set to Void but try to get an ArrayList<String>.

So, to solve your problem, change the three Voids to whatever you need it to input and output.

However, to deserialize JSON you should use an external library (or use a 3rd party library for REST calls altogether).

Twometer
  • 1,561
  • 2
  • 16
  • 24
1

//AsyncTask has onPostExecute which will be called after background execution, where you will get the result in mainthread

class FetchData extends AsyncTask<Void, Void, String> {
    @Override
    protected String doInBackground(Void... voids) {
        try {
            URL url = new URL("http://192.168.403.211/api/wordsupdate.php");

            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            InputStream inputStream = httpURLConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                builder.append(line);
            }
            return builder.toString();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        //Your result String is here which runs on MAIN THREAD
        super.onPostExecute(result);
    }
}
Balu Sangem
  • 712
  • 4
  • 16
0

Retrofit 2 will help you - easy and simple

Edit : For Async task see the top answer here

What arguments are passed into AsyncTask<arg1, arg2, arg3>?

Sandeep PC
  • 797
  • 8
  • 12
0

In your code snippet , you specified AsyncTask params types are Void. Void means , it does't have any return value. As per AsyncTask Syntax,
You have to specify three arguments. 1- InputType- DoInBanckground 2- ProgressType - Publish Progress. 3- OutputType - OnPostExecute.

The three types used by an asynchronous task are the following:

Params, the type of the parameters sent to the task upon execution. Progress, the type of the progress units published during the background computation. Result, the type of the result of the background computation.

In your snippet doInBackground method and AsycTask types are mismatching .

For more information : https://developer.android.com/reference/android/os/AsyncTask.html

user2851150
  • 397
  • 5
  • 12