I am not sure what I am doing wrong. I am very new to this and just jumped straight into trying to make API calls. I am trying to retrieve information from rapidAPI for a simple project I am working on to view prices of stocks and so on. I am using the volley package from Android Studio to make my APIcalls to retrieve JSON and trying to put that into a textView. The way I imagine this to work is that I press a button and then once that is clicked, it runs the code to get the information and then shows the response in the textView. however, when the button is clicked, nothing happens. no error or response of any sort.
private TextView mTextViewResult;
private RequestQueue mQueue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextViewResult= findViewById(R.id.text_view_result);
Button buttonParse= findViewById(R.id.button_parse);
mQueue= Volley.newRequestQueue(this);
buttonParse.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
jsonParse();
}
});
}
private void jsonParse(){
String url="https://apidojo-yahoo-finance-v1.p.rapidapi.com/market/get-quotes?region=CA&lang=en&symbols=VEQT.TO";
JsonObjectRequest request= new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray= response.getJSONArray("result");
JSONObject result=jsonArray.getJSONObject(0);
int marketPrice= result.getInt("regularMarketPrice");
mTextViewResult.setText(String.valueOf(marketPrice));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mTextViewResult.setText("" +error.toString());
}
}){
#Override
public Map<String,String> getHeaders() throws AuthFailureError{
Map<String,String> params= new HashMap<>();
params.put("x-rapidapi-host", "apidojo-yahoo-finance-v1.p.rapidapi.com");
params.put("x-rapidapi-key", "APIKEY");
return params;
}
};
mQueue.add(request);
}
}
From what you've posted are you sure your x-rapidapi-key is APIKEY. Pretty sure that's the primary reason of your issue. Only after you put a valid API key in your request header, will your API call return a proper expected response.
You can read how to generate the rapidapi key from their official docs here
Currently the response you receive on api call using the wrong apikey is something like this:
{
"message": "Key doesn't exists"
}
Now in your java code you are looking for a JSONArray based on the key "result", while the response currently only has "message" being returned. That's the reason nothing happens, you can try finding the value in response for message and get the error messages if you wish. Generate a valid rapidapi key and try again, Good luck!
Related
I can get very strange issue in my project. I can get the response from volley over the internet and after reposne I want to store it in sharedpref, but issue is that when I get the response and showed up within resonse function then it shows correct data, but when I used to save it outside the response function sharedpref it gives 0. I declared the string public and top of the class but got no luck. Am very strange whats the issue.
SharedPreferences savelogin = getSharedPreferences("login",MODE_PRIVATE);
final SharedPreferences.Editor slogin = savelogin.edit();
String url = "https://datafinderdatabase.xyz/dfapi/FetchId.php?username="+fuser;
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
userid = response.toString();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toasty.error(getApplicationContext(), "Network Issue", Toast.LENGTH_SHORT).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
slogin.putString("username",fuser);
slogin.putString("password",fpass);
slogin.putString("userid",userid);
slogin.commit();
This is because your call to the API is asynchronous. Therefore, the result you get back may be processed after that function finishes. To solve this, you can take a Interface approach, explained here for a similar issue:
wait until firebase retrieves data
OR: you need to save the variable to the shared preferences inside the onResponse function.
These:
slogin.putString("username",fuser);
slogin.putString("password",fpass);
slogin.putString("userid",userid);
slogin.commit();
must be inside this:
#Override
public void onResponse(String response) {
userid = response.toString();
//here
}
I create an application for Android, which saves GPS coordinates and displays them with addresses.
I have a function:
public String getAddressByGpsCoordinates(String latlan) {
requestQueue = Volley.newRequestQueue(this);
String url= "http://maps.googleapis.com/maps/api/geocode/json?latlng="+latlan+"&sensor=true&key=(I have a correct key :))";
JsonObjectRequest request = new JsonObjectRequest(url,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
address = response.getJSONArray("results").getJSONObject(0).getString("formatted_address");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(request);
return address;
}
It is returned NULL all the time.
Can You help me what is wrong with my code?
Using JsonObjectRequest with a RequestQueue is an asynchronous mechanism--the work is performed in the background and the onResponse callback is called whenever the response is ready.
Because of this, it is very likely that you return from your method before onResponse gets called, and since address isn't set beforehand (that you've shown, anyway), its value will be null.
If you want to block your thread until the request has completed and set the value of address, you should use a RequestFuture: Can I do a synchronous request with volley?
My android app needs to send a string, and based on that, needs to get a response from the database.
I have a php that receives the string from the app, queries the database, and returns the response using echo json_encode($response_array); which works fine on the browser and echoes in a json object format.
However, In the app, I am using Volley. The php array $response_array above sends multiple strings which i need to display in the app textview.
I have set up volley in the gradle dependencies.
However, on running the app from my phone (which is connected on my laptop hotspot), the error i get is "null". This is the sample code from the app.
TextView o,t;
private RequestQueue requestQueue;
private static final String URL = "http://172.25.33.189/fadapp/mirror.php";
private StringRequest request;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
o=(TextView)findViewById(R.id.tryOne);
t=(TextView)findViewById(R.id.tryTwo);
requestQueue = Volley.newRequestQueue(this);
request = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonobject = new JSONObject(response);
if (jsonobject.names().get(0).equals("name")) {
o.setText(jsonobject.getString("name"));
if(jsonobject.getString("stat").equals("1")) {
t.setText(R.string.inText);
t.setTextColor(Color.parseColor("#00FF00"));
} else {
t.setText(R.string.outText);
t.setTextColor(Color.parseColor("#FF0000"));
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, ""+error.getMessage(), Toast.LENGTH_SHORT).show();;
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("speid", "database query string here");
return hashMap;
}
};
requestQueue.add(request);
Have you grant the intenet access to the app with ?
If you are hosting from your laptop you may need to open the port 80, to be sure that the problem isn't yor Volley set-up try to query for example google and print the response that should be a 200 http code
String name;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getData();
this.setText(name);
}
private void getData(){
name = object.getString("name");
}
I'm just making my line of code short, anyway the idea is already there. So on the method getData() I'm retrieving data from the web. I am able to test and was able to get the result however when I put the name on the onCreate() it gives me a null value. How to do some work arounds on this?
public class Testing extends NavigationLiveo{
String name;
#Override
public void onInt(Bundle savedInstanceState) {
getData();
Log.wtf("name0", name);
this.username.setText(name);
}
private void getData() {
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
StringRequest sr = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String s) {
try {
name = object.getString("name");
Log.wtf("name1", name);
} catch (Exception e) {
Log.wtf("testing1", e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("user", user_pid);
return params;
}
};queue.add(sr);
}
}
Once again, I've made my coding simple. I can really get the data from the web server. It's just that whenever the I'll try to access the name on the onInt(Bundle savedInstanceState) it returns a null value. The log says it all as well. "name1" returns a value while "name0" returns null.
The only explanation is that the object.getString("name") returns null, or you are setting it to null somewhere afterwards. By the way, when retreiving data from the web, you should use AsyncTask, for more details refer here.
Can you put the getData() code?
I think that since the method uses AsyncTask or so to download the data from URL asynchronously. That means the method hasn't completed downloading, the setText(name) code already executed. So it displays null.
I want to get some JSON code from my API. I wish to do something like this in the OnCreate:
try
{
String jsonstr = getSomeThingAndPauseAndroid("http://someplace.com/api/xyz");
if (!jsonstr.isEmpty()) JSONObject jsonobj = new JSONObject(jsonstr);
}
catch { // handle error }
But when it happens, Android just go doing stuff and don't wait for the request to complete and response and I get nothing on jsonstr.
Is there some way to do that not needing a lot of new class files?
The correct way to do this is to make the request asynchronously and trigger a method on response. This is an example using Google's Volley:
//Start volley:
RequestQueue queue = Volley.newRequestQueue(this); // this = context
final String url = "http://someplace.com/api/xyz"";
// prepare the Request
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response) {
//This is where you setup your UI
//Remember to dismiss the ProgressDialog
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
//Remember to dismiss the ProgressDialog
Log.d("Error.Response", response);
}
}
);
// add it to the RequestQueue
//Here you should add a ProgressDialog so the user knows to wait
queue.add(getRequest);