Reputation: 752
I'm writing a class with requests to rest API (Yandex disk). I use volley, but I do have some problems with getting a response from it. You can check the rest API here.
I use volley and I can get a response in the debugger, but not in my Activity
.
Here is my Requests
class
class Requests {
private String response_of_server, token;
private String url = "https://cloud-api.yandex.net/v1/disk";
private Context context;
Requests (String token, Context context) {
this.token = token;
this.context = context;
}
private void set_response_of_server(String response) {
this.response_of_server = response;
}
String get_response() {
return response_of_server;
}
void get_metadata_of_user() {
try {
/*Request*/
RequestQueue queue = Volley.newRequestQueue(this.context);
Response.ErrorListener error_listener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
};
Response.Listener<String> response_listener = new Response.Listener<String>()
{
@Override
public void onResponse(String response) {
set_response_of_server(response);
}
};
StringRequest getRequest = new StringRequest(Request.Method.GET, url+"?fields=user", response_listener, error_listener) {
@Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<>();
params.put("Host", "cloud-api.yandex.net");
params.put("Authorization", token);
return params;
}
};
queue.add(getRequest);
/*Request end*/
} catch (Exception e) {
e.printStackTrace();
}
}
}
And the MainActivity
where I want my response.
public class MainActivity extends AppCompatActivity {
private final String ID_OF_APP = "Your token of app";
private final String URL_FOR_CODE_QUERY = "https://oauth.yandex.com/authorize?response_type=token&client_id=" + ID_OF_APP;
private String SAVED_TOKEN = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_get_code = findViewById(R.id.btn_get_code); // send to get code page (yandex)
btn_get_code.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(URL_FOR_CODE_QUERY));
startActivity(i);
}
});
Button btn_sign_in = findViewById(R.id.btn_sign_in);
btn_sign_in.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText code_field = findViewById(R.id.code_field);
String token = code_field.getText().toString();
save_token(token);
try {
if(check_token()) {
//Toast.makeText(MainActivity.this, "You are successfully signed in", Toast.LENGTH_SHORT).show();
// TODO change activity
}
else {}
} catch (InterruptedException e) {
e.printStackTrace();
}
//Toast.makeText(MainActivity.this, "Something went wrong. Please, check your connection and try again later", Toast.LENGTH_SHORT).show();
}
});
}
private void save_token(String token) {
SharedPreferences sPref = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor ed = sPref.edit();
ed.putString(SAVED_TOKEN, token);
ed.apply();
}
private String load_token() {
SharedPreferences sPref = getPreferences(MODE_PRIVATE);
return sPref.getString(SAVED_TOKEN, "");
}
private boolean check_token() throws InterruptedException {
String token = load_token();
String result;
Requests request = new Requests(token, this);
request.get_metadata_of_user();
result = request.get_response();
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
return !(result.equals("-1"));
}
}
check_token()
function at the moment should just make a toast with a response of the server. However, I cannot get the Toast
or any response coming back from the server.
Upvotes: 1
Views: 682
Reputation: 24211
You have a Requests
class which has the function to call the server API which is Asynchronous
. Hence, you will not get the result
immediately after calling the request.get_metadata_of_user();
in your check_token()
function.
Hence I would like to suggest you modify your Request
class like the following.
public class Requests {
private String response_of_server, token;
private String url = "https://cloud-api.yandex.net/v1/disk";
private Context context;
private HttpListener listener; // Add a listener to get the callback functionality
Requests (String token, Context context, HttpListener listener) {
this.token = token;
this.context = context;
this.listener = listener; // initialize the listener here
}
private void set_response_of_server(String response) {
this.response_of_server = response;
listener.onResponseReceived(response); // Send the response back to the calling class
}
String get_response() {
return response_of_server;
}
void get_metadata_of_user() {
try {
RequestQueue queue = Volley.newRequestQueue(this.context);
Response.ErrorListener error_listener = new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
};
Response.Listener<String> response_listener = new Response.Listener<String>()
{
@Override
public void onResponse(String response) {
set_response_of_server(response);
}
};
StringRequest getRequest = new StringRequest(Request.Method.GET, url+"?fields=user", response_listener, error_listener) {
@Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<>();
params.put("Host", "cloud-api.yandex.net");
params.put("Authorization", token);
return params;
}
};
queue.add(getRequest);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Now the HttpListener
class might look like the following. Create HttpListener.java
and add the following code to create this as an interface.
public interface HttpListener {
public void onResponseReceived();
}
Hence you need to implement this interface
in your MainActivity
like the following.
public class MainActivity extends AppCompatActivity implements HttpListener {
private final String ID_OF_APP = "Your token of app";
// I fixed this part too. Please change if that is not useful
private final String URL_FOR_CODE_QUERY = "https://oauth.yandex.com/authorize?response_type=" + SAVED_TOKEN + "&client_id=" + ID_OF_APP;
private String SAVED_TOKEN = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ... I omitted some code
Button btn_sign_in = findViewById(R.id.btn_sign_in);
btn_sign_in.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText code_field = findViewById(R.id.code_field);
String token = code_field.getText().toString();
save_token(token);
try {
// if(check_token()) {
// The check_token function call is Async. This will not return immediately. Hence you might consider removing this if part. Simply just call the function and listen to the callback function when the response is received
// }
check_token(); // Simply call the function here
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
private void save_token(String token) {
SharedPreferences sPref = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor ed = sPref.edit();
ed.putString(SAVED_TOKEN, token);
ed.apply();
}
private String load_token() {
SharedPreferences sPref = getPreferences(MODE_PRIVATE);
return sPref.getString(SAVED_TOKEN, "");
}
// I changed the return type as this is not returning anything.
private void check_token() throws InterruptedException {
String token = load_token();
String result;
Requests request = new Requests(token, this);
request.get_metadata_of_user();
// You will not get the response immediately here. So omit these codes.
// result = request.get_response();
// Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
// return !(result.equals("-1"));
}
@Override
public void onResponseReceived(String response) {
// Here is your response. Now you can use your response
// and can perform the next action here.
}
}
Please note that, the code is not tested. Please modify as per your requirement. I hope that helps you to understand the problem.
Upvotes: 1