-1

I'm trying to run an application and it crashes because of this error:

FATAL EXCEPTION: main             
                 Process: com.panaceasoft.citiesdirectory, PID: 4201
                 com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: Invalid double: ""

It had some Gradle errors, but I had solved them, and now it still crashed when I tried to run the app. It looks like that problem is in the class below, at line 252. Tried everything possible to check data and to solve this error, but nothing so far. What should I do? Thanks!

CitiesListFragment:

public class CitiesListFragment extends Fragment {

    //-------------------------------------------------------------------------------------------------------------------------------------
    //region // Private Variables
    //-------------------------------------------------------------------------------------------------------------------------------------
    private RecyclerView mRecyclerView;
    private ProgressWheel progressWheel;
    private CityAdapter adapter;
    private SwipeRefreshLayout swipeRefreshLayout;
    private TextView display_message;
    private ArrayList<PCityData> pCityDataList;
    private ArrayList<PCityData> pCityDataSet;
    private NestedScrollView singleLayout;
    private TextView scCityName;
    private TextView scCityLocation;
    private TextView scCityAbout;
    private TextView scCityCatCount;
    private TextView scCitySubCatCount;
    private TextView scCityItemCount;
    private ImageView scCityPhoto;
    private Button scCityExplore;
    private String jsonStatusSuccessString;
    private String connectionError;

    //-------------------------------------------------------------------------------------------------------------------------------------
    //endregion Public Variables
    //-------------------------------------------------------------------------------------------------------------------------------------

    //-------------------------------------------------------------------------------------------------------------------------------------
    //region // Constructor
    //-------------------------------------------------------------------------------------------------------------------------------------
    public CitiesListFragment() {

    }
    //-------------------------------------------------------------------------------------------------------------------------------------
    //endregion Constructor
    //-------------------------------------------------------------------------------------------------------------------------------------

    //-------------------------------------------------------------------------------------------------------------------------------------
    //region // Override Functions
    //-------------------------------------------------------------------------------------------------------------------------------------
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_cities_list, container, false);

        initUI(view);

        initData();

        return view;
    }
    //-------------------------------------------------------------------------------------------------------------------------------------
    //endregion Override Functions
    //-------------------------------------------------------------------------------------------------------------------------------------

    //-------------------------------------------------------------------------------------------------------------------------------------
    //region // Init UI Function
    //-------------------------------------------------------------------------------------------------------------------------------------

    private void initUI(View view){
        initSingleUI(view);

        initSwipeRefreshLayout(view);

        initProgressWheel(view);

        initRecyclerView(view);

        startLoading();
    }

    private void initSingleUI(View view) {

        singleLayout =(NestedScrollView) view.findViewById(R.id.single_city_layout);
        scCityName = (TextView) view.findViewById(R.id.sc_city_name);
        scCityLocation = (TextView) view.findViewById(R.id.sc_city_loc);
        scCityAbout = (TextView) view.findViewById(R.id.sc_city_desc);
        scCityCatCount = (TextView) view.findViewById(R.id.txt_cat_count);
        scCitySubCatCount = (TextView) view.findViewById(R.id.txt_sub_cat_count);
        scCityItemCount = (TextView) view.findViewById(R.id.txt_item_count);
        scCityPhoto = (ImageView) view.findViewById(R.id.sc_city_photo);
        scCityExplore = (Button) view.findViewById(R.id.button_explore);

        int screenWidth = Utils.getScreenWidth();

        int rlWidth = (screenWidth/3) - 20;

        RelativeLayout r1 = (RelativeLayout) view.findViewById(R.id.rl_count1);
        RelativeLayout r2 = (RelativeLayout) view.findViewById(R.id.rl_count2);
        RelativeLayout r3 = (RelativeLayout) view.findViewById(R.id.rl_count3);

        r1.setMinimumWidth(rlWidth);
        r2.setMinimumWidth(rlWidth);
        r3.setMinimumWidth(rlWidth);

        scCityPhoto.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                if(pCityDataList !=null && pCityDataList.size() > 0) {
                    final Intent intent;
                    intent = new Intent(getActivity(), SelectedCityActivity.class);
                    GlobalData.citydata = pCityDataList.get(0);
                    intent.putExtra("selected_city_id", pCityDataList.get(0).id);
                    getActivity().startActivity(intent);
                    getActivity().overridePendingTransition(R.anim.right_to_left, R.anim.blank_anim);
                }

            }
        });

        scCityExplore.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                if(pCityDataList !=null && pCityDataList.size() > 0) {
                    final Intent intent;
                    intent = new Intent(getActivity(), SelectedCityActivity.class);
                    GlobalData.citydata = pCityDataList.get(0);
                    intent.putExtra("selected_city_id", pCityDataList.get(0).id);
                    getActivity().startActivity(intent);
                    getActivity().overridePendingTransition(R.anim.right_to_left, R.anim.blank_anim);
                }

            }
        });

    }

    private void initSwipeRefreshLayout(View view) {
        swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                requestData(Config.APP_API_URL + Config.GET_ALL);
            }
        });
    }

    private void initProgressWheel(View view) {
        progressWheel = (ProgressWheel) view.findViewById(R.id.progress_wheel);
    }

    private void initRecyclerView(View view) {

        mRecyclerView = (RecyclerView) view.findViewById(R.id.my_recycler_view);
        mRecyclerView.setHasFixedSize(true);

        LinearLayoutManager llm = new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(llm);
        display_message = (TextView) view.findViewById(R.id.display_message);
        display_message.setVisibility(view.GONE);

        pCityDataSet = new ArrayList<>();
        adapter = new CityAdapter(getActivity(), pCityDataSet);
        mRecyclerView.setAdapter(adapter);

        mRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), mRecyclerView, new ClickListener() {
            @Override
            public void onClick(View view, int position) {
                onItemClicked(position);
            }

            @Override
            public void onLongClick(View view, int position) {

            }
        }));
    }

    //-------------------------------------------------------------------------------------------------------------------------------------
    //endregion Init UI Function
    //-------------------------------------------------------------------------------------------------------------------------------------

    //-------------------------------------------------------------------------------------------------------------------------------------
    //region // Init Data Function
    //-------------------------------------------------------------------------------------------------------------------------------------

    private void initData(){
        requestData(Config.APP_API_URL + Config.GET_ALL);

        jsonStatusSuccessString = getResources().getString(R.string.json_status_success);
        connectionError = getResources().getString(R.string.connection_error);

    }

    private void requestData(String uri) {
        JsonObjectRequest request = new JsonObjectRequest(uri,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            String status = response.getString("status");
                            if (status.equals(jsonStatusSuccessString)) {
                                progressWheel.setVisibility(View.GONE);
                                Gson gson = new Gson();
                                Type listType = new TypeToken<List<PCityData>>() {
                                }.getType();

                                //String data="";
                                pCityDataList = gson.fromJson(response.getString("Data"), listType);

                                Utils.psLog("City Count : "  + pCityDataList.size());
                                if(pCityDataList.size() > 1) {
                                    singleLayout.setVisibility(View.GONE);
                                    mRecyclerView.setVisibility(View.VISIBLE);
                                    updateDisplay();
                                }else{
                                    mRecyclerView.setVisibility(View.GONE);
                                    singleLayout.setVisibility(View.VISIBLE);
                                    stopLoading();
                                    updateSingleDisplay();
                                }

                                updateGlobalCityList();

                            } else {
                                stopLoading();
                                Utils.psLog("Error in loading CityList.");
                            }
                        } catch (JSONException e) {
                            Utils.psErrorLogE("Error in loading CityList.", e);
                            stopLoading();
                            e.printStackTrace();
                        }
                    }
                },


                new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError ex) {
                        progressWheel.setVisibility(View.GONE);
                        stopLoading();
                       /* NetworkResponse response = ex.networkResponse;
                        if (response != null && response.data != null) {

                        } else {*/
                        try {
                            display_message.setVisibility(View.VISIBLE);
                            display_message.setText(connectionError);
                        }catch (Exception e){
                            Utils.psErrorLogE("Error in Connection Url.", e);
                        }
                        //}

                    }
                });

        request.setRetryPolicy(new DefaultRetryPolicy(
                5000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));


        RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
        queue.add(request);
    }

    //-------------------------------------------------------------------------------------------------------------------------------------
    //endregion Init Data Function
    //-------------------------------------------------------------------------------------------------------------------------------------

    //-------------------------------------------------------------------------------------------------------------------------------------
    //region // Bind Functions
    //-------------------------------------------------------------------------------------------------------------------------------------
    private void updateSingleDisplay() {
        try {
            if (pCityDataList.size() > 0) {

                display_message.setVisibility(View.GONE);
                singleLayout.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in));
                scCityName.setText(pCityDataList.get(0).name);
                scCityLocation.setText(pCityDataList.get(0).address);
                scCityAbout.setText(pCityDataList.get(0).description);
                scCityCatCount.setText(pCityDataList.get(0).category_count + " Categories");
                scCitySubCatCount.setText(pCityDataList.get(0).sub_category_count + " Sub Categories");
                scCityItemCount.setText(pCityDataList.get(0).item_count + " Items");
                Picasso.with(getActivity()).load(Config.APP_IMAGES_URL + pCityDataList.get(0).cover_image_file).into(scCityPhoto);

            }
        }catch(Exception e){
            Utils.psErrorLogE("Error in single display data binding.", e);
        }
    }

    private void updateGlobalCityList() {
        GlobalData.cityDatas.clear();
        for (PCityData cd : pCityDataList) {
            GlobalData.cityDatas.add(cd);
        }
    }

    private void updateDisplay() {

        if (swipeRefreshLayout.isRefreshing()) {
            pCityDataSet.clear();
            adapter.notifyDataSetChanged();

            for (PCityData cd : pCityDataList) {
                pCityDataSet.add(cd);
            }
        } else {
            for (PCityData cd : pCityDataList) {
                pCityDataSet.add(cd);
            }
        }
        stopLoading();
        adapter.notifyItemInserted(pCityDataSet.size());
    }

    //-------------------------------------------------------------------------------------------------------------------------------------
    //endregion Bind Functions
    //-------------------------------------------------------------------------------------------------------------------------------------

    //-------------------------------------------------------------------------------------------------------------------------------------
    //region // Private Functions
    //-------------------------------------------------------------------------------------------------------------------------------------

    private void onItemClicked(int position) {
        Utils.psLog("Position : " + position);
        Intent intent;
        intent = new Intent(getActivity(),SelectedCityActivity.class);
        GlobalData.citydata = pCityDataList.get(position);
        intent.putExtra("selected_city_id", pCityDataList.get(position).id);
        getActivity().startActivity(intent);
        getActivity().overridePendingTransition(R.anim.right_to_left, R.anim.blank_anim);
    }

    private void startLoading(){
        try{
            swipeRefreshLayout.post(new Runnable() {
                @Override
                public void run() {
                    swipeRefreshLayout.setRefreshing(true);
                }
            });
        }catch (Exception e){}
    }

    private void stopLoading(){
        try {
            if (swipeRefreshLayout.isRefreshing()) {
                swipeRefreshLayout.setRefreshing(false);
            }
        }catch (Exception e){}
    }

    //-------------------------------------------------------------------------------------------------------------------------------------
    //endregion Private Functions
    //-------------------------------------------------------------------------------------------------------------------------------------

Line 252:

pCityDataList = gson.fromJson(response.getString("data"), listType);

PCityData.class:

package com.panaceasoft.citiesdirectory.models;

import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;

/**
 * Created by Panacea-Soft on 6/8/15.
 * Contact Email : teamps.is.cool@gmail.com
 */
public class PCityData implements Parcelable {

    public int id;

    public String name;

    public String description;

    public String address;

    public String lat;

    public String lng;

    public String added;

    public int status;

    public int item_count;

    public int category_count;

    public int sub_category_count;

    public int follow_count;

    public String cover_image_file;

    public int cover_image_width;

    public int cover_image_height;

    public String cover_image_description;

    public ArrayList<PCategoryData> categories;

    protected PCityData(Parcel in) {
        id = in.readInt();
        name = in.readString();
        description = in.readString();
        address = in.readString();
        lat = in.readString();
        lng = in.readString();
        added = in.readString();
        status = in.readInt();
        item_count = in.readInt();
        category_count = in.readInt();
        sub_category_count = in.readInt();
        follow_count = in.readInt();
        cover_image_file = in.readString();
        cover_image_width = in.readInt();
        cover_image_height = in.readInt();
        cover_image_description = in.readString();
        if (in.readByte() == 0x01) {
            categories = new ArrayList<PCategoryData>();
            in.readList(categories, PCategoryData.class.getClassLoader());
        } else {
            categories = null;
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(name);
        dest.writeString(description);
        dest.writeString(address);
        dest.writeString(lat);
        dest.writeString(lng);
        dest.writeString(added);
        dest.writeInt(status);
        dest.writeInt(item_count);
        dest.writeInt(category_count);
        dest.writeInt(sub_category_count);
        dest.writeInt(follow_count);
        dest.writeString(cover_image_file);
        dest.writeInt(cover_image_width);
        dest.writeInt(cover_image_height);
        dest.writeString(cover_image_description);
        if (categories == null) {
            dest.writeByte((byte) (0x00));
        } else {
            dest.writeByte((byte) (0x01));
            dest.writeList(categories);
        }
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<PCityData> CREATOR = new Parcelable.Creator<PCityData>() {
        @Override
        public PCityData createFromParcel(Parcel in) {
            return new PCityData(in);
        }

        @Override
        public PCityData[] newArray(int size) {
            return new PCityData[size];
        }
    };
}

L.E:

data:

[{"id":"1","name":"Maramureș","description":"Maramureș is a mountainous .","address":"Maramureș, Romania","lat":"0","lng":"0","admin_id":"3","is_approved":"1","paypal_trans_id":"0","added":"2016-07-1420:45:50","status":"1","item_count":85,"category_count":49,"sub_category_count":0,"follow_count":0,"cover_image_file":"singapore.png","cover_image_width":"600","cover_image_height":"400","cover_image_description":"Singapore","categories":

L.E:

PCategoryData.java:

package com.panaceasoft.citiesdirectory.models;

import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;

/**
 * Created by Panacea-Soft on 8/8/15.
 * Contact Email : teamps.is.cool@gmail.com
 */
public class PCategoryData implements Parcelable {

    public int id;

    public int shop_id;

    public String name;

    public int is_published;

    public int ordering;

    public String added;

    public String updated;

    public String cover_image_file;

    public int cover_image_width;

    public int cover_image_height;

    public ArrayList<PSubCategoryData> sub_categories;
    public Double value;

    protected PCategoryData(Parcel in) {
        id = in.readInt();
        shop_id = in.readInt();
        name = in.readString();
        is_published = in.readInt();
        ordering = in.readInt();
        added = in.readString();
        updated = in.readString();
        cover_image_file = in.readString();
        cover_image_width = in.readInt();
        cover_image_height = in.readInt();
        if (in.readByte() == 0x01) {
            sub_categories = new ArrayList<PSubCategoryData>();
            in.readList(sub_categories, PSubCategoryData.class.getClassLoader());
        } else {
            sub_categories = null;
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeInt(shop_id);
        dest.writeString(name);
        dest.writeInt(is_published);
        dest.writeInt(ordering);
        dest.writeString(added);
        dest.writeString(updated);
        dest.writeString(cover_image_file);
        dest.writeInt(cover_image_width);
        dest.writeInt(cover_image_height);
        if (sub_categories == null) {
            dest.writeByte((byte) (0x00));
        } else {
            dest.writeByte((byte) (0x01));
            dest.writeList(sub_categories);
        }
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<PCategoryData> CREATOR = new Parcelable.Creator<PCategoryData>() {
        @Override
        public PCategoryData createFromParcel(Parcel in) {
            return new PCategoryData(in);
        }

        @Override
        public PCategoryData[] newArray(int size) {
            return new PCategoryData[size];
        }
    };
}
Ezekiel
  • 89
  • 3
  • 12
  • The error thrown was `com.google.gson.JsonSyntaxException`. Sounds like your JSON is invalid to me. – wakjah Jul 17 '16 at 13:19
  • It is not, I updated the post to see how it looks "data" in logs. – Ezekiel Jul 17 '16 at 13:21
  • The JSON data you pasted is invalid in a trivially obvious way. Try putting it through a validator like http://jsonlint.com/ and you will see why. – wakjah Jul 17 '16 at 13:29
  • It is valid, but I didn't post the whole json content, because it's very long. – Ezekiel Jul 17 '16 at 13:34

1 Answers1

0

I guess that PCategoryData has double field, and guess that json value of that double field is "";

UPDATE

Your code will be like this:

public class CitiesListFragment extends Fragment {

    ...

    private void requestData(String uri) {
                    ...
                    final GsonBuilder gsonBuilder = new GsonBuilder();
                    gsonBuilder.registerTypeAdapter(PCategoryData.class, new PCategoryDataTypeAdapter());
                    final Gson gson = gsonBuilder.create();

                    Type listType = new TypeToken<List<PCityData>>() {
                    }.getType();

                    //String data="";
                    pCityDataList = gson.fromJson(response.getString("Data"), listType);
                    ...
    }

    ...

    class PCategoryDataTypeAdapter extends TypeAdapter<PCategoryData> {

        @Override
        public PCategoryData read(JsonReader in) throws IOException {
            final PCategoryData data = new PCategoryData();

            in.beginObject();
            while (in.hasNext()) {
                switch (in.nextName()) {
                    case "value": //Please change "value" to your field name.
                        try {
                            data.value = Double.valueOf(in.nextString());
                        } catch (NumberFormatException e) {
                            data.value = 0;
                        }
                        break;
                }
            }
            in.endObject();

            return data;
        }

        @Override
        public void write(JsonWriter out, PCategoryData data) throws IOException {
            out.beginObject();
            out.name("value").value(data.value);  //Please change "value" to your field name.
            out.endObject();
        }
    }
    ...
}
nshmura
  • 5,940
  • 3
  • 27
  • 46
  • A number must not be quoted in json. Change "" to 0 in your json. see http://stackoverflow.com/questions/15368231/can-json-numbers-be-quoted – nshmura Jul 17 '16 at 13:44
  • Got it. But should I make them all string, or how? – Ezekiel Jul 17 '16 at 13:47
  • Can't you change the json? – nshmura Jul 17 '16 at 14:03
  • No, I don't think so. This data, is from the backend taken. – Ezekiel Jul 17 '16 at 14:10
  • I can't understand your situation completely. But if you can change the json, it is better to modify the quoted number to unquoted number in your json. ex) "1" -> 1, "" -> 0 – nshmura Jul 17 '16 at 14:19
  • Or you can use TypeAdapter to conver invalid double number "" to 0 , like this: https://gist.github.com/nshmura/cc58affeda0db60424cd0c1165a34d2a – nshmura Jul 17 '16 at 14:30
  • Should I make another class and paste your code, or how should I use it? Thanks a lot man. – Ezekiel Jul 17 '16 at 17:19
  • Throws me this errors: `Error:(17, 36) error: constructor PCategoryData in class PCategoryData cannot be applied to given types; required: Parcel found: no arguments reason: actual and formal argument lists differ in length Error:(26, 38) error: incompatible types: int cannot be converted to Double` . Thank a lot ! – Ezekiel Jul 17 '16 at 17:35
  • please paste PCategoryData.java source code. And I want to know overall json. – nshmura Jul 17 '16 at 17:39
  • Updated first post ! – Ezekiel Jul 17 '16 at 17:47
  • Thanks. "value" in my code is exsample. please change "value" to your real field name. And there is not duble type field in PCategoryData... – nshmura Jul 17 '16 at 17:53
  • Still the same error on this line: `final PCategoryData data = new PCategoryData();` ( `Error:(17, 36) error: constructor PCategoryData in class PCategoryData cannot be applied to given types; required: Parcel found: no arguments reason: actual and formal argument lists differ in length`) – Ezekiel Jul 17 '16 at 17:58
  • I understand. Thank anyway for trying. – Ezekiel Jul 17 '16 at 18:06