JsonMappingException: Can not construct instance of... rest API in androidstudio [duplicate] - java

This question already has answers here:
Jackson error: no suitable constructor
(2 answers)
Closed 3 years ago.
I'm trying to implement the global magnet API in an android application. I do a rest API get request and put the json API data in a string (this string is called dataString. This string looks like this:
{
declination: {
units: "Deg",
value: -4.8235602378845215
},
inclination: {
units: "Deg",
value: -30.085556030273438
},
total_intensity: {
units: "nT",
value: 31945.123046875
}
}
I'm now trying to deserialize this string into an object. I've made the following classes:
public class MagneticData {
#JsonProperty("declination")
public MagneticDataElement declination;
#JsonProperty("grid_variation")
public MagneticDataElement grid_variation;
#JsonProperty("inclination")
public MagneticDataElement inclination;
#JsonProperty("total_intensity")
public MagneticDataElement total_intensity;
}
public class MagneticDataElement {
#JsonProperty("units")
public String units;
#JsonProperty("value")
public double value;
}
I now use the ObjectMapper.readValue() function to convert the dataString to an object of the type MagneticData but i get the following error:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.mobcom.apitest.MainActivity$MagneticData: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
What am i doing wrong?

I tested your code with revised JSON string and add toString() to your POJOs, everything works fine as follows, so maybe you have to provide more information for debugging such as how you deserialize it and which version of Jackson library you used.
Revised JSON string
{
"declination": {
"units": "Deg",
"value": -4.8235602378845215
},
"inclination": {
"units": "Deg",
"value": -30.085556030273438
},
"total_intensity": {
"units": "nT",
"value": 31945.123046875
}
}
Code snippet
ObjectMapper mapper = new ObjectMapper();
MagneticData magneticData = mapper.readValue(jsonStr, MagneticData.class);
System.out.println(magneticData.toString());
Console output
MagneticData [declination=MagneticDataElement [units=Deg, value=-4.8235602378845215], inclination=MagneticDataElement [units=Deg, value=-30.085556030273438], total_intensity=MagneticDataElement [units=nT, value=31945.123046875]]

I'm using jackson version 2.8.5:
implementation 'com.fasterxml.jackson.core:jackson-databind:2.8.5'
implementation 'com.fasterxml.jackson.core:jackson-core:2.8.5'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.8.5'
This is my full code:
public class MainActivity extends AppCompatActivity {
Button click;
TextView data;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"units",
"value"
})
public class MagneticData {
#JsonProperty("declination")
public MagneticDataElement declination;
#JsonProperty("grid_variation")
public MagneticDataElement grid_variation;
#JsonProperty("inclination")
public MagneticDataElement inclination;
#JsonProperty("total_intensity")
public MagneticDataElement total_intensity;
MagneticData(MagneticDataElement d, MagneticDataElement g, MagneticDataElement i, MagneticDataElement t) {
declination = d;
grid_variation = g;
inclination = i;
total_intensity = t;
}
}
public class MagneticDataElement {
#JsonProperty("units")
public String units;
#JsonProperty("value")
public double value;
MagneticDataElement(String u, double v) {
units = u;
value = v;
}
}
public void deserialize(String str) throws IOException {
//data.setText(jsonNode.get("total_intensity").textValue());
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
click = findViewById(R.id.button);
data = findViewById(R.id.fetchedData);
click.setOnClickListener(new View.OnClickListener() {
String dataString = "";
#Override
public void onClick(View v) {
AsyncTask.execute(new Runnable() {
#Override
public void run() {
double altitude = 0;
double latitude = 0;
double longitude = 0;
double year = 2019;
URL url = null;
try {
url = new URL("https://globalmagnet.amentum.space/api/calculate_magnetic_field?altitude="+altitude+"&latitude="+latitude+"&longitude="+longitude+"&year="+year);
HttpsURLConnection myConnection = (HttpsURLConnection) url.openConnection();
myConnection.setRequestMethod("GET");
myConnection.setRequestProperty("Accept", "application/json");
if (myConnection.getResponseCode() == 200) {
Log.e("TYPE", myConnection.getContentType());
Log.e("Content", String.valueOf(myConnection.getInputStream()));
InputStream inputStream = myConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while (line != null) {
line = bufferedReader.readLine();
dataString = dataString + line;
}
Log.e("DATA", dataString);
MagneticData magneticData = new ObjectMapper().readValue(dataString, MagneticData.class);
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
} else {
Log.e("ERROR", String.valueOf(myConnection.getResponseCode()));
Log.e("ERROR", myConnection.getResponseMessage());
Log.e("ERROR", String.valueOf(myConnection.getHeaderField("altitude")));
}
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
});
}
});
}
}

Related

Jackson no suitable constructor found for android.graphics.Bitmap

I'm trying to serialize my Character object with the use of Jackson. The mapper.writeValue method invocation is successful it seems, but when I try to read the value with the use of mapper.readValue I get the following error message:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of android.graphics.Bitmap: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: java.io.FileReader#9ab6557; line: 1, column: 199] (through reference chain: java.lang.Object[][0]->com.myproj.character.Character["compositeClothes"]->com.myproj.character.clothing.CompositeClothing["clothes"]->java.util.ArrayList[0]->com.myproj.character.clothing.concrete.Hat["bitmap"])
These are my classes:
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "#class")
#JsonSubTypes({
#JsonSubTypes.Type(value = Hat.class, name = "hat"),
#JsonSubTypes.Type(value = Necklace.class, name = "necklace"),
#JsonSubTypes.Type(value = Shirt.class, name = "shirt")
})
public interface Clothing {
int getCoolness();
int getrId();
Bitmap getBitmap();
}
My hat class:
public class Hat implements Clothing {
private int rId;
private int coolness;
private Bitmap bitmap;
#JsonCreator
public Hat(#JsonProperty("coolness") int coolness, #JsonProperty("bitmap") Bitmap bitmap) {
rId = R.id.hat_image;
this.coolness = coolness;
this.bitmap = bitmap;
}
public int getrId() {
return rId;
}
#Override
public int getCoolness() {
return coolness;
}
public Bitmap getBitmap() {
return bitmap;
}
}
My composite clothing class:
public class CompositeClothing implements Clothing, Iterable<Clothing> {
#JsonProperty("coolness")
private int coolness = 0;
private List<Clothing> clothes = new ArrayList<>();
public void add(Clothing clothing) {
clothes.add(clothing);
}
public void remove(Clothing clothing) {
clothes.remove(clothing);
}
public Clothing getChild(int index) {
if (index >= 0 && index < clothes.size()) {
return clothes.get(index);
} else {
return null;
}
}
#Override
public Iterator<Clothing> iterator() {
return clothes.iterator();
}
#Override
public int getCoolness() {
return coolness;
}
#Override
public int getrId() {
return 0;
}
#Override
public Bitmap getBitmap() {
return null;
}
}
And my character class:
public class Character implements Observable {
private static final transient Character instance = new Character();
#JsonProperty("compositeClothes")
private CompositeClothing clothes = new CompositeClothing();
#JsonProperty("compositeHeadFeatures")
private CompositeHeadFeature headFeatures = new CompositeHeadFeature();
private transient List<Observer> observers = new ArrayList<>();
#JsonProperty("skin")
private Skin skin;
public void attach(Observer observer) {
observers.add(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
public void setSkin(Skin skin) {
this.skin = skin;
notifyAllObservers();
}
public Skin.Color getSkinColor() {
return skin.getColor();
}
public Bitmap getSkinBitmap() {
return skin.getBitmap();
}
public boolean hasSkin() {
return skin != null;
}
public void addClothing(Clothing clothing) {
Clothing oldClothing = (Clothing) getSameTypeObjectAlreadyWorn(clothing);
if (oldClothing != null) {
clothes.remove(oldClothing);
}
clothes.add(clothing);
notifyAllObservers();
}
public CompositeClothing getClothes() {
return clothes;
}
private Object getSameTypeObjectAlreadyWorn(Object newClothing) {
Class<?> newClass = newClothing.getClass();
for (Object clothing : clothes) {
if (clothing.getClass().equals(newClass)) {
return clothing;
}
}
return null;
}
public void removeClothing(Clothing clothing) {
clothes.remove(clothing);
}
public void addHeadFeature(HeadFeature headFeature) {
HeadFeature oldHeadFeature = (HeadFeature) getSameTypeObjectAlreadyWorn(headFeature);
if (oldHeadFeature != null) {
headFeatures.remove(oldHeadFeature);
}
headFeatures.add(headFeature);
notifyAllObservers();
}
public void removeHeadFeature(HeadFeature headFeature) {
headFeatures.remove(headFeature);
}
public CompositeHeadFeature getHeadFeatures() {
return headFeatures;
}
public static Character getInstance() {
return instance;
}
}
The code that I'm using to persist and then read the data:
File charactersFile = new File(getFilesDir() + File.separator + "characters.ser");
ObjectMapper mapper = new ObjectMapper()
.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
try (FileWriter fileOut = new FileWriter(charactersFile, false)) {
List<Character> characters = Arrays.asList(character);
mapper.writeValue(fileOut, characters);
} catch (IOException e) {
e.printStackTrace();
}
Character[] characters = null;
try (FileReader fileIn = new FileReader(charactersFile)) {
characters = mapper.readValue(fileIn, Character[].class);
} catch (IOException e) {
e.printStackTrace();
}
Thanks!
If your bitmaps come from assets or resources, there is no point on saving the bitmaps to JSON. That would be a waste of CPU time and disk space. Instead, store a value in the JSON that will allow you to identify the asset or resource to display. However, bear in mind that resource IDs (e.g., R.drawable.foo) can vary between app releases, so that is not a good durable identifier for the image.
I have similar requirement in my app where I need to store drawable data in JSON. I solved it by storing only its string name. For example, if I have resource R.drawable.testBmp then I store it in JSON like :
{
...
"mydrawable" : "testBmp"
}
Then at run time, I will read it and convert is as drawable like following code:
JSONObject jsonObj;
...
String bmpName = jsonObj.getString("mydrawable");
int resId = context.getResources().getIdentifier(bmpName,
"drawable",
context.getPackageName());
Drawable bmp = ContextCompat.getDrawable(context,resId);

Setter doesnt work [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Iam trying to make login activity
I got a problem. My setter doesnt work, i dont know why?
I have 3 classes.
1st one is Data with server data and getters and setters
public class Data{
String addressesURL = "/DataSnap/rest/TServerMethods1/LookupCustomers";
String articlesURL = "/DataSnap/rest/TServerMethods1/LookupArticle";
String invoicesURL = "/DataSnap/rest/TServerMethods1/LookupInvoice";
String invoicesDetailsURL = "/DataSnap/rest/TServerMethods1/LookupInvoicePos";
String invoicesDetailsAddressesURL = "/DataSnap/rest/TServerMethods1/LookupInvoiceAddress";
String ordersURL = "/DataSnap/rest/TServerMethods1/LookupOrders";
String ordersDetailsURL = "/DataSnap/rest/TServerMethods1/LookupOrdersPos";
String ordersDetailsAddressesURL = "/DataSnap/rest/TServerMethods1/LookupOrdersAddress";
public String serverURL;
//String serverURL = "http://10.10.10.75:8081";
String username = "admin";
String password = "admin";
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddressesURL() {
return addressesURL;
}
public void setAddressesURL(String addressesURL) {
this.addressesURL = addressesURL;
}
public String getArticlesURL() {
return articlesURL;
}
public void setArticlesURL(String articlesURL) {
this.articlesURL = articlesURL;
}
public String getInvoicesURL() {
return invoicesURL;
}
public void setInvoicesURL(String invoicesURL) {
this.invoicesURL = invoicesURL;
}
public String getInvoicesDetailsURL() {
return invoicesDetailsURL;
}
public void setInvoicesDetailsURL(String invoicesDetailsURL) {
this.invoicesDetailsURL = invoicesDetailsURL;
}
public String getInvoicesDetailsAddressesURL() {
return invoicesDetailsAddressesURL;
}
public void setInvoicesDetailsAddressesURL(String invoicesDetailsAddressesURL) {
this.invoicesDetailsAddressesURL = invoicesDetailsAddressesURL;
}
public String getOrdersURL() {
return ordersURL;
}
public void setOrdersURL(String ordersURL) {
this.ordersURL = ordersURL;
}
public String getOrdersDetailsURL() {
return ordersDetailsURL;
}
public void setOrdersDetailsURL(String ordersDetailsURL) {
this.ordersDetailsURL = ordersDetailsURL;
}
public String getOrdersDetailsAddressesURL() {
return ordersDetailsAddressesURL;
}
public void setOrdersDetailsAddressesURL(String ordersDetailsAddressesURL) {
this.ordersDetailsAddressesURL = ordersDetailsAddressesURL;
}
public String getServerURL() {
return serverURL;
}
public void setServerURL(String serverURL) {
this.serverURL = serverURL;
}}
2nd one is where I start my login Activity
public class Settings extends AppCompatActivity {
//declarations
//Edittext fields for username , server, password & port information
EditText edtIpurl, edtPort, edtUsername, edtPassword;
//Textviews that can be clicked
TextView databaseDel, databaseRef, magnumgmbh, contact, support;
//imagebuttons for bottom menu
ImageButton contacts, articles, invoices, orders;
//string for server URL
//String sURL = "http://";
Thread newSettingsThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
setTitle("Settings");
newSettingsThread = new Thread(){
public void run(){
runOnUiThread(new Runnable() {
#Override
public void run() {
String serverURL = "http://rest.magnumgmbh.de";
//edtIpurl = (EditText)findViewById(R.id.edtIpurl);
Data newD = new Data();
newD.setServerURL(serverURL);
}
});
}
};
newSettingsThread.start();
//start activitys if bottom buttons clicked
contacts = (ImageButton) findViewById(R.id.contacts);
//articles activity start
contacts.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//start activity addresses
Intent startAddresses = new Intent(Settings.this, Addresses.class);
startActivity(startAddresses);
}
});
}}
And the next one is where i try to get my new serverURL
public class Address extends AppCompatActivity{
Thread newAddressThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addresses);
//set activity name
setTitle("Addresses");
//new thread for network operations
newAddressesThread = new Thread() {
public void run() {
//make text from json
jsonText = new StringBuilder();
try {
String str;
Data newData = new Data();
//json dates url
String addressesURL = newData.getAddressesURL();
String serverUrl = newData.getServerURL();
String username = newData.getUsername();
String password = newData.getPassword();
URL url = new URL(serverUrl + addressesURL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//String encoded = Base64.encode("admin:admin");
String encoded = Base64.encodeToString((username+":"+password).getBytes("UTF-8"), Base64.NO_WRAP);
urlConnection.setRequestProperty("Authorization", "Basic " + encoded);
//check http status code
try {
int statusCode = urlConnection.getResponseCode();
System.out.println(statusCode);
} catch (IOException e) {
}
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
while ((str = in.readLine()) != null) {
jsonText.append(str);
}
//cast stringbuilder to string
addressesJsonStr = jsonText.toString();
//close IOstream
in.close();
} catch (MalformedURLException e1) {
System.out.println(e1.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
};
//start thread
newAddressesThread.start();
}}
Hier in the third one by serverURL I got null and it thow me an exeption "Protocol not found: null/DataSnap/rest/TServerMethods1/LookupCustomers" so that is my problem.
What do I wrong?
you are creating a new Object in the third class, so the url has the initilize value because the url you've setted in the second class is stored in another object.
If you want that all Objects of Type Data have the same adress, make the variable static otherwise you have to access the object you have created in the second class in the third class.

parse json object using gson in android

i have an json object like this and i am getting this response in my Fragment.
json
{
"data":{
"categories":[
{
"id":"d5c4eedf-093e-422f-8335-6c6376ca3ccb",
"schedule_m_id":1,
"title_en":"Bakery Products",
"title_fr":"Produits de boulangerie",
"subtitle_en":"Bread, Cakes, Cookies, Crackers, Pies",
"subtitle_fr":"Pain, gateaux, biscuits, craquelins, tartes",
"created_at":"2015-03-04 15:39:44",
"updated_at":"2015-03-04 15:39:44"
},
{
"id":"6d1d4945-9910-40ae-82a8-3fe4137c24c2",
"schedule_m_id":2,
"title_en":"Beverages",
"title_fr":"Boissons",
"subtitle_en":"Soft Drinks, Coffee, Tea, Cocoa",
"subtitle_fr":"Boissons gazeuses, café, thé, cacao",
"created_at":"2015-03-04 15:39:44",
"updated_at":"2015-03-04 15:39:44"
}
]
},
"result":"success"
}
and my categories class is like this:
public class Categories {
private int id;
private String title_en;
private String title_fr;
private int schedule_m_id;
private String subtitle_en;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle_en() {
return title_en;
}
public void setTitle_en(String title_en) {
this.title_en = title_en;
}
public String getTitle_fr() {
return title_fr;
}
public void setTitle_fr(String title_fr) {
this.title_fr = title_fr;
}
public int getSchedule_m_id() {
return schedule_m_id;
}
public void setSchedule_m_id(int schedule_m_id) {
this.schedule_m_id = schedule_m_id;
}
public String getSubtitle_en() {
return subtitle_en;
}
public void setSubtitle_en(String subtitle_en) {
this.subtitle_en = subtitle_en;
}
}
In my fragment how can i parse this json object. i need to make an ArrayList which type is "Categories". i need this Categories object List to make an custom adapter. Can anybode help me.
JSONObject jsonObject = (JSONObject) response;
JSONObject dataProject = jsonObject.getJSONObject("data");
JSONArray products = dataProject.getJSONArray("categories");
Gson gson = new Gson();
Categories categories = new Categories();
ArrayList<Categories> items = new ArrayList<Categories>();
int productCount = products.length();
for (int i = 0; i < productCount; i++) {
categories = gson.fromJson(products.get(i), Categories.class);
items.add(categories);
}
```
I posting a class working with gson volley May be Helpful for you....
Step1. For Parsing your json data use "www.jsonschema2pojo.org/" and generate pojo classes. copy classes in your project with same name.
Step2. Just create a GsonRequest Class as follows (taken from https://developer.android.com/training/volley/request-custom.html)
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;
/**
* Make a GET request and return a parsed object from JSON.
*
* #param url URL of the request to make
* #param clazz Relevant class object, for Gson's reflection
* #param headers Map of request headers
*/
public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
#Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(
gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
Step3.Now in your main Activity just use this "GsonRequest" class like that:
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
GsonRequest<MyPojoClass> gsonRequest = new GsonRequest<MyPojoClass>(
Request.Method.GET,
apiurl,
MyPojoClass.class,
mySuccessListener(),
myErrorListener());
//Add below these code lines for "Retry" data fetching from api
gsonRequest.setRetryPolicy(new DefaultRetryPolicy(
5000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
mRequestQueue.add(gsonRequest);
}
private Response.Listener<MyPojoClass> mySuccessListener() {
return new Response.Listener<CustomRequest>() {
#Override
public void onResponse(MyPojoClass pRequest) {
//do something
}
};
}
private Response.ErrorListener myErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println(volleyError.getMessage().toString());
}
};
}

How do I combine two separate parsed jsonObjects into a single arraylist?

I would like to combine two separate parsed jsonObjects into a single arraylist, then display the results as Strings?
I would like to store summaryJsonObject & segment in storylineData. When I step through the code using the debugger summaryJsonObject & segment both hold the raw json. The raw json data also shows in the logcat but storylineData remains null & unavailable throughout.
Here is the parsing code.
public class StorylineData {
private static String date;
private ArrayList<SummaryData> summary;
private ArrayList<SegmentData> segments;
private String caloriesIdle;
private String lastUpdate;
public String getDate() {
return date;
}
public ArrayList<SummaryData> getSummary() {
return summary;
}
public ArrayList<SegmentData> getSegments() {
return segments;
}
public String getCaloriesIdle() {
return caloriesIdle;
}
public String getLastUpdate() {
return lastUpdate;
}
public void setDate(String date) {
this.date = date;
}
public void setSummary(ArrayList<SummaryData> summary) {
this.summary = summary;
}
public void setSegments(ArrayList<SegmentData> segments) {
this.segments = segments;
}
public void setCaloriesIdle(String caloriesIdle) {
this.caloriesIdle = caloriesIdle;
}
public void setLastUpdate(String lastUpdate) {
this.lastUpdate = lastUpdate;
}
public static StorylineData parse(JSONObject jsonObject) {
if (jsonObject != null) {
StorylineData storylineData = new StorylineData();
storylineData.date = jsonObject.optString("date");
storylineData.caloriesIdle = jsonObject.optString("caloriesIdle");
storylineData.lastUpdate = jsonObject.optString("lastUpdate");
storylineData.summary = new ArrayList<SummaryData>();
storylineData.segments = new ArrayList<SegmentData>();
JSONArray summariesJsonArray= jsonObject.optJSONArray("summary");
if (summariesJsonArray != null) {
for (int i = 0; i < summariesJsonArray.length(); i++) {
JSONObject summaryJsonObject = summariesJsonArray.optJSONObject(i);
if (summaryJsonObject != null) {
storylineData.summary.add(SummaryData.parse(summaryJsonObject));
Log.d("storylineHandler", summaryJsonObject.toString());
}
}
}
JSONArray segmentsJsonArray = jsonObject.optJSONArray("segments");
if (segmentsJsonArray != null) {
for (int i = 0; i < segmentsJsonArray.length(); i++) {
JSONObject segment = segmentsJsonArray.optJSONObject(i);
if (segment != null) {
storylineData.segments.add(SegmentData.parse(segment));
Log.d("storylineHandler", segment.toString());
}
}
}
return storylineData;
}
return null;
}
}
The MainActivity looks like this:
MainActivity
public class MainActivity extends FragmentActivity implements OnClickListener{
..other variables here..
List<StorylineData> storylineData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...other ui elements here...
mEditTextResponse = (TextView) findViewById(R.id.editResponse);
storylineData = new StorylineData();
MovesAPI.init(this, CLIENT_ID, CLIENT_SECRET, CLIENT_SCOPES.....
#Override
public void onClick(View v) {
toggleProgress(true);
switch (mSpinnerAPI.getSelectedItemPosition()) {
... other cases here...
break;
...other cases here...
case 4: // Get Summary Day
MovesAPI.getSummary_SingleDay(summaryHandler, "20150418", null);//Date changed to "20150117"
break;
Other cases here..
case 10: // Get Storyline Day
MovesAPI.getStoryline_SingleDay(storylineHandler, "20150418", null, false);//Date changed to "20150418"
break;
...Other cases here..
}
}
... Other MovesHandlers here...
private JSONObject summaryJsonObject;
private List<StorylineData> storylineList;
private JSONObject summariesJsonArray;
private MovesHandler<ArrayList<StorylineData>> storylineHandler = new MovesHandler<ArrayList<StorylineData>>() {
#Override
public void onSuccess(ArrayList<StorylineData> result) {
toggleProgress(false);
storylineList = (List<StorylineData>) StorylineData.parse(summaryJsonObject);
updateResponse( + storylineData.toString() + "\n" //displays true to layout view
result.add(StorylineData.parse(summariesJsonArray))+ "\n"
+Log.d("call result", result.toString()) + "\n" //displays 60 in layout view & com.protogeo.moves.demos.apps.storyline.StorylineData#52824f88, null]
+ Log.d("Log.d storylineHandler", storylineHandler.toString()) + "\n" ); //returns 78 in layout view & com.protogeo.moves.demos.apps.Mainactivity#234234 to log cat
onFailure code here..
}
};
public void toggleProgress(final boolean isProgrressing) {
togglePregress code here..
}
public void updateResponse(final String message) {
runOnUiThread(new Runnable() {
public List<StorylineData> storylineList;
#Override
public void run() {
mEditTextResponse.setText(message);
if (storylineData!= null) {
for (StorylineData storylineData : storylineList) {
mEditTextResponse.append(("storylineData" + storylineData.toString()));
}
}
}
});
}
}
HttpClass
public static void getDailyStorylineList(final MovesHandler<JSONArray> handler,
final String specificSummary,
final String from,
final String to,
final String pastDays,
final String updatedSince,
final boolean needTrackPoints) {
new Thread(new Runnable() {
#Override
public void run() {
try {
/* Refresh access token if only AuthData.MOVES_REFRESHBEFORE days are there to expire current token */
AuthData.refreshAccessTokenIfNeeded();
/* Exchange the authorization code we obtained after login to get access token */
HashMap<String, String> nameValuePairs = new HashMap<String, String>();
nameValuePairs.put("access_token", AuthData.getAuthData().getAccessToken());
// if (specificSummary != null && specificSummary.length() > 0) nameValuePairs.put("specificSummary", specificSummary);//att
if (from != null && from.length() > 0) nameValuePairs.put("from", from);
if (to != null && to.length() > 0) nameValuePairs.put("to", to);
if (pastDays != null && pastDays.length() > 0) nameValuePairs.put("pastDays", pastDays);
if (updatedSince != null && updatedSince.length() > 0) nameValuePairs.put("updatedSince", updatedSince);
if (needTrackPoints) nameValuePairs.put("trackPoints", "true");
URL url = new URL(MovesAPI.API_BASE + MovesAPI.API_PATH_STORYLINE + (specificSummary != null ? specificSummary : "") + "?" + Utilities.encodeUrl(nameValuePairs));
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.connect();
if (urlConnection.getResponseCode() != 200) {
/* All other HTTP errors from Moves will fall here */
handler.onFailure(getErrorStatus(Utilities.readStream(urlConnection.getErrorStream()), urlConnection.getResponseCode()), "Server not responded with success ("+ urlConnection.getResponseCode() +")");
return;
}
String response = Utilities.readStream(urlConnection.getInputStream());
Object object = new JSONTokener(response).nextValue();
if (object instanceof JSONArray) {
JSONArray jsonArray = (JSONArray) object;
ArrayList<StorylineData> storylineData = new ArrayList<StorylineData>();
if (jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject storylineJsonObject = jsonArray.optJSONObject(i);
if (storylineJsonObject != null) {
storylineData.add(StorylineData.parse(storylineJsonObject));
}
}
}
handler.onSuccess(storylineData);
} else {
handler.onFailure(MovesStatus.INVALID_RESPONSE, "Expected a JSONArray from server, but failed");
}
} catch (Exception ex) {
ex.printStackTrace();
handler.onFailure(MovesStatus.UNEXPECTED_ERROR, "An unexpected error occured, please check logcat");
}
}
}).start();
}
MovesHandler
public interface MovesHandler<T> {//T stands for generic type
/**
* Implement this method to get success notifications along with the result
* #param result : Result of the operation completed with this handler
*/
public void onSuccess(ProfileData result);
/**
* Implement this method to get failure notifications along with the {#link MovesStatus} code and a brief message
* #param status : Status code of the failure
* #param message : A brief message about the reason behind failure
*/
public void onFailure(MovesStatus status, String message);
}
If you wanted to have one ArrayList to store both SummaryData and SegmentData, you could just created an ArrayList of Objects, ArrayList<Object>. This would be the more general solution.
The alternative would be having SummaryData and SegmentData inherit the same class or implement the same interface.
Using an extended class, you could have:
class Data {
}
class SegmentData extends Data {
}
class SummaryData extends Data {
}
You could then have an ArrayList that would be able to add both SegmentData and SummaryData objects.
If you wanted to show each item as a String you would need to loop through the list and call the toString() function of each item
ArrayList<Data> dataList;
for (Data d : dataList) {
Log.d("data", d.toString())
}
Just make sure to overwrite the toString() function in SegmentData and SummaryData
EDIT: Showing how to print JsonArray
If you wanted to just print for JsonArrays, you could:
public class StorylineData {
private static String date;
private JSONArray summary;
private JSONArray segments;
private String caloriesIdle;
private String lastUpdate;
public String getDate() {
return date;
}
public JSONArray getSummary() {
return summary;
}
public JSONArray getSegments() {
return segments;
}
public String getCaloriesIdle() {
return caloriesIdle;
}
public String getLastUpdate() {
return lastUpdate;
}
public void setDate(String date) {
this.date = date;
}
public void setSummary(JSONArray summary) {
this.summary = summary;
}
public void setSegments(JSONArray segments) {
this.segments = segments;
}
public void setCaloriesIdle(String caloriesIdle) {
this.caloriesIdle = caloriesIdle;
}
public void setLastUpdate(String lastUpdate) {
this.lastUpdate = lastUpdate;
}
public static StorylineData parse(JSONObject jsonObject) {
if (jsonObject != null) {
StorylineData storylineData = new StorylineData();
storylineData.date = jsonObject.optString("date");
storylineData.caloriesIdle = jsonObject.optString("caloriesIdle");
storylineData.lastUpdate = jsonObject.optString("lastUpdate");
storylineData.summary = jsonObject.optJSONArray("summary");
storylineData.segments = jsonObject.optJSONArray("segments");
return storylineData;
}
return null;
}
#Override
public String toString() {
JSONArray combined = new JSONArray(summary);
combined.put(segment);
return combined.toString();
}
}
In your MainActivity
private StorylineData storylineData;
private MovesHandler<JSONArray> storylineHandler = new MovesHandler<JSONArray>() {
#Override
public void onSuccess(JSONArray result) {
toggleProgress(false);
storylineData = StorylineData.parse(summaryJsonObject);
updateResponse(storylineData.toString()) //displays true to layout view
result.add(storylineData.getSummary());
Log.d("call result", result.toString());
Log.d("Log.d storylineHandler", storylineHandler.toString());
}
};

converting json with gson error Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

[{"user_id":"5633795","username":"_Vorago_","count300":"203483","count100":"16021","count50":"1517","playcount":"1634","ranked_score":"179618425","total_score":"1394180836","pp_rank":"34054","level":"59.6052","pp_raw":"1723.43","accuracy":"96.77945709228516","count_rank_ss":"1","count_rank_s":"19","count_rank_a":"17","country":"US","events":[]}]
I'm trying to convert the JSON above with GSON but am running into errors.
package com.grapefruitcode.osu;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import com.google.gson.Gson;
public class Main {
static String ApiKey = "";
public static void main(String[]Args) throws Exception{
String json = readUrl("");
System.out.println(json);
Gson gson = new Gson();
User user = gson.fromJson(json, User.class);
System.out.println();
}
private static String readUrl(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
return buffer.toString();
} finally {
if (reader != null)
reader.close();
}
}
}
The url and api key are left blank for security reasons, the variables are filled when I run the code and the json is converted to a string properly. I've tested it already. If somebody could tell me what is causing the error that would be wonderful.
package com.grapefruitcode.osu;
public class User {
String user_id = "";
String username = "";
String count300 = "";
String count100= "";
}
In JSON
[ ... ] represents array
{ ... } represents object,
so [ {...} ] is array containing one object. Try using
Gson gson = new Gson();
User[] users = gson.fromJson(json, User[].class);
System.out.println(Arrays.toString(users));
//or since we know which object from array we want to print
System.out.println(users[0]);
Using RetroFit 2 Solution
interface APIInterface {
#POST("GetDataController/GetData")
Call<GeoEvent> getGeofanceRecord(#Body GeoEvent geoEvent);
}
APIInterface apiInterface; // Declare Globally
apiInterface = APIClient.getClient().create(APIInterface.class);
final GeoEvent geoEvent = new GeoEvent(userId);
Call<GeoEvent> call = apiInterface.getGeofanceRecord(geoEvent);
call.enqueue(new Callback<GeoEvent>() {
#Override
public void onResponse(Call<GeoEvent> call, Response<GeoEvent> response) {
GeoEvent geoEvent1 = response.body();
// Log.e("keshav","Location -> " +geoEvent1.responseMessage);
List<GeoEvent.GeoEvents> geoEventsList = geoEvent1.Table; // Array Naame
List<GeoEvent.GeoEvents> geoEventsArrayList = new ArrayList<GeoEvent.GeoEvents>();
geoEventsArrayList.addAll(geoEventsList);
for (GeoEvent.GeoEvents geoEvents : geoEventsList) {
Log.e("keshav", "Location -> " + geoEvents.Location);
Log.e("keshav", "DateTime -> " + geoEvents.DateTime);
}
if (geoEventsArrayList != null) {
adapter.clear();
adapter.addAll(geoEventsArrayList);
adapter.notifyDataSetChanged();
}
}
#Override
public void onFailure(Call<GeoEvent> call, Throwable t) {
call.cancel();
}
});
Your Pojo Class Like This
package pojos;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class GeoEvent {
public String userId;
public GeoEvent(String userId){
this.userId= userId;
}
public List<GeoEvents> Table = new ArrayList<>();
public class GeoEvents {
#SerializedName("Location")
public String Location;
#SerializedName("DateTime")
public String DateTime;
public String getLocation() {
return Location;
}
public void setLocation(String location) {
Location = location;
}
public String getDateTime() {
return DateTime;
}
public void setDateTime(String dateTime) {
DateTime = dateTime;
}
}
}

Categories