Java Android AsyncHttpClient convert byte[]responseBody to InputStream - java

I want to create a methos which return a InputStream I did this :
public static InputStream sendGetDataRequest(Context context,
String version, String power, String lon, String lat, String radius) throws MalformedURLException, ConnectTimeoutException, IOException
{
AsyncHttpClient client = new AsyncHttpClient();
String url = Util.getServerUrl(context) + "/GetData";
// ContentValues values=new ContentValues();
RequestParams values = new RequestParams();
values.put("token", String.valueOf(E_Gps.TOKEN));
values.put("xml", login_xml);
StringEntity entity = null;
try {
entity = new StringEntity(values.toString());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
entity.setContentType(new BasicHeader("Content-Type","application/xml"));
final InputStream[] is = new InputStream[1];
final InputStream inputStream;
client.post(context,url,values , new AsyncHttpResponseHandler(Looper.getMainLooper()) {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Log.e("success_noti", new String(responseBody) + "");
is[0] = new ByteArrayInputStream(responseBody);
Log.e("Status " , statusCode + " ");
Log.e("is" , convertStreamToString(is[0]));
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.e("success_noti", new String(responseBody) + "");
Log.e("Status " , statusCode + " ");
}
});
return is[0];
}
And I have probleme when I return is[0] is a null but when I log in onSuccess :
Log.e("is" , convertStreamToString(is[0]));
is not null why I have null object is[0] ?

Because client.post is an asynchronous call while return is[0] is a synchronous. This means that is[0] is null as long as the async call is not done yet. One way to solve is by making sendGetDataRequest return void and instead accepts a callback e.g.
public static void sendGetDataRequest(final YourCallback callback, ...)
Create a new Interface named YourCallback
public interface YourCallback{
void onSuccess(String string);
void failure();
}
And use that Callback inside the async method
client.post(context,url,values , new AsyncHttpResponseHandler(Looper.getMainLooper()) {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
callback.onSuccess(convertStreamToString(is[0]));
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
callback.onFailure();
}
}
Finally you call your static method like this
sendGetDataRequest(new YourCallback(){/* Override the methods */}, ...);
By the way you could also use AsyncTask from the android package which does everything above. It's personal preference.

Related

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();
}

Always returning false as boolean value

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()

Custom class extending AsyncHttpResponseHandler and return modified bytes

I have searched with google for the past 3 hours to no avail, I am not sure if this is even possible.
I am using AsyncHttpResponseHandler in 10-12 different activities, and with all of them I am doing the same initial transforming of the "byte[] bytes" in the initial code, which is around 50lines of code per activity.
How would I do said transformation of bytes, and then return the final value on the activity where the custom class gets called?
How would I reference the message variable?
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AsyncHttpClient client = new AsyncHttpClient();
client.post(URL, params, new VenueAsyncHttpResponseHandler() {
#Override
public void onSuccess(int i, Header[] headers, byte[] bytes) {
//How do I reference the transformed message here?
switch (message) {
case "success":
//Do something
break;
}
}
});
}
}
when using the custom class
public class VenueAsyncHttpResponseHandler extends AsyncHttpResponseHandler {
#Override
public void onSuccess(int i, Header[] headers, byte[] bytes) {
String byteToString = null;
JSONObject response = null;
String message = "";
try {
byteToString = new String(bytes, "UTF-8");
response = new JSONObject(byteToString);
message = response.getString("response"); //return this to the activity
} catch (UnsupportedEncodingException | JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
}
}
Add a method to your activity class which does what you want with the message. Then call this method from onSuccess().
Also, do not create an anonymous inner class. Instead instantiate your custom class directly:
VenueAsyncHttpResponseHandler handler = new VenueAsyncHttpResponseHandler();
client.post(URL, params, handler);

JsonHttpResponseHandler - method does not override method from its superclass

I have been struggling with this code for some time now. Why am I getting the follow error?
method does not override method from its superclass
Here is the code:
public void CanSendPassword() {
asyncHttpClientPassword = new AsyncHttpClient();
requestParamsPassword = new RequestParams();
requestParamsPassword.put("email", mEmail);
asyncHttpClientPassword.post(BASE_URL, requestParamsPassword, new JsonHttpResponseHandler()
{
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
jsonResponse = response.toString();
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
super.onFailure(statusCode, headers, throwable, errorResponse);
jsonResponse = "failed";
}
}
);
}
#override both are showing the same error and onSuccess and onFailure are greyed out too?
Here is my code
TwitterRestClient
import android.content.Context;
import com.loopj.android.http.*;
import cz.msebera.android.httpclient.entity.StringEntity;
public class TwitterRestClient {
private static final String BASE_URL = "https://www.example.com/api/";
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
}
public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.post(getAbsoluteUrl(url), params, responseHandler);
}
public static void post(Context ctx, String url, StringEntity entity, java.lang.String contentType, AsyncHttpResponseHandler responseHandler ){
client.post(ctx,getAbsoluteUrl(url),entity,contentType,responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return BASE_URL + relativeUrl;
}
}
This the method in my LoginAcitivity
public void testPost(StringEntity entity) throws JSONException {
TwitterRestClient.post(getApplicationContext(),"api-auth/", entity,"application/json", new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, cz.msebera.android.httpclient.Header[] headers, org.json.JSONArray response) {
// If the response is JSONObject instead of expected JSONArray
GlobalFunctions.ShowToast(getApplicationContext(),"test");
}
#Override
public void onFailure(int statusCode, cz.msebera.android.httpclient.Header[] headers, java.lang.Throwable throwable, org.json.JSONArray errorResponse){
GlobalFunctions.ShowToast(getApplicationContext(),"test1123");
}
#Override
public void onFailure(int statusCode, cz.msebera.android.httpclient.Header[] headers, java.lang.Throwable throwable, org.json.JSONObject errorResponse){
GlobalFunctions.ShowToast(getApplicationContext(),errorResponse.toString());
}
#Override
public void onFailure(int statusCode, cz.msebera.android.httpclient.Header[] headers, java.lang.String responseString, java.lang.Throwable throwable){
GlobalFunctions.ShowToast(getApplicationContext(),responseString);
}
});
}
This is what i call when user clicks the button
public void signIn(View v){
try {
String url = "/api-auth";
JSONObject jsonParams = new JSONObject();
jsonParams.put("username", "binsoi#gmail.com");
jsonParams.put("password", "cornedbeef");
StringEntity entity = new StringEntity(jsonParams.toString());
client.post(context, url, entity, "application/json",
responseHandler);
testPost(entity);
} catch (Exception err)
{
GlobalFunctions.ShowToast(this, err.toString());
}
}
Hope this will help you, tell me if it this doesn't work because i edited this before posting.
Here is a solution that I have working but it does not solve my exact issue. I post this as I can not understand why this code works but my code does not.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
EditText etSearchTerms;
Button btnSearch;
TextView tvSearchResults;
MyLoopjTask myLoopjTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etSearchTerms = (EditText) findViewById(R.id.etSearchTerms);
btnSearch = (Button) findViewById(R.id.btnSearch);
tvSearchResults = (TextView) findViewById(R.id.tvSearchResults);
btnSearch.setOnClickListener(this);
myLoopjTask = new MyLoopjTask();
}
#Override
public void onClick(View v) {
String searchTerm = etSearchTerms.getText().toString();
etSearchTerms.setText("");
// make loopj http call
myLoopjTask.executeLoopjCall(searchTerm);
}
}
And here is the other class:
public class MyLoopjTask {
AsyncHttpClient asyncHttpClient;
RequestParams requestParams;
String BASE_URL = "https://team.mycompany.com/teambeta/LoginApp/Recovery/";
String jsonResponse;
public MyLoopjTask() {
asyncHttpClient = new AsyncHttpClient();
requestParams = new RequestParams();
}
public void executeLoopjCall(final String queryTerm) {
requestParams.put("email", queryTerm);
asyncHttpClient.post(BASE_URL, requestParams, new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
jsonResponse = response.toString();
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
super.onFailure(statusCode, headers, throwable, errorResponse);
jsonResponse = "failed";
}
});
}
}
So why does this code work but not in my oringinal question?
Finally solved my issue. It was not the code as I was doing everything correctly. I just had the old jar file still in the app/libs folder.
And here is the error I was seeing. Everything was working but Override and the super.onSuccess were red underlined.
Remove the android-async-1.4.3.jar file and the red lines disappeared.

How to request in roads api using snap to roads?

i would like to use the roads api to get the distance of my currentlocation and add the list of Latlng in onLocationChanged and to snap a set of coordinates (approx 100~200 points) to roads and that will return a json to get the accurate distance of driving.
-- i got a problem with path parameters the latitude and longitude is not populating in which join by this "|" but i got an error like.
---This is my url
protected String getSnapUrl(List<LatLng> pat_value) {
String str_path = null;
for (int x = 0; x < pat_value.size(); x++) {
str_path = "path=" + pat_value.get(x).latitude + "," + pat_value.get(x).longitude + "|";
Log.e("path", "" + pat_value.get(x).latitude + "-" + pat_value.get(x).longitude);
}
String str_interpolate = "interpolate=true";
String key = "key=google key";
String parameters = str_path + "&" + str_interpolate + "&" + key;
String output = "snapToRoads";
String url = output + "?" + parameters;
return url;
}
protected void snapToRoad() {
SnapToRoadAsyncHttpClient.get(getSnapUrl(path), null, new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
Log.e("snapToRoad", "" + response);
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
super.onFailure(statusCode, headers, throwable, errorResponse);
Log.e("snapToRoadFail", "" + errorResponse + throwable);
}
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
super.onFailure(statusCode, headers, responseString, throwable);
Log.e("snapToRoadFail", "" + responseString + throwable);
}
});
}
--Error snaptoroads error:400 message:path.
Status code 400 is due to a invalid request.Roads API takes in at most 100 points , try decreasing your points.

Categories

Resources