This question already has answers here:
How do I parse JSON in Android? [duplicate]
(3 answers)
Using GSON to parse a JSON with dynamic "key" and "value" in android
(2 answers)
Closed 5 years ago.
This is my JsonResponse , and since its not in array i am facing some difficulties , can any one help me out ? in android
{
"errorno": "0",
"responsemsg": "Login Success.",
"busid": "1234",
"returnmobileno": "1234567890"
}
try this
try {
JSONObject lJsonObject = new JSONObject(response);
String errorno = lJsonObject .getString("errorno");
String responsemsg = lJsonObject .getString("responsemsg");
String busid = response.lJsonObject ("busid");
String returnmobileno = lJsonObject .getString("returnmobileno");
} catch (JSONException e) {
e.printStackTrace();
}
Try this,
try {
String errorno = response.getString("errorno");
String responsemsg = response.getString("responsemsg");
String busid = response.getString("busid");
String returnmobileno = response.getString("returnmobileno");
Log.d(TAG, "errorno:" + errorno+" responsemsg:"+responsemsg+" busid:"+busid+" returnmobileno:"+returnmobileno);
} catch (JSONException e) {
e.printStackTrace();
}
use below code to pass your strong
serverData = gson.fromJson(response, ServerData.class);
in build.gradle -> dependencies
// retrofit, gson
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
public class ApiClient {
public static final String SERVER_BASE_URL = "http://example.com/abc/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(SERVER_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public interface ApiInterface {
#POST("appServices/getData.php")
#FormUrlEncoded
Call<ResponseBody> getAllDataJSONFromServer(#Field("vcode") String vcode);
}
public class ServerData implements Parcelable {
public static final Creator<ServerData> CREATOR = new Creator<ServerData>() {
#Override
public ServerData createFromParcel(Parcel in) {
return new ServerData(in);
}
#Override
public ServerData[] newArray(int size) {
return new ServerData[size];
}
};
private static final int VERSION = 1;
#SerializedName("errorno")
private String errorno;
#SerializedName(responsemsg)
private String responsemsg;
#SerializedName("busid")
private String busid;
#SerializedName("returnmobileno")
private String returnmobileno;
private void readFromParcel(Parcel in) {
if (in.readInt() == VERSION) {
errorno = in.readString();
responsemsg = in.readString();
busid = in.readString();
returnmobileno = in.readString();
}
}
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(VERSION);
parcel.writeString(errorno);
parcel.writeString(responsemsg);
parcel.writeString(busid);
parcel.writeString(returnmobileno);
}
#Override
public int describeContents() {
return 0;
}
public String getErrorno() {
return errorno;
}
public void setErrorno(String errorno) {
this.errorno = errorno;
}
public String getResponsemsg() {
return responsemsg;
}
public void setResponsemsg(String responsemsg) {
this.responsemsg = responsemsg;
}
public String getBusid() {
return busid;
}
public void setBusid(String busid) {
this.busid = busid;
}
public String getReturnmobileno() {
return returnmobileno;
}
public void setReturnmobileno(String returnmobileno) {
this.returnmobileno = returnmobileno;
}
}
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
// get and save all data from server
Call<ResponseBody> call = apiService.getAllDataJSONFromServer(local_vcode, local_cvcode, pckgName);
call.enqueue(new Callback<ResponseBody>() {
#SuppressWarnings("ConstantConditions")
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> responsebody) {
try {
String response = responsebody.body().string();
serverData = gson.fromJson(response, ServerData.class); // this will fetch data to model class ServerData
if (serverData != null) {
// do the rest here...
String vcode = serverData.getVcode();
Log.e("~~~ vode = ", vcode);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
progressDialog.dismiss();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
try {
t.printStackTrace();
progressDialog.dismiss();
} catch (Exception ignored) {
}
}
});
Related
textView = findViewById(R.id.textVieww);
String url = "https://zenquotes.io/api/random";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
final String myResponse = response.body().string();
try {
JSONArray jsonarray = new JSONArray(myResponse);
for(int i=0; i<jsonarray.length(); i++) {
JSONObject obj = jsonarray.getJSONObject(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
Quote.this.runOnUiThread(() ->
textView.setText(myResponse));
}
}
});
}
This is the part im stuck on i think im on the right track but not sure where to go from here im trying to get the "q" information from the returned url and the "a" information but it just outputs everything any suggestions?
What was your problem
Even when you parsed JSON string, you were still using the myResponse string in your textView.setText() method.
Continuing your code snippet
your code snippet is quite short, but i do think i can quite understand what you mean.
So let's say that we have Activity, which is called MainActivity and in that activity we have two views, one TextView called that has an id of tv_author_and_quote and one Button which has a xml id btn_request_quote.
The button has an OnClickListener which calls method requestForQuote().
Our onCreate + the variables of Button and TextView looks like this:
TextView tvAuthorAndQuote;
Button btnRequestQuote;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvAuthorAndQuote = findViewById(R.id.tv_author_and_quote);
btnRequestQuote = findViewById(R.id.btn_request_quote);
btnRequestQuote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
requestForQuote();
}
});
}
And then we have a code itself for method requestForQuote():
public void requestForQuote() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
if (response.isSuccessful()) {
final String myResponse = Objects.requireNonNull(response.body()).string();
String myFormattedQuote = "";
try {
JSONArray jsonarray = new JSONArray(myResponse);
for(int i=0; i<jsonarray.length(); i++) {
JSONObject obj = jsonarray.getJSONObject(i);
String quote = obj.getString("q");
String author = obj.getString("a");
Log.d(TAG, "onResponse: quote:" + quote);
Log.d(TAG, "onResponse: author:" + author);
myFormattedQuote = author + ": " + quote;
}
} catch (JSONException e) {
e.printStackTrace();
}
final String myFinalQuote = myFormattedQuote;
MainActivity.this.runOnUiThread(() -> {
if (!myFinalQuote.equals("")) {
tvAuthorAndQuote.setText(myFinalQuote);
} else {
tvAuthorAndQuote.setText(myResponse);
}
});
}
}
});
}
The code above basically uses your existing solution, but instead of setting the text of textView with myResponse string, it parses the json array and gets a quote and an author from it. Then it just logs it (just for testing purposes), then it constructs the string which gets displayed to the if there is any, otherwise it prints the response. That it is.
Using Gson library
import it into your gradle dependecies
implementation 'com.google.code.gson:gson:2.8.7'
Write short "holder" class called Quote
public class Quote {
public Quote() {
}
String q;
String a;
String h;
public String getQ() {
return q;
}
public void setQ(String q) {
this.q = q;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getH() {
return h;
}
public void setH(String h) {
this.h = h;
}
#NonNull
#NotNull
#Override
public String toString() {
return a + ": " + q;
}
}
Then the requestForQuote() method could look something like this:
public void requestForQuoteWithGson() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
if (response.isSuccessful()) {
final String myResponse = Objects.requireNonNull(response.body()).string();
Type listType = new TypeToken<ArrayList<Quote>>(){}.getType();
List<Quote> yourClassList = new Gson().fromJson(myResponse, listType);
if (yourClassList != null && yourClassList.size() > 0) {
final Quote quote = yourClassList.get(0);
if (quote != null) {
myQuotes.add(quote);
MainActivity.this.runOnUiThread(() ->
tvAuthorAndQuote.setText(quote.toString())
);
}
}
}
}
});
}
I want to parse time from
<monday>
<item>
<time>00:00:00</time>
</item>
...
</monday>
as long
I defiend items as
#Root(strict = false)
private static class Item {
#Element(name = "time")
#Convert(TimeConverter.class)
private Long time;
}
My Converter
public class TimeConverter implements org.simpleframework.xml.convert.Converter<Long> {
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
#Override
public Long read(InputNode node) throws Exception {
try {
String value = node.getValue();
return df.parse(value).getTime();
} catch (Exception e) {
Log.e("mcheck", "read: ", e);
return 0L;
}
}
#Override
public void write(OutputNode node, Long value) throws Exception {
try {
String v = df.format(new Date(value));
node.setValue(v);
} catch (Exception e) {
Log.e("mcheck", "write: ", e);
}
}
}
However when I parse it I receive
retrofit.RetrofitError: java.lang.NumberFormatException: Invalid long: "00:00:00"
As this exception is not caught in my try-catch blocks in converter I assume that parser does not visit converter at all.
My retrofit 1.9 call
OkHttpClient httpClient = new OkHttpClient();
RestAdapter.Builder builder = new RestAdapter.Builder();
builder.setEndpoint(url);
builder.setLogLevel(RestAdapter.LogLevel.FULL);
builder.setConverter(new SimpleXMLConverter());
builder.setClient(new OkClient(httpClient));
RestAdapter restAdapter = builder.build();
ChansonApi api = restAdapter.create(ChansonApi.class);
api.getStreamProgram(new Callback<StreamProgram>() {
#Override
public void success(StreamProgram streamProgram, Response response) {
if(streamProgram!=null){
Log.e("mcheck", "success: "+streamProgram.getProgram());
}
}
#Override
public void failure(RetrofitError error) {
Log.e("mcheck", "failure: ",error);
}
});
The problem was in proguard settings. I had to add TimeConverter to -keep class list
I have a retrofit 2 response by which i gets data from server. my code is working fine.
But i want cache this response using SharedPreferences and keep it till that activity is running and after activity is destroyed. i want to delete this response from SharedPreferences.
This is my Code:
public class SampleClass {
private DataInterface mListener;
public SampleClass() {
super();
}
public void getDataForId(final String id) {
ApiInterface apiInterface = APIClient.getApiInterface();
Call<MyResponse> call = apiInterface.getResponse();
call.enqueue(new Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if (response!=null && response.body() != null && mListener != null) {
mListener.responseData(response.body());
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
}
});
}
public void setOnDataListener(DataInterface listener) {
mListener = listener;
}
public interface DataInterface {
void responseData( MyResponse myResponse );
}
}
SecondData class file
sampleClass.setOnDataListener(new SampleClass.DataInterface() {
#Override
public void responseData(MyResponse myResponse) {
// i wanna store this response into SharedPreferences for temp and delete after activity is destroyed.
List<Detail> details = myResponse.getDetails();
for (Detail d : details) {
if (d.getId().equals(id)) {
reqDetail = d;
name.setText(reqDetail.getName());
Picasso.with(SecondData.this)
.load(reqDetail.getName())
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.into(image);
}
}
}
});
ApiInterface
public interface ApiInterfaceNew {
#GET("/display.php")
Call<MyResponse> getResponse();//imp to include MyResponse as a call
}
Api class
private static final String ROOT_URL = "";
private static Retrofit retrofit1 = null;
private static final String CACHE_CONTROL = "Cache-Control";
public static Retrofit getClient() {
if (retrofit1 == null) {
retrofit1 = new Retrofit.Builder()
.baseUrl(ROOT_URL)
.client(provideOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit1;
}
public static ApiInterfaceNew getApiInterface() {
return getClient().create(ApiInterfaceNew.class);
}
private static OkHttpClient provideOkHttpClient() {
return new OkHttpClient.Builder()
.addInterceptor(provideHttpLoggingInterceptor())
.addInterceptor(provideOfflineCacheInterceptor())
.addNetworkInterceptor(provideCacheInterceptor())
.cache(provideCache())
.build();
}
private static Cache provideCache() {
Cache cache = null;
try {
cache = new Cache(new File(AppControler.getInstance().getCacheDir(), "http-cache"),
10 * 1024 * 1024); // 10 MB
} catch (Exception e) {
Timber.e("Could not create Cache!");
}
return cache;
}
private static HttpLoggingInterceptor provideHttpLoggingInterceptor() {
HttpLoggingInterceptor httpLoggingInterceptor =
new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
Timber.e(message);
}
});
httpLoggingInterceptor.setLevel(BuildConfig.DEBUG ? HEADERS : NONE);
return httpLoggingInterceptor;
}
public static Interceptor provideCacheInterceptor() {
return new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// re-write response header to force use of cache
CacheControl cacheControl = new CacheControl.Builder()
.maxAge(2, TimeUnit.MINUTES)
.build();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl.toString())
.build();
}
};
}
public static Interceptor provideOfflineCacheInterceptor() {
return new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!AppControler.hasNetwork()) {
CacheControl cacheControl = new CacheControl.Builder()
.maxStale(7, TimeUnit.DAYS)
.build();
request = request.newBuilder()
.cacheControl(cacheControl)
.build();
}
return chain.proceed(request);
}
};
}
AppControler class
public class AppControler extends Application {
private static AppControler instance;
#Override
public void onCreate()
{
super.onCreate();
instance = this;
if (BuildConfig.DEBUG)
{
Timber.plant(new Timber.DebugTree());
}
Timber.i("Creating our Application");
}
public static AppControler getInstance ()
{
return instance;
}
public static boolean hasNetwork ()
{
return instance.checkIfHasNetwork();
}
public boolean checkIfHasNetwork()
{
ConnectivityManager cm = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
Add below code in your Retrofit response when a response is success.
First convert JSON to string and store.
Gson gson = new Gson();
String favData = gson.toJson(response.body());
save strings to prefrance.
preferenceManager is my SharedPref class
preferenceManager.setStringPreference(Global.OFFLINE_WORD, favData);
now when you want to get pref data call below method.
public ArrayList<MyResponse> getData(String key) {
String data = getStringPreference(key);
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<MyResponse>>() {
}.getType();
return gson.fromJson(data, type);
}
You can use either ObjectMapper or Gson.
For ObjectMapper you can refer the below code
public static void updateUserInfo(UserInfo userInfo, Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Crashlytics.log("updating User Info "+(userInfo!=null?userInfo.toString():"UserInfo is null"));
final SharedPreferences.Editor edit = preferences.edit();
ObjectMapper objectMapper = new ObjectMapper();
try {
String value = objectMapper.writeValueAsString(userInfo);
edit.putString("USER_INFO_MODEL", value);
edit.commit();
} catch (JsonProcessingException e) {
Exceptions.propagate(e);
}
}
you can also get the stored response from shared preferences
public static UserInfo getUserInfo(Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String userDetatails = preferences.getString(AppConstants.USER_INFO_MODEL, "");
Crashlytics.log("get UserInfo "+userDetatails);
ObjectMapper mapper = new ObjectMapper();
if (StringUtils.isEmpty(userDetatails)) {
return null;
}
UserInfo userInfo = null;
try {
userInfo = mapper.readValue(userDetatails, UserInfo.class);
} catch (IOException e) {
Exceptions.propagate(e);
}
return userInfo;
}
I am building an android application and I am new to json. I am fetching below josn formate -
{
"contact"[
{
"key1": "hey1",
"key2": [
{
"key3": "hey2"
}
]
}
]
}
I am using below code to fetch key1 value. Now problem I am facing is how to fetch key3 value -
jsonString = http.makeServiceCall(url, ServiceHandler.GET, null);
if (jsonString != null) {
try {
JSONObject jsonObj = new JSONObject(jsonString);
// Getting JSON Array node
questions = jsonObj.getJSONArray(TAG_CONTACTS);
for (int i = 0; i < questions.length(); i++) {
temp_obj = questions.getJSONObject(i);
key1Array.add(temp_obj.getString("key1").toString());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Please help me
If you want to use Gson to parse your json data. Let try it:
First of all, you must modify your json like this:
{
"contact":[
{
"key1": "hey1",
"key2": [
{
"key3": "hey2"
}
]
}
]
}
Second add Gson to your libs and sync build.gradle: download here extract it, and copy/past gson-2.2.4.gson to libs folder.
Third Create some class:
FullContents.java:
public class FullContents {
private List<ObjectKey> contact;
public List<ObjectKey> getContact() {
return contact;
}
public void setContact(List<ObjectKey> contact) {
this.contact = contact;
}
}
ObjectKey.java:
public class ObjectKey {
private String key1;
private List<ObjectKey3> key2;
public List<ObjectKey3> getKey2() {
return key2;
}
public void setKey2(List<ObjectKey3> key2) {
this.key2 = key2;
}
public String getKey1(){
return key1;
}
public void setKey1(String key1){
this.key1 = key1;
}
}
ObjectKey3.java:
public class ObjectKey3 {
private String key3;
public String getKey3(){
return key3;
}
public void setKey3(String key3){
this.key3 = key3;
}
}
And Finally, get data from url:
private class ParseByGson extends AsyncTask<String,Void,FullContents> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected FullContents doInBackground(String... params) {
FullContents fullContents = null;
try {
URL url=new URL(params[0]);
InputStreamReader reader=new InputStreamReader(url.openStream(),"UTF-8");
fullContents=new Gson().fromJson(reader,FullContents.class);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fullContents;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(FullContents results) {
super.onPostExecute(results);
ObjectKey objectKey = results.getContact().get(0);
Log.e(">>",objectKey.getKey1()+"--");
}
}
you can put below code to onCreate:
ParseByGson parseByGson = new ParseByGson();
parseByGson.execute(urlStringHere);
Update: Explain
1st of all: your json appears to be not valid (missing ':' after "content");
After reviewing thins:
You can use the named getters to retrieve many types of results (object, int, string, etc);
JSONObject contact = jsonObj.getJSONObject("contact"); // {"key1":"hey1","key2":[{"key3":"hey2"}]}
or
String key1 = jsonObj.getString("key1"); // hey1
To retrieve key3, you should use:
JSONObject contact = jsonObj.getJSONObject("contact");
JSONObject key2 = contact.getJSONObject("key2");
String key3 = key2.getString("key3");
Adapt the following code to what you are coding
for (int i = 0; i < questions.length(); i++) {
temp_obj = questions.getJSONObject(i);
key1Array.add(temp_obj.getString("key1"));
JSONObject temp_objKey2 = temp_obj.getJSONObject("key2");
Key2Object key2Object = new Key2Object();
key2Object.add(temp_objKey2.getString("key3"));
key1Array.add(key2Object);
}
http://www.ibm.com/developerworks/opensource/library/x-android/
I am using the code here, specifically the AndroidSaxParser. The problem is, is that I get all 4 parts of the Message objects the same as the title. I've combed it over and over, but I can't find anything wrong with what I put together.
Any ideas on where to look?
Here is the code:
public class AndroidSaxFeedParser extends BaseFeedParser {
public AndroidSaxFeedParser(String feedUrl) {
super(feedUrl);
}
public List<Message> parse() {
final Message currentMessage = new Message();
RootElement root = new RootElement("rss");
final List<Message> messages = new ArrayList<Message>();
Element channel = root.getChild("channel");
Element item = channel.getChild(ITEM);
item.setEndElementListener(new EndElementListener(){
public void end() {
messages.add(currentMessage.copy());
}
});
item.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){
public void end(String body) {
currentMessage.setTitle(body);
}
});
item.getChild(LINK).setEndTextElementListener(new EndTextElementListener(){
public void end(String body) {
currentMessage.setLink(body);
}
});
item.getChild(DESCRIPTION).setEndTextElementListener(new EndTextElementListener(){
public void end(String body) {
currentMessage.setDescription(body);
}
});
item.getChild(PUB_DATE).setEndTextElementListener(new EndTextElementListener(){
public void end(String body) {
currentMessage.setDate(body);
}
});
try {
Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
} catch (Exception e) {
throw new RuntimeException(e);
}
return messages;
}
}
public abstract class BaseFeedParser implements FeedParser {
// names of the XML tags
static final String PUB_DATE = "pubDate";
static final String DESCRIPTION = "description";
static final String LINK = "link";
static final String TITLE = "title";
static final String ITEM = "item";
static final String CHANNEL = "channel";
final URL feedUrl;
protected BaseFeedParser(String feedUrl){
try {
this.feedUrl = new URL(feedUrl);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
protected InputStream getInputStream() {
try {
return feedUrl.openConnection().getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}