I am implementing Link preview feature like WhatsApp, i.e
Provided any link, fetch all its Html
Crawl through Html, read all information
Display text and images
Jsoup Library
I am successfully able to perform this using Jsoup library
Document doc = Jsoup.connect("http://www.techjuice.pk").userAgent("Mozilla").get();
It returns the html code of the page as a response.
Retrofit Library
Now I wanted to perform the same task using Retrofit
Retrofit retrofit = new Retrofit.Builder()
.build();
API api = retrofit.create(API.class);
Call<ResponseBody> call = api.crawlLink("http://techjuice.pk");
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
API.class
public interface API {
#GET
Call<ResponseBody> crawlLink(#Url String url);
}
Exception
java.lang.IllegalStateException: Base URL required.
Unfortunatelly you can't change URL in Retrofit at Runtime in that way.
Try this tutorial: https://futurestud.io/tutorials/retrofit-2-how-to-change-api-base-url-at-runtime-2
or this answer: Set dynamic base url using Retrofit 2.0 and Dagger 2
Related
I'm using archictecture Android Architecture Components. I want to load an image from my api.
this is the request on postman :
!https://ibb.co/WPJjpFm
I' am actually using retrofit but i don't known how to transform Responsebody to file.
#GET("image/{filename}")
Call<ResponseBody> getImage(#Path("filename") String filename);
public MutableLiveData<File> retriveImageTest(String filename) {
MutableLiveData data = new MutableLiveData<>();
executor.execute(() -> {
imageWebService.getImage(filename).enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
// How to deal with responsebody ?
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
});
return data;
}
What' s the best way to do it without breaking Android Architecture Components ?
Thanks in advance.
It is better to use Image loading libraries like Glide ,Picasso or Fresco to load images:
Using Glide, add this to your app gradle file
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
Then ,
Glide.with(this).load(imageUrl).into(imageView);
For more info : Glide docs
I am implementation for Retrofit on api call using images-upload base64Encode string. it is sending data perfect but Retrofit return response Internal Server Error 500 and i am sending request type is Body custom class. Plz help me what i do.
#Headers("Accept:application/json")
#POST(RestClient.postRegister)
Call<RegisterResp> getRegisterResponse(#Body RequestRegisterVo requestRegisterVo);
Call<RegisterResp> call = MyApplication.getRestClient().getApplicationServices().getRegisterResponse(requestRegisterVo);
call.enqueue(new Callback<RegisterResp>() {
#Override
public void onResponse(Call<RegisterResp> call, Response<RegisterResp> response) {
if (Other.isValidResp(response)) {
// success Log.i(TAG,"Register successfully");
} else {
hideDialog();
}
}
#Override
public void onFailure(Call<RegisterResp> call, Throwable t) {
hideDialog();
showToast(t.getMessage());
}
});
The same issue I had to face it, I got a solution in my case-
there is parameter issue, I was sending parameters in String and at the backend, they required Integer parameters.
You also checkout may be there is the issue with parameters or second reason is the URL issue so check it URL also.
I want to POST JSON data having nested objects in it with the help of Asynctask in android studio, but I don't have good knowledge of API implementation in android studio. I am all new in android studio. I have successfully POST this data from POSTMAN, but I am not able to implement the code for it, also I don't have any tutorials for Asynctask. Please help me to implement code for this.
This is my Json data having nested Objects in it:
You don't need Async, Volley does it in the background for you. Put your JSONObject in the method instead of 'new JSONObject'. And YourURL - i.e '/api/route/'.
RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest request_json = new JsonObjectRequest(YourURL, new JSONObject(params)),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
//Do what you want on response
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//If there's an error...
}
});
//Add process to queue to get JSON in background thread
queue.add(request_json);
Nowadays a better/simpler approach would be to use a libary like Retrofit to do all the magic for you.
You can simply send a Java instance model to an API endpoint. Retrofit takes care of converting it to json when using the GsonConverterFactory class and sends the json to the endpoint you provided with the given HTTP method.
Best and Simple Library for Implementation for API services by third party library made by Square, Retrofit a Easy HTTP Client.
Why Retrofit? because, Retrofit automatically creates the background thread ,Parse the Json using GSON converter and get a call success and Failure call back directly on main thread. Without writing too much boiler plate code of AsyncTask and Parsing JSON and getting the result on main thread.
Make Retrofit Client.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
RetrofitInterface service = retrofit.create(RetrofitInterface.class);
Make Method in RetrofitInterface.
#POST("users/new")
Call<User> yourMethod(#Body UserType user);
Now Call your method and It will make your success and Failure Callback method
Call<List<Repo>> repos = service.yourMethod("octocat");
And then Call enque method to automatic create background thread.
repos.enqueue(new Callback<List<Repo>>() {
#Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
}
#Override
public void onFailure(Call<MainResponse> call, Throwable t) {
}
});
I'm new to Android developing and I don't know how to do this, I've searched on the internet, but everything I've tried so far doesn't work. What I'm trying to do, is to send string to the server and the key must be "interval=". This is what I have so far, but it doesn't work. I'm getting string time2 from spinner, but for now it doesn't matter, because I know that the spinner part works and POST doesn't.
PostInterface service = retrofit.create(PostInterface.class);
service.postTime(time2);
and interface
#FormUrlEncoded
#POST
Call<Response> postTime(#Field("interval=") String time);
What I'm supposed to do net and how can I test it with http://requestb.in/ (never used it before, I just saw it can be used for POST testing)?
Why do you use retrofit in the first place ?
It's a good library, but if you're new to Android, i suggest to start with HttpClient.
In your sample, the execute method was not called.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://requestb.in/")
.addConverterFactory(GsonConverterFactory.create())
.build();
PostInterface service = retrofit.create(PostInterface.class);
Call<Response> call = service.postTime(time2);
call.execute()
In your interface (replace xxx by the token given by requestbin)
#FormUrlEncoded
#POST("xxxxxxx")
Call<Response> postTime(#Field("interval=") String time);
ps: Be aware that you should not launch any http calls on the main thread.
if you are posting a form field, you should remove the "=" from "interval="
fields are key and values, no need for the "="
if you want a test client for posts and get you can try postman
please clarify your question more if this is not what you expected as an answer
as #Mickael Monsang Answer
dont' use call.execute directly better use
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<Response> call, Response<Response> response) {}}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
}
});
I've setup retrofit 2.1 and it is not making calls to my api at all. I just setup a lamp stack and made my ip publicly accessible. I'm trying to send information via a POST to my php script which would add data to my db. For some reason, retrofit will not make the call to my api... I'm not sure what I'm doing wrong.
#POST("/sendInformation.php")
Call<JSONObject> sendUserInfo(#Body JSONObject userViewModel);
OkHttpClient.Builder client = new OkHttpClient.Builder();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> Log.d(TAG, message));
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
client.addInterceptor(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client.build())
.addConverterFactory(JacksonConverterFactory.create())
.build();
UserInformationService userService = retrofit.create(UserInformationService.class);
Call<JSONObject> call = userService.sendUserInfo(jsonObject);
call.enqueue(new Callback<JSONObject>() {
#Override
public void onResponse(Call<JSONObject> call, Response<JSONObject> response) {
Toast.makeText(HomeActivity.this, response.body().toString(), Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<JSONObject> call, Throwable t) {
}
});
I tried to add logging but it won't make the call so I can't even see the logging. Anyone have any ideas?
EDIT: The BASE_URL I'm using is my public IP. I just forwarded my ports so it's accessible. I tried doing a POST on hurl.it and it works fine. It's only retrofit not working. I've also tried this with an asyncTask and httpURLConnection and it also works. I must be missing something really minor...
Call<JSONObject> call = userService.sendUserInfo(jsonObject);
This line is not enough. The Call<T> object represents an 'intent' of a call rather than the operation itself, and you need to execute it by calling one of two methods on the object: execute and enqueue.
Execute works in a blocking manner and will return your JSONObject through the response.getBody() method:
Response<JSONObject> response = call.execute();
Enqueue works asynchronously and will provide your JSONObject through the callback object - if call is successful, onResponse method will be called with your response as a call parameter.
call.enqueue(new Callback<JSONObject>() {
#Override
public void onResponse(Call<JSONObject> call, Response<JSONObject> response) {
}
#Override
public void onFailure(Call<JSONObject> call, Throwable t) {
}
});