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

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

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

how to Post data in an array in android using retrofit 2

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

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

Java Android AsyncHttpClient convert byte[]responseBody to InputStream

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.

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.

Categories

Resources