Always returning false as boolean value - java

After user selecting area, there is a function called checkCoverageGuest(). This function checks whether selected area by the user is under coverage for that restaurantor not. If the restaurant is under coverage, then checkCoverageGuest() will return true value. When there is no coverage for that restaurant, checkCoverageGuest() will return false.
If the value is true then, it proceed to the next level which is checkout. If the value is false, the screen will display toast error message that the selected restaurant is not under coverage.
Right now, every this coming out from this function checkCoverageGuest() as false.
Here is my code.
private boolean checkCoverageGuest() {
try {
String url;
if (appPrefs.getLanguage().equalsIgnoreCase("ar"))
url = LinksConstants.TEST_SERVER_URL
+ LinksConstants.SEARCH_COVERAGE_AREA;
else
url = LinksConstants.TEST_SERVER_URL
+ LinksConstants.SEARCH_COVERAGE_AREA;
Intent startingIntent = getIntent();
city_id = getIntent().getStringExtra("id");
RequestParams params = new RequestParams();
params.put("area", city_id);
NetworkRestClient.post(url, params, new JsonHttpResponseHandler() {
#Override
public void onStart() {
super.onStart();
progressActivity.showLoading();
}
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
progressActivity.showContent();
JSONObject[] restaurants_arr = null;
hasCoverageGuest = true;
try {
if (response != null) {
JSONArray restaurants = response.getJSONArray("restaurants");
// if restaurants deliver to that area
if (!restaurants.getString(0).equals("null")) {
restaurants_arr = new JSONObject[restaurants.length()];
int has_coverage = 1; // assume coverage is there..
for (int j = 0; j < Utils.cart_restaurants.size(); j++) {
RestaurantModel restaurant = Utils.cart_restaurants.get(j);
String restaurantCartID = restaurant.getId();
boolean found = false;
for (int i = 0; i < restaurants.length(); i++) {
restaurants_arr[i] = restaurants.getJSONObject(i);
String restaurantID = restaurants_arr[i].get("restaurant_id").toString();
if (restaurantCartID.equals(restaurantID)) {
found = true;
break;
}
} //end of inner for
if (found == false) {
Toast.makeText(CheckoutActivity.this, "There is no coverage for the Selected Area ", Toast.LENGTH_SHORT).show();
hasCoverageGuest = false;
break;
}
}
//end of outer for
} //end of if
else //if restaurants don't deliver to that area
{
hasCoverageGuest = false;
}
} // end of if response != null
} // end of try
catch (Exception ex) {
GSLogger.e(ex);
showError();
}
}
#Override
public void onFailure(int statusCode, Header[] headers, String errorResponse, Throwable throwable) {
super.onFailure(statusCode, headers, errorResponse, throwable);
showError();
if (AppConstants.DEBUG_MODE)
showToast(errorResponse);
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
super.onFailure(statusCode, headers, throwable, errorResponse);
showError();
}
});
} catch (Exception ex) {
GSLogger.e(ex);
showError();
}
return hasCoverageGuest;
}

You need to have a callback to specify success or failure. one way to do that is using interface.
public interface notifyGuestCoverage {
void hasCoverage(int status);
}
in onSuccess,
if (!restaurants.getString(0).equals("null")) {
notifyGuestCoverageObj.hasCoverage(true);
}
This interface will be implemented by class which requires value of has coverage. for ex,
class Example implements notifyGuestCoverage{
void hasCoverage(int status){
//your code
}
}

Your private boolean checkCoverageGuest() method returns before public void onSuccess() is executed, this is the reason for checkCoverageGuest() always returning false.
If you need to execute something after you get the hasCoverageGuest good value then excute it inside onSucess()

Related

Parsing OkHttp in android?

textView = findViewById(R.id.textVieww);
String url = "https://zenquotes.io/api/random";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
final String myResponse = response.body().string();
try {
JSONArray jsonarray = new JSONArray(myResponse);
for(int i=0; i<jsonarray.length(); i++) {
JSONObject obj = jsonarray.getJSONObject(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
Quote.this.runOnUiThread(() ->
textView.setText(myResponse));
}
}
});
}
This is the part im stuck on i think im on the right track but not sure where to go from here im trying to get the "q" information from the returned url and the "a" information but it just outputs everything any suggestions?
What was your problem
Even when you parsed JSON string, you were still using the myResponse string in your textView.setText() method.
Continuing your code snippet
your code snippet is quite short, but i do think i can quite understand what you mean.
So let's say that we have Activity, which is called MainActivity and in that activity we have two views, one TextView called that has an id of tv_author_and_quote and one Button which has a xml id btn_request_quote.
The button has an OnClickListener which calls method requestForQuote().
Our onCreate + the variables of Button and TextView looks like this:
TextView tvAuthorAndQuote;
Button btnRequestQuote;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvAuthorAndQuote = findViewById(R.id.tv_author_and_quote);
btnRequestQuote = findViewById(R.id.btn_request_quote);
btnRequestQuote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
requestForQuote();
}
});
}
And then we have a code itself for method requestForQuote():
public void requestForQuote() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
if (response.isSuccessful()) {
final String myResponse = Objects.requireNonNull(response.body()).string();
String myFormattedQuote = "";
try {
JSONArray jsonarray = new JSONArray(myResponse);
for(int i=0; i<jsonarray.length(); i++) {
JSONObject obj = jsonarray.getJSONObject(i);
String quote = obj.getString("q");
String author = obj.getString("a");
Log.d(TAG, "onResponse: quote:" + quote);
Log.d(TAG, "onResponse: author:" + author);
myFormattedQuote = author + ": " + quote;
}
} catch (JSONException e) {
e.printStackTrace();
}
final String myFinalQuote = myFormattedQuote;
MainActivity.this.runOnUiThread(() -> {
if (!myFinalQuote.equals("")) {
tvAuthorAndQuote.setText(myFinalQuote);
} else {
tvAuthorAndQuote.setText(myResponse);
}
});
}
}
});
}
The code above basically uses your existing solution, but instead of setting the text of textView with myResponse string, it parses the json array and gets a quote and an author from it. Then it just logs it (just for testing purposes), then it constructs the string which gets displayed to the if there is any, otherwise it prints the response. That it is.
Using Gson library
import it into your gradle dependecies
implementation 'com.google.code.gson:gson:2.8.7'
Write short "holder" class called Quote
public class Quote {
public Quote() {
}
String q;
String a;
String h;
public String getQ() {
return q;
}
public void setQ(String q) {
this.q = q;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getH() {
return h;
}
public void setH(String h) {
this.h = h;
}
#NonNull
#NotNull
#Override
public String toString() {
return a + ": " + q;
}
}
Then the requestForQuote() method could look something like this:
public void requestForQuoteWithGson() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
if (response.isSuccessful()) {
final String myResponse = Objects.requireNonNull(response.body()).string();
Type listType = new TypeToken<ArrayList<Quote>>(){}.getType();
List<Quote> yourClassList = new Gson().fromJson(myResponse, listType);
if (yourClassList != null && yourClassList.size() > 0) {
final Quote quote = yourClassList.get(0);
if (quote != null) {
myQuotes.add(quote);
MainActivity.this.runOnUiThread(() ->
tvAuthorAndQuote.setText(quote.toString())
);
}
}
}
}
});
}

problem with android : data from class don't send to activity

i wrote the code to an activity it work perfect but when i writhing them to a java class and send the result to the activity is not show anything to text view.
public class TheaudiodbWebData {
private String result = "";
public String getResult() {
return result;
}
public TheaudiodbWebData() {
getBiographyData();
}
private void getBiographyData() {
String url = "https://www.theaudiodb.com/api/v1/json/1/search.php?s=coldplay";
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new TextHttpResponseHandler() {
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
}
#Override
public void onSuccess(int statusCode, Header[] headers, String responseString) {
parseBiographyData(responseString);
}
});
}
private void parseBiographyData(String response) {
try {
Gson gson = new Gson();
TheaudiodbArtistBio bio = gson.fromJson(response, TheaudiodbArtistBio.class);
result = bio.getArtists().get(0).getStrArtist();
} catch (Exception e) {
}
}
}
and this is the Activity code :
public class BiographyActivity extends AppCompatActivity {
TextView test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_biography);
test=findViewById(R.id.test);
TheaudiodbWebData bio=new TheaudiodbWebData();
test.setText(bio.getResult());
}
}
If you are not passing data from one Activity to another Activity and you are getting the result than problem is clear. Part of code which you are executing in onCreate() method:
TheaudiodbWebData bio=new TheaudiodbWebData();
test.setText(bio.getResult());
is executed immediately but you are getting results over the Internet which means that data is not received immediately (connecting server -> getting result -> returning result = takes some time) that is why you have callback methods onFailure and onSuccess which are triggered after result is returned from the Internet depending was it successful or fail.
So solution is to create your own interface with method where you can pass the result than implement that interface and create your own callback methods.
Or more simpler solution move this part of code directly into your Activity and set the the result to the TextView in onSucces method for example:
private void getBiographyData() {
String url = "https://www.theaudiodb.com/api/v1/json/1/search.php?s=coldplay";
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new TextHttpResponseHandler() {
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
}
#Override
public void onSuccess(int statusCode, Header[] headers, String responseString) {
test.setText(responseString);
}
});
}
After that simply call this method inside onCreate() like:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_biography);
test=findViewById(R.id.test);
getBiographyData();
}

Mockito mock doAnswer returns same value when reused between tests

I have the following tests. When I run them separately they pass. If I run all of them only the first passes.
Business Logic gets a JSON response from the APIServiceTask code. It creates an event to post using EventBus. I am writing tests to verify that EventBus is creating the correct calls.
The JSON Reponses class at the end is just the answers I am trying to post. If I run all of the tests, it seems like the loginFailureChangePasswordJSON is the one posted to the business logic.
public class LoginBusinessLogic {
private static LoginBusinessLogic instance = null;
APIServiceTask apiServiceTask;
public static LoginBusinessLogic getInstance(APIServiceTask apiServiceTask) {
if (instance == null) {
instance = new LoginBusinessLogic();
instance.apiServiceTask = apiServiceTask;
}
return instance;
}
protected void doLogin() {
EventBus.getDefault().register(this);
apiServiceTask.execute();
}
#Subscribe
public void onEvent(ServiceResultEvent event) {
switch (event.event) {
case failed:
handleLoginError(event.result);
break;
case cancelled:
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_CANCELLE, event.result));
break;
case error:
if(event.originatorEvent != LoginEvent.TYPE_TOUCH_TOKEN_DELETE) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_ERROR, event.result));
}
break;
default:
break;
}
EventBus.getDefault().unregister(this);
}
private void handleLoginError(String error) {
ErrorModel signInError = new Gson().fromJson(error, ErrorModel.class);
int statusCode = signInError.getMTBStatusCode();
String errMsg;
if (statusCode == 40022) {
errMsg = signInError.getUserMessage();
} else {
errMsg = signInError.getUserMessage().replace("*", "").replace("\"", "");
}
if (statusCode == 40001) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, false));
} else if (statusCode == 40108) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, true, false));
}
else if (statusCode == 40107) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, false));
} else if (statusCode == 40104) {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, true));
} else {
EventBus.getDefault().postSticky(new LoginEvent(LoginEvent.TYPE_FAILED, statusCode, errMsg, false, false));
}
}
}
public class APIServiceTask {
public APIServiceTask(){
}
#SuppressWarnings("ConstantConditions")
public void execute() {
}
}
public class BusinessLogicTests {
#Mock
APIServiceTask service;
private LoginEvent loginEvent;
private LoginBusinessLogic loginBusinessLogic;
#Before
public void setUp(){
MockitoAnnotations.initMocks(this);
loginBusinessLogic = LoginBusinessLogic.getInstance(service);
EventBus.getDefault().register(this);
}
#After
public void tearDown(){
EventBus.getDefault().unregister(this);
}
#Subscribe
public void onEvent(LoginEvent event){
loginEvent = event;
}
#Test
public void badUsernamePasscode(){
doAnswer(JSONResponses.loginInvalidUsernamePasscodeJSON())
.when(service).execute();
loginBusinessLogic.doLogin();
Assert.assertEquals(40108, loginEvent.mtbStstusCode);
}
#Test
public void accountBlocked(){
doAnswer(JSONResponses.loginAccountBlockedJSON())
.when(service).execute();
loginBusinessLogic.doLogin();
Assert.assertEquals(40104, loginEvent.mtbStstusCode);
}
#Test
public void temporaryPasscode(){
doAnswer(JSONResponses.loginTemporaryPasscodeJSON())
.when(service).execute();
loginBusinessLogic.doLogin();
Assert.assertEquals(40109, loginEvent.mtbStstusCode);
}
#Test
public void changedPasscode(){
doAnswer(JSONResponses.loginFailureChangePasscodeJSON())
.when(service).execute();
loginBusinessLogic.doLogin();
Assert.assertEquals(40107, loginEvent.mtbStstusCode);
}
}
public class JSONResponses {
public static Answer loginFailureChangePasscodeJSON(){
Answer answer = new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String result = "{\"MTBStatusCode\":40107, \"UserMessage\":\"Your passcode has changed since last login.\"}";
EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
return null;
}
};
return answer;
}
public static Answer loginAccountBlockedJSON(){
Answer answer = new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String result = "{\"Version\":1,\"MTBStatusCode\":40104,\"HttpStatus\":401,\"UserMessage\":\"\\\"Your account is locked due to too many failed login attempts. <br><br>Reset Passcode >\\\"\",\"DeveloperMessage\":\"\\\"Account locked via multi-factor authentication.\\\"\"}";
EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
return null;
}
};
return answer;
}
public static Answer loginInvalidUsernamePasscodeJSON(){
Answer answer = new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String result = "{\"Version\":1,\"MTBStatusCode\":40108,\"HttpStatus\":401,\"UserMessage\":\"\\\"User ID or Passcode doesn’t match. Try again.\\\"\",\"DeveloperMessage\":\"\\\"Voyager Error -1073739414 : User ID or Passcode doesn’t match. Try again.\\\"\"}";
EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
return null;
}
};
return answer;
}
public static Answer loginTemporaryPasscodeJSON(){
Answer answer = new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
String result = "{\"Version\":1,\"MTBStatusCode\":40107,\"HttpStatus\":401,\"UserMessage\":\"\\\"You have logged in with a temporary passcode. Log in to M&T Online Banking to create a new passcode.\\\"\",\"DeveloperMessage\":\"\\\"Password should be changed.\\\"\"}";
EventBus.getDefault().post(new ServiceResultEvent(ServiceResultEvent.EVENT_TYPE.failed, result, 0));
return null;
}
};
return answer;
}
}
For anyone interested, it seems the singleton still exists when the other tests run. 2 ways I found to fix it are nulling out the singleton in a separate method or moving the following statement outside of the if in LoginBusinessLogic.
instance.apiServiceTask = apiServiceTask;

Arraylist populated from jsonarray request

I have a method which returns an arraylist, and it is populated from jsonarray
jsonrequest works fine, but when i call the method the arraylist returns a size of 0 even it is populated.
Below is the code, what am i doing wrong
private ArrayList<String> queryRes(String url, String searchString) {
final ArrayList<String> mylist = new ArrayList<>();
AsyncHttpClient client = new AsyncHttpClient();
client.get(url + searchString,
new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONArray jsonArray) {
for(int i =0; i < jsonArray.length(); i++) {
mylist.add(i, jsonArray.optJSONObject(i).optString("id"));
//Check if it is added to the list
Log.d("Try: ", mylist.get(i));
}
}
#Override
public void onFailure(int statusCode, Throwable throwable, JSONObject error) {
}
});
return mylist;
}
onSuccess() called when you get the response means AsynHttp call is done in another thread so your return statement call before onSucess thats why size is 0.
you can verify it on debugger
my suggestion is call a method from onSuccess() so you will get Arraylist
If you are doing everything in a single class
public void populateList(String url, String searchString)
{
final ArrayList<String> mylist = new ArrayList<>();
AsyncHttpClient client = new AsyncHttpClient();
client.get(url + searchString,
new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONArray jsonArray) {
for(int i =0; i < jsonArray.length(); i++) {
mylist.add(i, jsonArray.optJSONObject(i).optString("id"));
//Check if it is added to the list
Log.d("Try: ", mylist.get(i));
}
onListPopulated(myList);
}
#Override
public void onFailure(int statusCode, Throwable throwable, JSONObject error) {
}
});
}
A method to do something with the list
public void onListPopulated(ArrayList<String> list)
{
//do something with the list
}

Check network connection in libGDX

I would like to check network connection with use of libGDX and tried to use code below.
HttpRequestBuilder requestBuilder = new HttpRequestBuilder();
Net.HttpRequest httpRequest = requestBuilder.newRequest().method(Net.HttpMethods.GET).url("https://api.vk.com/").build();
Net.HttpResponseListener httpResponseListener = new httpResponseListener() {
public void handleHttpResponse (Net.HttpResponse httpResponse) {
HttpStatus status = httpResponse.getStatus();
if (status.getStatusCode() >= 200 && status.getStatusCode() < 300) {
// it was successful
} else {
// do something else
}
}
}
Gdx.net.sendHttpRequest(httpRequest, httpResponseListener);
It has several errors, like Gdx.net doesn't have sendHttpRequest() function now. How should I correct this code?
Gdx.net has got sendHttpRequest() method - it seems that you are using not proper HttpRequest instance (why this Net... is starting with uppercase?)
A proper minimal example of how to use Gdx.net is beneath - I have also added a comments where it was necessary
public class HttpManager implements HttpResponseListener
{
public HttpState state;
private String result;
private byte[] byteResult;
HttpRequest request;
public HttpManager()
{
request = new HttpRequest();
request.setMethod(Net.HttpMethods.GET); //or POST
request.setContent(""); //you can put here some PUT/GET content
request.setUrl(url);
Gdx.net.sendHttpRequest(request, this);
}
#Override
public void handleHttpResponse(HttpResponse httpResponse)
{
if( httpResponse.getStatus().getStatusCode() != 200 )
{
//ERROR
float errorCode = httpResponse.getStatus().getStatusCode();
}
else
{
byte[] byteResult = httpResponse.getResult(); //you can also get result as String by using httpResponse.getResultAsString();
}
}
#Override
public void failed(Throwable t)
{
// TODO Auto-generated method stub
}
#Override
public void cancelled()
{
// TODO Auto-generated method stub
}
}

Categories

Resources