I am integrating ROKO Mobi into my Android app.
I am trying to call RokoAccount.logout() after I call RokoAccount.setUser() but I see the following error message in my client-side console log when I try to do this.
E/btLogout: failure string: {"apiStatusCode":"AccessDenied","apiStatusMessage":"User not authorized for this action."}
Why am I receiving this?
It's possible you're seeing this error because RokoAccount.setUser() executes asynchronously.
The code snippet below calls RokoAccount.logout() in an asynchronous fashion, give it a shot!
RokoAccount.setUser(this, "UserA#referrals.com", null, null, new ResponseCallback() {
#Override
public void success(Response response) {
User userA = RokoAccount.getLoginUser(InfoActivity.this);
final String userAreferralCode = userA.referralCode;
Log.i("userA.referralCode", "refCode = " + userAreferralCode);
// call logout() in the asynchronous success callback of setUser()
RokoAccount.logout(InfoActivity.this, new ResponseCallback() {
#Override
public void success(Response response) {
Log.i("btLogout", "success response: " + response.body);
}
#Override
public void failure(Response response) {
Log.e("btLogout", "failure string: " + response.body);
}
});
}
#Override
public void failure(Response response) {
}
});
Related
I'm new to Android development, and am trying to use a good pattern for accessing my data from a web service using ViewModel, Retrofit, LiveData. Looking for feedback on this pattern.
I went through a few iterations and online guides, and came up with this
From the Activity:
LiveData<TicklerResponse> ticklerLiveData =
ticklerViewModel.search(ticklerSearchObject);
ticklerLiveData.observe(this, new Observer<TicklerResponse>() {
#Override
public void onChanged(#Nullable TicklerResponse ticklerResponse) {
Log.d(TAG, "onChanged: ticklerResponse size = " + ticklerResponse.getContent().size());
}
});
The ViewModel
public LiveData<TicklerResponse> search(TicklerSearchObject ticklerSearchObject) {
TicklerRepository ticklerRepository = TicklerRepository.getInstance();
String header = OscarOAuthContainer.getInstance()
.generateAuthorizationHeader(Verb.POST,"/tickler/search?startIndex=0&limit=1000");
MutableLiveData<TicklerResponse> liveData = new MutableLiveData<TicklerResponse>();
ticklerRepository.search(header,liveData, ticklerSearchObject);
return liveData;
}
The Repository
public void search(final String authHeader, final MutableLiveData<TicklerResponse> ticklerLiveData, TicklerSearchObject ticklerSearchObj) {
Log.d(TAG, "search: called");
Call<TicklerResponse> call = api.search(authHeader,0,1000,ticklerSearchObj);
call.enqueue(new Callback<TicklerResponse>() {
#Override
public void onResponse(Call<TicklerResponse> call, Response<TicklerResponse> response) {
if(response.isSuccessful()){
Log.d(TAG, "onResponse: successful response for getProvider");
TicklerResponse result = response.body();
ticklerLiveData.setValue(result);
} else {
Log.d(TAG, "onResponse: NOT SUCCESSFUL");
}
}
#Override
public void onFailure(Call<TicklerResponse> call, Throwable t) {
t.printStackTrace();
}
});
}
It seems to work, but I'm concerned if I'm using the LiveData structure correctly in how it's being instantiated/passed around.
I'm very new to android development. Trying to connect some site and get data from it. I have this function called only from onCreate in the main activity. Every time I turn virtual Android phone left or right I see new "run()" strings in EditText and requests in Wireshark. How to stop that properly?
Tried call.cancel() and mClient.dispatcher().cancelAll() inside OnResponse
protected void Load(String url) {
Request request = new Request.Builder()
.url(url)
.build();
mClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
if (response.isSuccessful()) {
mHandler.post(new Runnable() {
#Override
public void run() {
mEdit.setText(mEdit.getText() + "run()\n");
}
});
}
}
});
}
retrofit supports enqueue canceling, and it works great.
And i think if you will try to run this code - your client enqueues would be stoped
protected void Load(String url) {
Request request = new Request.Builder()
.url(url)
.build();
Call<Response> mCall = mClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
if (call.isCanceled()) {
Log.e(TAG, "request was cancelled");
}
else {
Log.e(TAG, "other larger issue, i.e. no network connection?");
}
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
if (response.isSuccessful()) {
mHandler.post(new Runnable() {
#Override
public void run() {
mEdit.setText(mEdit.getText() + "run()\n");
}
});
}
}
});
mCall.cancel();
}
I don't know you project structure and what kind of patterns you using(MVP, MVVM or else), but in simple, this code can be improved by returning Call
protected void Load(String url): Call<Response>
And then you can hadle you request status, and if it longer than 5 seconds for example, you call call.cancel() and request is stopping.
onCreate is called every time configuration changes (for example you rotate your phone/emulator). For more info: https://developer.android.com/guide/components/activities/activity-lifecycle
You can save your response to prevent new request on every onCreate. Something like this:
MainActivity {
private Response savedResponse;
onCreate() {
if (savedResponse == null) {
Load(url)
}
}
}
and in your onResponse save the response:
#Override
public void onResponse(Call call, final Response response) throws IOException {
if (response.isSuccessful()) {
savedResponse = response; // <----
mHandler.post(new Runnable() {
#Override
public void run() {
mEdit.setText(mEdit.getText() + "run()\n");
}
});
}
}
However, correct way would be to separete network calls/requests from activity lifecycle and load data somewhere else (Service, WorkManager, ...)
I've been building an app which has Log In functionality. I've tested it but every time i tried to Log In, the progress bar disappeared to quickly (like a quarter second or something), and the response i get from the server is like about 2 seconds after the progress bar disappeared. Here are some of my codes.
My LoginTask inner class :
private class LoginTask extends AsyncTask<Account, Void, Account>{
private String getUsername = username.getText().toString();
private String getPassword = password.getText().toString();
#Override
protected void onPreExecute() {
super.onPreExecute();
//showDialog();
progressBar.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Account account) {
super.onPostExecute(account);
//dismissDialog();
progressBar.setVisibility(View.GONE);
}
#Override
protected Account doInBackground(Account... accounts) {
getLogin(getUsername, getPassword);
return null;
}
}
Login Retrofit call to server
private void getLogin(String email, String password) {
Call<LoginAuth> call = userService.getLogin(email, password);
call.enqueue(new Callback<LoginAuth>() {
#Override
public void onResponse(Call<LoginAuth> call, Response<LoginAuth> response) {
try {
if (response.body().getToken_type().equals("xxx")) {
Log.i(TAG, "getLogin, Authorized access");
Log.i(TAG, "getLogin, access_token: " + response.body().getAccess_token().toString());
Log.i(TAG, "getLogin, expires_at" + response.body().getExpires_at().toString());
} else {
Log.e(TAG, "getLogin, Unauthorized access" + response.body().getToken_type().toString());
}
} catch (Exception e) {
Log.e(TAG, "getLogin exception " + e.getMessage());
}
}
#Override
public void onFailure(Call<LoginAuth> call, Throwable t) {
Log.e(TAG, "getLogin, onFailure : " + t.getMessage());
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(LoginActivity.this, "Unable to Log In :(", Toast.LENGTH_SHORT).show();
}
});
}
});
}
I want it to work like when the response is fetched, that's the time the progress bar disappeared (not instantly). Did i do something wrong with the code?
As you are using retrofit, there is no necessity to call your api in separate asynctask as retrofit manages it asynchronously. what you should do is show your progressbar before you call api and dismiss it in onResponse and onFailure both. so your code would change to something like below.
private void getLogin(String email, String password) {
progressBar.setVisibility(View.VISIBLE);
Call<LoginAuth> call = userService.getLogin(email, password);
call.enqueue(new Callback<LoginAuth>() {
#Override
public void onResponse(Call<LoginAuth> call, Response<LoginAuth> response) {
progressBar.setVisibility(View.Gone);
//rest of your code
}
#Override
public void onFailure(Call<LoginAuth> call, Throwable t) {
Log.e(TAG, "getLogin, onFailure : " + t.getMessage());
progressBar.setVisibility(View.Gone);
//rest of your code
}
});
}
Im trying to send JSON messages through HTTP with retrofit2 in android, to a django server with the rest api running.
using a retrofit interface and the calls:
#POST("getDates/")
Call<Event> newEvent(#Body Event event);
#PUT("getDates/{id}/")
Call<Event> updateEvent(#Path("id") int id, #Body Event event);
as well as
public void postNewEvent(Event event) {
Call<Event> call = service.newEvent(event);
call.enqueue(new Callback<Event>() {
#Override
public void onResponse(Call<Event> call, Response<Event> response) {
Log.i("REST", "POST was sucessful: " + response.isSuccessful());
Log.i("REST", "response body: " + response.body().toString());
Log.i("REST", "response message: " + response.message());
Log.i("REST", "response code: " + response.code());
Log.i("REST", "response code: " + response.errorBody());
}
#Override
public void onFailure(Call<Event> call, Throwable t) {
Log.e("REST", t.getMessage());
Log.e("REST", call.toString());
}
});
}
public boolean updateEvent(Event event) {
Call<Event> call = service.updateEvent(event.getId(), event);
call.enqueue(new Callback<Event>() {
#Override
public void onResponse(Call<Event> call, Response<Event> response) {
success = response.isSuccessful();
}
#Override
public void onFailure(Call<Event> call, Throwable t) {
Log.e("REST", t.getMessage());
}
});
}
However, every message i send to the server through my interface only gets a reply with: OK and code:200.
I have tried sending the calls manually through the api and it works just fine.
This code used to also work for me, but now it just stopped.
I've added an Nginx Server and Gunicorn instead of UWSGI, but i can't imagine them blocking the app.
Does anyone have a clue what could be going wrong? I just can't figure it out!
Before I always used retrofit to load data. It's very easy to handle or get status code of the response.
But now I want to use Retrofit with RxJava but I don't know how to handle or get the https status code of the response in onNext method.
progressDialog.show();
Observable<ResponseData> observable = apiService.getData();
compositeDisposable.add(observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<ResponseData>() {
#Override
public void onNext(ResponseData responseData) {
Log.e("pppp", "onNext: " + responseData.toString());
}
#Override
public void onError(Throwable e) {
progressDialog.dismiss();
Log.e("pppp", "onError: " + e.getMessage());
}
#Override
public void onComplete() {
progressDialog.dismiss();
Log.e("pppp", "onComplete");
}
})
);
Everyone, please help me to solve this problem.
Thanks!
You should wrap your ResponseData inside Response as
Observable<Response<ResponseData>> observable = apiService.getData();
Then inside onNext
#Override
public void onNext(Resposne<ResponseData> response) {
int statusCode = response.code();
}
and for error
#Override
public void onError(Throwable e) {
((HttpException) e).code();
}
responseData.code gives you the status code
int statusCode = responseData.code();
for getting status
Observable<ResponseData> observable = apiService.getData();
compositeDisposable.add(observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<ResponseData>() {
#Override
public void onNext(ResponseData responseData) {
int statusCode = responseData.code();
// here you get your status code
Log.e("statusCode ", "onNext: " + statusCode );
}
#Override
public void onError(Throwable e) {
progressDialog.dismiss();
Log.e("pppp", "onError: " + e.getMessage());
}
#Override
public void onComplete() {
progressDialog.dismiss();
Log.e("pppp", "onComplete");
}
})
);