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) {
}
}
});
Related
I have an application in Android, it sends several data in short time. Aprox. 2500 request.
This process is very time-consuming.
What advice can you give me to improve the time?
Thanks
You can use multiple Thread to send data to the server in the background.
If you are updating UI component after the execution use AsyncTask. But you have to run AsyncTask parallelly. You can do that by AsyncTaskCompat.executeParallel(Your AsyncTask);
If you wish to send data even your app closed. You can use service.
I'd recommend using Retrofit. It handles a lot of threading issues you might be struggling with.
Here's an example from their website.
You'd create an interface for the API you're looking to receive:
public interface GitHubService {
#GET("users/{user}/repos")
Call<List<Repo>> listRepos(#Path("user") String user);
}
You build a retrofit class
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
And finally you get a call object:
Call<List<Repo>> repos = service.listRepos("octocat");
Consuming the call object requires enqueueing a Callback. Here's an example using a different Retrofit service (TaskService in this case):
TaskService taskService = ServiceGenerator.createService(TaskService.class);
Call<List<Task>> call = taskService.getTasks();
call.enqueue(new Callback<List<Task>>() {
#Override
public void onResponse(Call<List<Task>> call, Response<List<Task>> response) {
if (response.isSuccessful()) {
// tasks available
} else {
// error response, no access to resource?
}
}
#Override
public void onFailure(Call<List<Task>> call, Throwable t) {
// something went completely south (like no internet connection)
Log.d("Error", t.getMessage());
}
}
Source
Hi I'm working with an API, which returns the login page when the session token is invalid/JSON response if the session is valid. How can I implement this with Retrofit, ie having multiple response types ?
P.S It's an old API and it can't be changed. I'm new to retrofit, I'll be really grateful of your help.
Would post this as comment as it's more a suggestion then actual answer but here it goes:
(If you're completely new to Retrofit leave a comment to explain it in more detail)
You could make your Call return a Response like so:
#GET("login/endpoint")
Call<Response> getLogin();
than you can make the call like this
Call<Response> getLogin = ApiService.getLogin();
getLogin.enqueue(new Callback<Void>() {
#Override
public void onResponse(Call<Response> call, Response<Response> response) {
//here you can access Response.body() and use it to determine wether it's json or html and react accordingly
}
#Override
public void onFailure(Call<Response> call, Throwable t) {
//todo: error message
}
});
note: the Response i've used is from the OkHttp Library.
If this doesn't work you could try to make your own converter which has a check for html/json and adding it in the creation of the retrofit instance. i'm not entirely sure how you can go about with that but this seems to have a general idea: custom converter from futurestudio.
If you need more guidance/clarification please let me know i'll be able to answer later today.
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 already looked at most of the questions related to prestashop.Some of them is saying that there is no api for prestashop.look at this link
http://online.fastchef.in/api/customers/12?output_format=JSON
it is giving result in json form.only thing is to parse this form.but still m getting error
My Code:MainActivity
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
int id=Integer.parseInt(mEditText.getText().toString());
PrestaShopClient client =retrofit.create(PrestaShopClient.class);
Call<Customer> hj=client.getCustomer(id);
hj.enqueue(new Callback<Customer>() {
#Override
public void onResponse(Call<Customer> call, Response<Customer> response) {
int status = response.code();
Customer customer = response.body();
mTextView.setText(customer.getFirstname());
}
#Override
public void onFailure(Call<Customer> call, Throwable t) {
}
});
PrestaShopCLient:
public interface PrestaShopClient {
#GET("customers/{id}?output_format=JSON")
Call<Customer> getCustomer(#Path("id") int id);
}
help me out guys...this problem took my day nd half ;(
We suggest you to create a separate web service that will communicate with your android app and fetches and passes data in JSON format.
Web service means a PHP file that is present inside your PrestaShop installation. It performs operations on the basis of received requests and returns the data in JSON format that can be further decoded by your android app for respective functionalities.
You can download a web service from the following link
Prestashop Android App
I am making an android app using Retrofit 2. My REST Api are all written in Liferay. Now in Liferay, what I have seen is, to access the web services we need to authenticate first. So i have authenticated like this
http://test:q1w2e3r4#192.168.0.110:8080/liferay-portlet/api/secure/jsonws/
Liferay has its own user authentication method which we have overridden.I checked the Web service call from Postman its working fine.
URL:http://test:q1w2e3r4#192.168.0.110:8080/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name
form-encoded values
companyId:10154
screenName:xyz
password:xyz
active:true
If i put this in the postman, it fetches the json response properly.
Now when i call the same from my android code i get a response "Unauthorized".
My Retrofit service
public interface LoginApi {
#FormUrlEncoded
#POST("/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name")
Call<User> login(#Field("companyId")long companyId,#Field("screenName")String screenName,#Field("password")String password,#Field("active")boolean active);
}
My RestApiManager Class(This class is used to call the service interface and create the retrofit builder)
public class RestApiManager {
private LoginApi loginApi;
public LoginApi login() {
if (loginApi==null) {
GsonBuilder gson=new GsonBuilder();
gson.registerTypeAdapter(String.class, new StringDeserializer());
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://test:q1w2e3r4#192.168.0.110:8080")
.addConverterFactory(GsonConverterFactory.create())
.build();
loginApi=retrofit.create(LoginApi.class);
}
return loginApi;
}
A call to the RestApiManager
Call<User> callUser=restApiManager.login().login(loginData.getCompanyId(),loginData.getScreenName(),loginData.getPassword(),loginData.isActive());
callUser.enqueue(new Callback<User>() {
#Override
public void onResponse(Response<User> response, Retrofit retrofit) {
Log.d("Login","Login Response:"+response.body());
}
#Override
public void onFailure(Throwable t) {
Log.d("Login","Login Response:"+t.getMessage());
}
});
It looks like perhaps your request should have a JSON body instead of a POST variables? You are calling a JSON webservice and your example parameters look more JSON than POST. If so, then you can encapsulate your parameters in an object --
public class User {
int companyId;
String screenName;
String password;
boolean active;
User(int companyId, String screenName, String password, boolean active) {
this.companyId = companyId;
this.screenName = screenName;
this.password = password;
this.active = active;
}
Your interface would be --
public interface LoginApi {
#POST("/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name")
Call<User> login(#Body User user);
}
and construct your call as --
User user = new User(loginData.getCompanyId(),loginData.getScreenName(),loginData.getPassword(),loginData.isActive());
Call<User> callUser = restApiManager.login().login(user);
The session management in cross-platform does not work the way it works on browser. Postman is a web client that works on browser platform.
1.One solution is to maintain cookies on the device.
Check this answer manage sessions with Android Application.
2.The other solution would be to use Json Web Token based auth.
I tried to run your demo code in my local PC, but no lucky as your server is in your local area network, about this question if you are using cookie or session authorize in you server side, I would suggestion you try to setCookieHandler as following, the PersistentCookieStore.java you can find here
private PersistentCookieStore cookieStore= new PersistentCookieStore(JApplication.getInstance().getApplicationContext());
CookieManager cookieManager = (new CookieManager(
cookieStore,
CookiePolicy.ACCEPT_ALL));
okHttpClient.setCookieHandler(cookieManager);
OkClient okClient = new OkClient(okHttpClient);
RestAdapter restAdapter = new RestAdapter.Builder()
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
request.addHeader(Constant.Header_UserAgent, getUserAgent());
}
})
.setClient(okClient)
.setEndpoint(URL)
.setErrorHandler(new HttpErrorHandler())
.setConverter(new GsonConverter(gson))
.build();
It may be difficult to us to help you without knowing exactly which request your Retrofit Api is building.
So I recommend you to configure a Logging Interceptor to get in touch with what is really happening then if you still don't know what is going on you could come back to us with more information.
Check this answer to discover how to configure LoggingInterceptor with Retrofit 2:
Logging with Retrofit 2
Hope that it helps.
Best regards.
I tried all the solutions given here, but unfortunately nothing worked.The only solution i found to call the lifer service from within android is to use lifer mobile sdk.It already has methods and services to call liferay services. You can also call upon your custom services.More info
Liferay Mobile SDK