I'm wondering how to pass the response.body() as paramater in order to further process it.
Since now i could pass it only to a Toast, or setText of a textView, and it works just fine.
But if i try to pass it to a function which saves it to SharedPrefs or something like it just passes a null object. I don't get the point why the first is working, but the second not, where's the difference?
My JSon response body looks like this:
{
"Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbkBhZG1vbi5jb20iLCJleHAiOjE1OTQ2NTQ0NjF9.4meOycRP4wbx6hVCJntxH71E03jMYJhg484zCGInUDh6EKPPVDlOhEkCC3X2mjPaCHVfT0qhiulBnC39uh4WEQ"
}
My Pojo like this:
public class LoginResponse {
#Expose
#SerializedName("Authorization")
private String authToken;
public LoginResponse(String authToken) {
this.authToken = authToken;
}
public void setAuthToken(String authToken) {
this.authToken = authToken;
}
public String getAuthToken() {
return authToken;
}
}
The function where I do the Call (it's called after hitting the login button):
private void loginCustomer() {
LoginRequest loginRequest = new LoginRequest(editTextUsername.getText().toString(), editTextPassword.getText().toString());
Call<LoginResponse> loginCall = ApiUtils.getApi().login(loginRequest);
loginCall.enqueue(new Callback<LoginResponse>() {
#Override
public void onResponse(#NotNull Call<LoginResponse> call, #NotNull Response<LoginResponse> response) {
if (!response.isSuccessful()) {
Toast.makeText(LoginActivity.this, "User Credentials Wrong", Toast.LENGTH_SHORT).show();
} else {
if (response.body() != null) {
// this does not work
authToken = response.body().getAuthToken();
saveToken(authToken);
//this does not work either SharedPreferences.Editor editor = sp.edit();
editor.putString("authToken", response.body().getAuthToken());
// openUserMainActivity();
// this works Toast.makeText(LoginActivity.this, response.code() + " " + response.body().getAuthToken(), Toast.LENGTH_SHORT).show();
// this does not work Toast.makeText(LoginActivity.this, sp.getString("authToken", "no token"), Toast.LENGTH_SHORT).show();
}
}
}
Any help will be appreciated. Thanks in Advance!
You forgot to call editor.apply(); or editor.commit(); in order to save the changes.
Related
I was using the retrofit get method to fetch some details from the server.
My retrofit interface is
#GET("studentlist/{schoolid}/{driverid}")
Call<String> getStudentList(#Path("schoolid") String schoolid,#Path("driverid") String driverid);
And when i call my activity I'm getting the two query from the bundle and the data like
Bundle bundle = getIntent().getExtras();
schoolname = bundle.getString("school_id");
driverid = bundle.getString("dri_number");
Call<String> call = api.getStudentList(schoolname, driverid);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Toast.makeText(StudentListActivity.this, response.message(), Toast.LENGTH_SHORT).show();
if (response.isSuccessful()){
if (response.body() != null){
Toast.makeText(StudentListActivity.this, response.body(), Toast.LENGTH_SHORT).show();
String jsonResponse = response.body().toString();
writeRecycler(jsonResponse);
} else {
Log.i("onEmptyResponse", "Returned empty response");
}
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Toast.makeText(StudentListActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
And saving the response like
#SerializedName("status")
private String status;
#SerializedName("res")
public List<StudentListResponse.StudentsList> resp = new ArrayList<>();
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
probably your json has the wrong structure. Verify your JSON structure and validate.
Verify if your JSON data starts with an open quotes.
Gson is expecting your JSON string to begin with an object opening brace. e.g.
{
But the string you have passed to it starts with an open quotes
"
i am facing a problem regarding posting data in an array in android using retrofit 2. i have to post the data of nearly 14 fields in my profile setting activity ...
Like this ...
name="basics[first_name] , name="basics[last_name]" , name="basics[phone_number]"
i have to send data in this format. i am not understanding how to do it need help.i am not understanding how to make Call of the api in the interface because i have to put data in an array.
Currently i am doing it like this but i know its not right...
#FormUrlEncoded
#POST("profile_setting/basic_setting")
Call<ResponseBody> UpdateBasics(
#Query("user_id") int user_id ,
#Field("nickname") String nickname ,
#Field("first_name") String first_name ,
#Field("last_name") String last_name ,
#Field("phone_number") String phone_number ,
#Field("fax") String fax
);
Make a class
public class Basic {
public final int user_id;
public final String nickname;
....
public Basic(int user_id, ...) {
}
}
Then pass list of objects of this class to this interface
public interface MyService {
#POST("/basic")
Response void sendData(#Body List<Basic> basic);
}
Or you can do the same with JSONObject. Just make a list of jsonobjects
JSONObject paramObject = new JSONObject();
paramObject.put(value_one, "field_one"));
paramObject.put(value_second, "field_second"));
put the objects in a list
list.add(paramObject);
then pass to the retrofit
public interface MyService {
#POST("/basic")
Response void sendJsonObjectData(#Body List<JSONObject> basic);
}
Do this way to send Json Object as request parameters using Retrofit 2
#Headers("Content-Type: application/json")
#POST("profile_setting/basic_setting")
Call<ResponseBody> UpdateBasics(#Body String body);
This is how you would use the above method to send json object
try {
JSONObject paramObject = new JSONObject();
paramObject.put(value_one, "field_one"));
paramObject.put(value_second, "field_second"));
Call<ResponseBody> userCall = apiInterface.UpdateBasics(paramObject.toString());
userCall.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//handle your result here
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
//handle failure
}
});
} catch (JSONException e) {
e.printStackTrace();
}
You can follow this was. (posting how i've done that)
#POST("Users.json")
Call<UploadData> uploadToken(#Body UploadData uploadData);
UploadData.class
public class UploadData {
private String DeviceToken, DeviceIMEI;
public UploadData(String deviceToken, String deviceIMEI) {
DeviceToken = deviceToken;
DeviceIMEI = deviceIMEI;
}
public String getDeviceToken() {
return DeviceToken;
}
public String getDeviceIMEI() {
return DeviceIMEI;
}
}
Then in your Activity
private void uploadToken() {
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
UploadData uploadToken = new UploadData(deviceToken, imei);
final Call<UploadData> callUpload = apiInterface.uploadToken(uploadToken);
callUpload.enqueue(new Callback<UploadData>() {
#Override
public void onResponse(Call<UploadData> call, Response<UploadData> response) {
if (response.isSuccessful()) {
Toasty.success(Main.this, "Token Uploaded !! ", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure (Call < UploadData > call, Throwable t){
call.cancel();
Toasty.error(Main.this, "Error: " + t.getLocalizedMessage(),Toast.LENGTH_SHORT).show();
}
});
}
My image is not getting upload to server i have searched several links but didn't find the useful way bellow are the codes
RFInterface.java
#Multipart
#POST("compose_notice")
Call<PostNoticeModel> compose_notice(
#Query("apartment_id") String apartment_id,
#Query("subject") String subject,
#Query("descriptions") String descriptions,
#Query("expiry_time") String expiry_time,
#Query("notice_visible_group") String notice_visible_group,
#Query("selectedUser") String selectedUser,
//#Part ("attachmentFile") RequestBody file
//#Part ("attachmentFile\"; filename=\"attachmentFile\" ") RequestBody attachmentFile
#Part MultipartBody.Part attachmentFile
);
here are the code from where i am getting response to rfinterface.java file
btn_submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
get_title = edt_title.getText().toString();
get_description = edt_description.getText().toString();
if(get_expires.equals("Custom")){
get_expires = custom_date.getText().toString();
}
if(get_title.trim().length() == 0){
Toast.makeText(PostNotice.this, "Please enter title", Toast.LENGTH_SHORT).show();
}else if(get_description.trim().length() == 0){
Toast.makeText(PostNotice.this, "Please enter description", Toast.LENGTH_SHORT).show();
}else {
if(finalfile != null) {
reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), finalfile);
body = MultipartBody.Part.createFormData("attachmentFile", finalfile.getName(), reqFile);
// get_titlee =
// RequestBody.create(MediaType.parse("multipart/form-data"), get_title);
}else{
body = null;
}
//Toast.makeText(PostNotice.this, ""+body, Toast.LENGTH_SHORT).show();
RFInterface api = RFClient.getApiService();
Call<PostNoticeModel> call = api.compose_notice(apartment_id, get_title, get_description, get_expires, get_noticevisibility, suserstring, body);
final ProgressDialog progressDoalog;
progressDoalog = new ProgressDialog(PostNotice.this);
progressDoalog.setMessage("Its loading....");
progressDoalog.setTitle("Please wait it take some time ");
// show it
progressDoalog.show();
call.enqueue(new Callback<PostNoticeModel>() {
#Override
public void onResponse(Call<PostNoticeModel> call, Response<PostNoticeModel> response) {
if (response.isSuccessful()) {
getresponse = response.body().getMsg();
Toast.makeText(getApplicationContext(), getresponse, Toast.LENGTH_LONG).show();
progressDoalog.dismiss();
} else {
Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_SHORT).show();
progressDoalog.dismiss();
}
}
#Override
public void onFailure(Call<PostNoticeModel> call, Throwable t) {
progressDoalog.dismiss();
}
});
}
}
});
please tell me where i am doing wrong all things are working properly all the data get inserted in table to compose notice but image is not uploaded image column remain empty.
Use Requesbody
#Multipart
#POST(urlString)
fun addField(#PartMap partMap: Map,
#Part imagefile: MultipartBody.Part?
): Observable
How can I get users facebook information when he is already logged in? I think I am doing everything fine but its not working..
1st. I am getting the accessToken and checking if it exists. If it does exist I try to get user data.
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken != null) {
String userData = getUserDataFromFacebook(accessToken, headerTitle);
headerTitle.setText(userData);
}
2nd. I try to get the user data the same way as i would get it at the first facebook login.
getUserDataFromFacebook:
private String getUserDataFromFacebook(AccessToken accessToken, final TextView headerTitle) {
Log.v("LoginActivity", "I am here"); // this log works
GraphRequest.newMeRequest(
accessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.v("LoginActivity", "RESPONSE: " + response); //this log doesn`t work.
// Application code
try {
Log.v("LoginActivity", "I am here"); //this log doesn`t work
name = object.getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return name;
}
The biggest problem is that the the onCompleted method is not called and I cant access any of the information. I have no idea why..
P.S. I am terrible at Java and this is my first android application.
You're not actually executing the request.
GraphRequest request = GraphRequest.newMeRequest(
accessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
// your logic
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link");
request.setParameters(parameters);
request.executeAsync();
Keep in mind this is an Async call so you can't return the name from the function like you've tried to do. Instead you'll have to implement a callback mechanism.
Try this code as it is it will help you to get data from facebook.
make sure you already set permission for data on FacebookLoginButton.
private void getUserDataFromFacebook() {
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Log.e(" Response", response.toString());
String res = (String) object.toString();
Log.e("Response", res);
Gson gson = new Gson();
if (res.length() > 0) {
//do your work here with your res
} else {
Utils.showDialog(SelectFacebookAlbumActivity.this, "",
"Error in getting data");
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name");
request.setParameters(parameters);
request.executeAsync();
}
Let us know it it works for you.
Somehow line mResponseText = response.body().string(); isn't writing member variable. Instead it appears to be creating and logging it locally.
Any ideas why? The more I look at it the more clueless I'm getting :(
public class Gateway {
private static final String TAG = Gateway.class.getSimpleName();
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
private String mResponseText = "[{'comment' : 'fake' , 'psn_nickname' : 'fake', 'created':'now', 'parent_class':''}]";
public Gateway (String url, String json, final Context context) {
if(isNetworkAvailable(context)) {
//if network is available build request
OkHttpClient client = new OkHttpClient();
// RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
//.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
//execute call
#Override
public void onFailure(Request request, IOException e) {
// if request failed
Toast.makeText(context, "request failed", Toast.LENGTH_LONG).show();
}
#Override
public void onResponse(Response response) throws IOException {
// if succeeded
if(response.isSuccessful()){
mResponseText = response.body().string();
Log.v(TAG, "SETTING RESPONSE");
// THIS LOGS PROPER JSON LOADED FROM NETWORK
Log.v(TAG, mResponseText);
} else {
//alertUserAboutError(context);
Toast.makeText(context, "Something wrong with response", Toast.LENGTH_LONG).show();
}
}
});
} else {
Toast.makeText(context, "Network is not available", Toast.LENGTH_LONG).show();
}
}
public String getResponse () {
Log.v(TAG, "GETTING RESPONSE");
// THIS LOGS FAKE SAMPLE JSON --- WTF???
Log.v(TAG, mResponseText);
return mResponseText;
}
// check if network is available
private boolean isNetworkAvailable(Context c) {
ConnectivityManager manager = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
/*
private void alertUserAboutError(Context c) {
AlertDialogFragment dialog = new AlertDialogFragment();
dialog.show(c.getFragmentManager(), "error_dialog");
}
*/
}
Here's the code that's using this class
Gateway gateway = new Gateway(mCommentURL, "", this);
String mJsonData = gateway.getResponse();
EDIT Code update - removed extends Activity
You're calling getResponse() too early. The async operation has not completed yet and the value returned is the one you initialize there in the first place, not the one written in the Callback.
Put the code that uses the response in the Callback, or call that code from the callback.