I want to parse a single url from my remote json file. I have a Button code in onCreate and I want to parse url from my json object to my DynamicButton.
private void parseJSON() {
String url = https://www.example.com/data.json
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("MyDynamicUrl");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject hit = jsonArray.getJSONObject(i);
String myDynamicLink = hit.getString("Link");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mRequestQueue.add(request);
}
I have this button in onCreate and Now I want to parse myDynamicLink to this button. I am getting Error "Can not resolve symbol 'MyDynamicLink' "
DLbtn = findViewById(R.id.DynamicLinkButton);
DLbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String url = myDynamicLink;
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
My json file structure
{
"MyDynamicUrl": [
{"Link":"https://www.myDynamicUrl.com"}
]}
You should define myDynamicLink as a field outside of the method and then set a value to it:
private String myDynamicLink;
private void parseJSON() {
...
myDynamicLink = hit.getString("Link");
...
}
Also note, that the request is made asynchronously (on another thread),
it means that your button may be already initialized and you can click it, but possibly you may still not receive a response.
In addition, you may start using a library for converting JSON objects to Java objects, such as Gson, it will let you much easily parse the JSON.
Related
I would like to access the data associated under the current dates of this json link. For instance, for the date : "2020-09-26",i would like to access the revenue associated under that date. I tried researching my question but i have not found anything helpful. Could someone assist me with this? So far, i already downloaded the json data and parsed it as well as extracted the revenue and date from the json file but i would like to get the revenue under each specified date.
https://financialmodelingprep.com/api/v3/income-statement/AAPL?limit=120&apikey=demo
private void downloadAnalystEstimateData(String api) {
// Initialize a new JsonArrayRequest instance
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
Request.Method.GET,
api,
null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
// Do something with response
//mTextView.setText(response.toString());
//Log.i("jsonResponse", response.toString());
// Process the JSON
// Loop through the array elements
for (int i = 0; i < response.length(); i++) {
// Get current json object
try {
stockDetails = response.getJSONObject(i);
// Log.i("analyst estimate data..", stockDetails.toString());
dates = stockDetails.getString("date");
revenue = stockDetails.getString("revenue");
Log.i("revenue", revenue);
Log.i("dattes", dates);
// Log.i("estimatedRevenueLow", estimatedEbitdaLow);
//Log.i("revenueGrowth", estimatedRevenueLow);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Do something when error occurred
// Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
Log.i("error", error.toString());
// Toast.makeText(Analyze_Stocks_Activity.this, "An error occured....", Toast.LENGTH_SHORT).show();
}
}
);
// Add JsonArrayRequest to the RequestQueue
requestQueue.add(jsonArrayRequest);
}
I know this question has been asked a few times and i have tried all the solutions however, nothing seems to work. My method:
public static LocationGeoData getLocationGeoData(Location location){
RequestQueue requestQueue = Volley.newRequestQueue(MyApplication.getAppContext());
Date dateNow = new Date();
SimpleDateFormat fmt = new SimpleDateFormat("yyyy.MM.dd");
String url = "MYCORRECTURL";
Log.d("geoData", "In getGeoData " + url); // this is called and logs
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("geoData", "inside the response");// this never gets called
try {
JSONObject jsonObject = response.getJSONObject("data");
for(int i = 0; i <jsonObject.length(); i++){
JSONObject heading = jsonObject;
if(heading.getString("field-value").equals("field-value")){
JSONObject totIntensity = heading.getJSONObject("total-intensity");
JSONObject declination = heading.getJSONObject("declination");
JSONObject inclination = heading.getJSONObject("inclination");
int totalIntensity = totIntensity.getInt("value");
double declinationValue = declination.getDouble("value");
double inclinationValue = inclination.getDouble("value");
locationGeoData = new LocationGeoData(totalIntensity, declinationValue, inclinationValue);
}
}
} catch (JSONException e) {
Log.d("geoData", "Error recorded");//never called
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("geoData", "Error recorded");// never called
}
});
requestQueue.add(request);
return locationGeoData;
}
The second Log message inside the response never gets called, i get no error messages, my url works and i can see the JsonOBject in the browser when tested, but the response is never called in my method. Can anyone advise me what i am doing wrong?
this is the api response i ma accessing the json object and setting the textview of uuid in text view but nothing happen
please suggest code for accessing json object from api response
{
"success":true,
"data {
"serial_key_id":"75",
"order_id":"0",
"product_id":"0",
"serial_key":"WURYFO",
"valid_till":null,
"limit":"0",
"uuid":"",
"used":false
}
}
private void jsonobject() {
String url = "http://mylocalpay.com/?serial_key_api=1&coupon=WURYFO";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i("msg", "response" + response);
try {
JSONObject success = response.getJSONObject("success");
JSONObject data = response.getJSONObject("data");
String serial_key_id = data.getString("serial_key_id");
String order_id = data.getString("order_id");
String product_id = data.getString("product_id");
String serial_key = data.getString("serial_key");
String limit = data.getString("limit");
String uuid = data.getString("uuid");
boolean used = data.getBoolean("used");
JSONObject valid_till = data.getJSONObject("valid_till");
textView.setText(uuid);
System.out.println(serial_key);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
});
}
}
You need to parse this JSON into a java object. You could write your own code to do this (which is a very large undertaking) or you could use Googles GSON library.
GSON GitHub page
You can use this library as so
Gson gson = new Gson();
String jsonInString = "{'serial_key_id' : '75'}";
YourClass yourClass = gson.fromJson(jsonInString, YourClass.class);
I'm using Volley however I'm having some problems with the JSON parsed data most likely because volley doesn't implement something like AsyncTask's onPostExecute() and I'm getting some duplicated data on wrong list items.
Then I came across this: https://github.com/yakivmospan/volley-request-manager#custom-listener-implementation-
Has anyone use it? How can I add it to my current Volley code?
More details about my problem here Volley not sending correct data. How to implement an alternative to onPostExecute()?
UPDATE
As requested, some code. Here's a button that calls a method on another class that uses Volley to request some raw JSON data (NovaJSON) and then send the JSON to a parser class (NovaParser):
info.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String instanceDetail = NovaJSON.shared().receiveDetail(getId());
Dialog dialog = new Dialog(v.getContext());
dialog.setContentView(R.layout.instances_info);
TextView image = (TextView) dialog.findViewById(R.id.imageInstance);
TextView flavor = (TextView) dialog.findViewById(R.id.flavorInstance);
dialog.setTitle(name.getText() + " Details");
if (instanceDetail != null) {
image.setText(" \u2022 image : " + NovaParser.shared().parseImages(instanceDetail));
flavor.setText(" \u2022 flavor : " + NovaParser.shared().parseFlavor(instanceDetail));
}
dialog.show();
}
});
This is the method that does the Volley request on the NovaJSON class:
public void getJSONdetail() {
final String authToken = getAuth();
String novaURL = getNova();
novaURL = novaURL+"/servers/"+id;
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, novaURL, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("Nova on Response", response.toString());
setNovaJSONdetail(response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("Nova on Error", "Error: " + error.getMessage());
setNovaJSONdetail(error.toString());
}
}
) {
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("X-Auth-Token", authToken);
params.put("User-Agent", "stackerz");
params.put("Accept", "application/json");
params.put("Content-Type", "application/json; charset=utf-8");
return params;
}
};
queue = VolleySingleton.getInstance(this).getRequestQueue();
queue.add(getRequest);
}
It then sends the JSON from the server as a string to be parsed using the following methods:
public static String parseImages(String imagesDetail){
ArrayList<HashMap<String, String>> imagesList = NovaParser.shared().getImagesList();
String temp = null;
JSONObject novaDetail = null;
try {
novaDetail = new JSONObject(imagesDetail);
JSONObject server = novaDetail.getJSONObject("server");
JSONObject image = server.getJSONObject("image");
if (imagesList !=null){
temp = image.getString("id");
for (Map<String,String> map : imagesList) {
if (map.containsValue(temp)) {
temp = map.get(NAME);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return temp;
}
public static String parseFlavor(String instanceDetail){
ArrayList<HashMap<String, String>> flavorList = NovaParser.shared().getFlavorList();
String temp = null;
JSONObject novaDetail = null;
try {
novaDetail = new JSONObject(instanceDetail);
JSONObject server = novaDetail.getJSONObject("server");
JSONObject flavor = server.getJSONObject("flavor");
if (flavorList !=null){
temp = flavor.getString("id");
for (Map<String,String> map : flavorList) {
if (map.containsValue(temp)) {
temp = map.get(NAME);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return temp;
}
When I press the button once the dialog is displayed with empty values. When I press it the second time I get the correct parsed data. Basically first time I click the button the instanceDetail string is null because Volley didn't finish doing its thing then I click the 2nd time it loads the values accordingly because it finally finished the 1st request.
I understand Volley is asynchronous, the requests happen in parallel and the responses sometimes are not immediate however I need some sort of progress bar or spinning wheel to give the user some feedback that the app is waiting for data. It could be done with AsyncTask however it doesn't seem to be possible with Volley.
I think your problem is not because of Volley.
Check the parameters you send and receive.
However if you need onPostExcecute you have Volley's callback:
Response.Listener<JSONObject> and Response.ErrorListener() which are called after the request.
About Volley request manager just switch all your volley calls with appropriate Volley request manager calls
I solved my problem by dumping Volley altogether and moving to Retrofit. I setup all the calls to be sync/blocking, worked out the exceptions/errors using try/catches and setup a short timeout on the OkHTTP client. Now it's working as I wanted.
I'm using this code for sending data to server , but when i want to parser response data on volley onResponse method , my UI freezing .
JsonObjectRequest req = new JsonObjectRequest(Method.GET, url, null, new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response)
{
parseFromJsonObject(response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
}
});
RequestHelper.getInstance().addToRequestQueue(req, this);
And it's parser method
public boolean parseFromJsonObject(JSONObject response)
{
boolean validResponse = super.isValidResponse(response);
try
{
if(response.has("keywords"))
{
JSONObject keywords = response.getJSONObject("keywords");
Iterator<?> langIterator = keywords.keys();
ArrayList<LanguagesStorage> languagesStorageArray = new ArrayList<LanguagesStorage>();
while(langIterator.hasNext())
{
String lang = (String) langIterator.next();
JSONObject langValues = keywords.getJSONObject(lang);
Iterator<?> valueIterator = langValues.keys();
while(valueIterator.hasNext())
{
String key = (String) valueIterator.next();
String value = (String) langValues.getString(key);
LanguagesStorage languagesStorage = new LanguagesStorage();
languagesStorage.setKey(key);
languagesStorage.setLang(lang);
languagesStorage.setValue(value);
languagesStorageArray.add(languagesStorage);
}
}
if(languagesStorageArray.size() > 0)
{
LanguageAdapter languageAdapter = new LanguageAdapter();
languageAdapter.insert(languagesStorageArray, true);
}
}
return lastParsingStatus = true;
}
catch (JSONException e)
{
RLog.error("Parsing error in keyword Parser " + e);
return lastParsingStatus = false;
}
}
What is the issue ? Why my UI thread freezing?
Volley onResponce work inside the UI thread
I recommend you to do parsing inside a separate thread.
In your parseFromJsonObject method, try to create a new Thread and inside that thread execute your parsing data.