My java skills are quite good, still I fail to grasp what happens here.
I am programming an android app and right now I am programming a class which uses the Google Volley API in order to interact with a web-server.
The problem is that I want the class to be called like this:
Server_interaction s_i = new Server_interaction(getApplication);
String text = s_i.post_request();
Text should now contain the returned post request, in my case the string "Hello from server". Instead, it turns out to be null. This happens because the post_request method seems to return before having executed the post_request.
Here is the Server_interaction class:
public class Server_interaction
{
String server_url = "someipadress/greeting.php"; //this address is correct, but I want to hide it for you guys :)
String response_string;
Context myContext;
RequestQueue requestQueue;
public static final String TAG = Server_interaction.class.getSimpleName();
/* Here we add a constructor that takes in context. We need a context for volley requestqueue, and this is an elegant way*/
public Server_interaction(Context context)
{
myContext = context;
requestQueue = Volley.newRequestQueue(myContext);
}
public String post_request()
{
StringRequest stringRequest = new StringRequest(Request.Method.POST, server_url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
response_string = response;
requestQueue.stop();
Log.i(TAG, "the response is: "+ response_string);
}
}
, new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
response_string = "Something went wrong";
//error.printstacktrace()
requestQueue.stop();
}
}
); //stringrequest parameter end
//add request to requestqueue
requestQueue.add(stringRequest);
Log.i(TAG, "the response again:: "+ response_string);
return response_string;
}
}
When being executed, logcat shows this:
01-22 19:00:44.878 2954-2954/com.example.koenraad.Exigentia I/Server_interaction: the response again:: null
01-22 19:00:44.926 2954-2954/com.example.koenraad.Exigentia I/Server_interaction: the response is: hello from server
So this means that the string is null when being returned, then afterwards it is set. How can this be fixed?
Thanks in advance!
Your code is asynchrounous.
The StringRequest object created in method post_request() will be used by the framework after the method returns.
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'm doing a school project where i need to parse a JSON and make queries to get specific values. The API in question is this one http://data.nba.net/10s/prod/v2/2018/teams.json and I only want the teams of the "standard" array.
For example I want only the teams which are NBA Franchise, I tried the following:
private void loadTeams() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(application);
String franchise = preferences.getString("isnbafranchise", "true");
Uri baseUri = Uri.parse(NBA_REQUEST_URL);
Uri.Builder uriBuilder = baseUri.buildUpon();
uriBuilder.appendQueryParameter("isnbafranchise", franchise);
RequestQueue requestQueue = Volley.newRequestQueue(application);
StringRequest request = new StringRequest(Request.Method.GET, uriBuilder.toString(), new Response.Listener<String>() {
#Override
public void onResponse(String response) {
List<NBATeam> teamList = QueryUtils.extractFeatureFromJson(response);
teams.setValue(teamList);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error Volley", error.toString());
}
});
requestQueue.add(request);
}
But it is the same as without the appendQueryParameter, returns all the taams. I've also tried doing a GET request from Mozilla (http://data.nba.net/10s/prod/v2/2018/teams.json?isnbafranchise=true) and the same result, which makes me think that I'm not doing the query correctly.
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?
Alright, I've looked all over the website for a possible solution to send a POST request using android but I don't seem to understand the usage of Volley here or the method which was starting an async thread to make the request.
private RequestQueue signupRequestQ = Volley.newRequestQueue(this);
#Override
public void onClick(View view) {
String postUrl = "https://mypost.url";
signupRequestQ.start();
switch (view.getId()) {
case R.id.signupBtn:
if (((EditText) findViewById(R.id.passwordSignup)).getText().toString().length() < 6) {
Dialog.showInvalidInputFieldsDialog(this,"Password must be longer than 5 characters").show();
} else {
try {
StringRequest strRequest = new StringRequest(Request.Method.POST, postUrl,
response -> {
System.out.println(response);
},
error -> {
System.out.println("What the funk");
}) {
#Override
protected Map<String, String> getParams() {
LinkedHashMap<String, String> postForm = new LinkedHashMap<String, String>();
postForm.put("test", "var");
return postForm;
}
};
signupRequestQ.add(strRequest);
} catch (ParseException e) {
System.out.println("Something went wrong");
}
}
}
For some reason, this code causes my app to crash with a java.lang.RuntimeException and java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getCacheDir()' on a null object reference.
However, I should not be encountering the NullPointerException as the Volley RequestQueue javadoc clearly stated that I only had to provide a context for the newRequestQueue method which I did.
Could anyone please help with my issue? Thank you!
It's because you instanciate your RequestQueue with a null Context at the top of your Activity :
private RequestQueue signupRequestQ = Volley.newRequestQueue(this); // "this" is null here
Try to create your RequestQueue in the onCreate() method of your Activity like :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
signupRequestQ = Volley.newRequestQueue(this);
}
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);