How to stream real time data using Retrofit - android

I want to observer changes from server in my android app.
So I'm using this interface for open stream with server.
public interface Service {
#GET("/n/{id}/streaming")
void streamThreads(#Path("name_space_id") String Id, #QueryMap Map<String, String> options,#Query("exclude_types") String type, Callback<Object> callback);
}
and this is my method where I can get response in my activity
server.streamThreads(accountInfo.getId(), map, "thread", new Callback<Object>() {
#Override
public void success(Object o, Response response) {
String json = (String) o;
Log.i(TAG,json);
}
#Override
public void failure(RetrofitError error) {
Response r = error.getResponse();
if (r != null)
Log.e(TAG, "error: " + r.getReason());
}
});
So I tested method in web browser and life stream works.
But response comes in my mobile app every 30 minutes. I'm using one activity and call method onCreate().
Thanks

Retrofit provides an #Streaming annotation.
The unread byteStream can then be obtained from the raw OkHttp ResponseBody.

Related

trying to get results from youtube api via retrofit

get request endpoint method defined in api interface
#GET("youtube/v3/search")
Callback<YoutubeResponse> getYouTubeVideos(#Query("key") String apiKey,
#Query("channelId") String channelId,
#Query("part") String videoPart,
#Query("order") String videoOrder,
#Query("maxResults") int maxResults,
Callback<ChannelListResponse> callback);
Method call to get the results :
Callback <YoutubeResponse> call = apiService.getYouTubeVideos(API_KEY,
"UCjXfkj5iapKHJrhYfAF9ZGg", "snippet", "date", 20, new Callback<ChannelListResponse>() {
#Override
public void onResponse(Call<ChannelListResponse> call, Response<ChannelListResponse> response) {
Log.v("check", response.body().getEtag() + "check");
}
#Override
public void onFailure(Call<ChannelListResponse> call, Throwable t) {
}
}) ;
I am not getting results via this implementaion giving illegal stat exception .
There is some structual mistake because the log says Unable to create call adapter for retrofit2.Callbackfor method ApiInterface.getYouTubeVideos
using these additional links to implement the same . Using this reference link for help : YouTube Data API v3 search JSON response retrofit parsing error
But If keep the return type of getYouTubeVideos() as void. Then it says service method can not have void return type .
A help in this regards will be appreciated
Please correct the retofit syntax like this.
api interface,
#GET("youtube/v3/search")
Call<ChannelListResponse> getYouTubeVideos(#Query("key") String apiKey,
#Query("channelId") String channelId,
#Query("part") String videoPart,
#Query("order") String videoOrder,
#Query("maxResults") int maxResults);
Method call,
Call<ChannelListResponse> call = apiService.getYouTubeVideos(API_KEY,
"UCjXfkj5iapKHJrhYfAF9ZGg", "snippet", "date", 20);
call.enqueue(new Callback<ChannelListResponse>() {
#Override
public void onResponse(Call<ChannelListResponse>call,
Response<ChannelListResponse> response) {
Log.d(TAG, "onResponse");
}
#Override
public void onFailure(Call<ChannelListResponse>call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});

retrofit calling id from url

How I use these query in retrofit network call and display it in category wise result
https://api.themoviedb.org/3/genre/{genre_id}/movies
Perhaps this could help:
interface class
public interface TheApiInterface{
#GET("url/bits/until/{path_variable}/then/more/url")
Call<TheThingResponse> getTheThing(#Path("path_variable") String var);
}
Activity or whatever:
public class ThePlaceYoureCallingItFrom {
//set up the api interface and http client
public TheApiInterface getApi(){
String endpoint = "https://api.root.site/api/";
//set up retrofit object
return new Retrofit.Builder().baseUrl(endpoint)
//add chosen converter factory for pojo serialization
.addConverterFactory(GsonConverterFactory.create())
//add the OKHTTP client
.client(new OkHttpClient.Builder().build())
//now gimme
.build().create(TheApiInterface.class);
}
public void callGetTheThing(){
//create call
Call<TheThingResponse> call = getApi().getTheThing("somePathVar");
//set callback
ThingResponseCallback callback = new ThingResponseCallback(this, THING_RESPONSE_INTENT_FILTER);
//fire
call.enqueue(callback);
}
}
the callback:
public class ThingResponseCallback implements Callback<TheThingResponse>{
#Override
public void onResponse(Call<TheThingResponse> call, Response<TheThingResponse> response) {
if (response.isSuccessful() && response.body() != null) {
Log.i(TAG, "onResponse: success: theResponseFieldIWant1: " + response.theResponseFieldIWant1;);
} else {
Log.i(TAG, "onResponse: something went wrong with the response object " +response.body());
}
}
#Override
public void onFailure(Call<TheThingResponse> call, Throwable t) {
Log.i(TAG, "onFailure: to: " + call.request().url() + " req " + call.request());
}
}
the response pojo:
public class TheThingResponse{
#SerializedName("theJsonKeyOfTheFieldReturnedInServerResponse1")
public String theResponseFieldIWant1;
#SerializedName("theJsonKeyOfTheFieldReturnedInServerResponse2")
public String theResponseFieldIWant2;
#SerializedName("theJsonKeyOfTheFieldReturnedInServerResponse3")
public String theResponseFieldIWant3;
#SerializedName("theJsonKeyOfTheFieldReturnedInServerResponse4")
public String theResponseFieldIWant4;
}
the JSON you're receiving would look like this:
{
"theJsonKeyOfTheFieldReturnedInServerResponse1": "the value I wanted 1",
"theJsonKeyOfTheFieldReturnedInServerResponse2": "the value I wanted 2",
"theJsonKeyOfTheFieldReturnedInServerResponse3": "the value I wanted 3",
"theJsonKeyOfTheFieldReturnedInServerResponse4": "the value I wanted 4"
}
but you can build more complex POJOs for more complex JSON.
I've found it useful to make my POJOs all share a Serializable parent class, to make them easy to move about in the Callback, but you could also use a ContentProvider in here quite readily and insert some rows into a DB or something like that if you want to have a more permanent storage.
But bear in mind this is all async- if you want synchronous Retrofit calls, you can use call.execute()
At least in the "retrofit" library, it works like this
#GET("/url/{id}")
suspend fun getNews(
#Path("id") searchById:String
):Response<News>

Custom API in Azure APP Serivce examples searched for Android Client

I need a working example for a custom API for Microsoft Azure App Service.
I could not get any useful or working information/examples for that, or they just show each time different approaches which are outdated?!?!
For now I have a working table controller which gets information from database and returns it back to my Android client. Now I need to define a custom API Controller to get a string back. In the examples they are all sending an object to the service in order to get an object back. I do not want to send anything to the API, just retrieve some information back from a GET Request.
Regards
// EDIT - Added / edited client / server code to Post a String.
You can use the following code to do a GET request on the auto generated API controller Visual Studio creates (ValuesController).
private void getStringFromAzure() throws MalformedURLException {
// Create the MobileService Client object and set your backend URL
String yourURL = "https://yourApp.azurewebsites.net/";
MobileServiceClient mClient = new MobileServiceClient(yourURL, this);
// Your query pointing to yourURL/api/values
ListenableFuture<JsonElement> query = mClient.invokeApi("values", null, GetMethod, null);
// Callback method
Futures.addCallback(query, new FutureCallback<JsonElement>() {
#Override
public void onSuccess(JsonElement jsonElement) {
// You are expecting a String you can just output the result.
final String result = jsonElement.toString();
// Since you are on a async task, you need to show the result on the UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, result, Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onFailure(Throwable throwable) {
Log.d(TAG, "onFailure: " + throwable.getMessage());
}
});
}
public void sendString(final String someString) throws MalformedURLException {
// Your query pointing to /api/values/{String}
ListenableFuture<JsonElement> query = mClient.invokeApi("values/" + someString, null, PostMethod, null);
// Callback method
Futures.addCallback(query, new FutureCallback<JsonElement>() {
#Override
public void onSuccess(JsonElement jsonElement) {
// You are expecting a String you can just output the result.
final String result = jsonElement.toString();
}
#Override
public void onFailure(Throwable throwable) { }
});
}
The backend API: (ValuesController)
{
// Use the MobileAppController attribute for each ApiController you want to use
// from your mobile clients
[MobileAppController]
public class ValuesController : ApiController
{
// GET api/values
public string Get()
{
return "Hello World!";
}
// POST api/values/inputString
public string Post(string inputString)
{
return inputString;
}
}
}
You can also send parameters along in the following way:
List<Pair<String, String>> parameters = new ArrayList<>();
parameters.add(new Pair<>("name", "John"));
parameters.add(new Pair<>("password", "fourwordsalluppercase"));
ListenableFuture<JsonElement> query = client.invokeApi("yourAPI", PostMethod, parameters);
Or as json in the body:
JsonObject body = new JsonObject();
body.addProperty("currentPassword", currentPassword);
body.addProperty("password", password);
body.addProperty("confirmPassword", confirmPassword);
ListenableFuture<JsonElement> query = mClient.invokeApi("yourAPI", body, PostMethod, null);
Based on my understanding, I think there are two parts in your question which include as below. And I think you can separately refer to two sections to get the answers and write your own example.
How to define a custom API on Azure Mobile App to retrieve data from database? Please refer to the section Custom APIs to know how to do with Azure Mobile App backend.
How to call a custom API from Android App? Please refer to the section How to: Call a custom API to know how to do with Android SDK.

Trouble get special character in retrofit 2 and gson

I'm trying to get a json list from a web service.
This is the json string return by server :
[{"categoryName":"Política"},{"categoryName":"Economía"},{"categoryName":"Cultura"},{"categoryName":"Deportes"}
The problem is converting in to the POJO. The special characters (í) it's appear like "Pol�tica".
This is the retrofit call function :
#GET("categories")
public Call<List<CategoryPojo>> getCategorias(#Query("sitename") String site)
this is the callback function:
Call<List<CategoryPojo>> call = restservice.getApiService().getCategorias(medio);
try {
call.enqueue(new Callback<List<CategoryPojo>>() {
#Override
public void onResponse(Call<List<CategoryPojo>> call, Response<List<CategoryPojo>> response) {
List<CategoryPojo> categories = response.body();
if (listener != null)
listener.onDataLoaded(categories);
}
#Override
public void onFailure(Call<List<CategoryPojo>> call, Throwable throwable) {
Log.e("Retrofit Error", throwable.getMessage());
}
});
this is the POJO:
public class CategoryPojo implements Serializable{
public CategoryPojo() { }
#SerializedName("categoryName")
private String name;
public String getName()
{
return this.name;
}
}
The result of the request to the Web services, (output in browser) is :
[{"categoryName":"Política"},{"categoryName":"Economía"},{"categoryName":"Cultura"},{"categoryName":"Deportes"},{"categoryName":"Salud"},{"categoryName":"Ciencia y Tecnología"},{"categoryName":"Medio Ambiente"},{"categoryName":"Medios"},{"categoryName":"Militar e Inteligencia"},{"categoryName":"Sociedad"}]
So, the return json has a good encoding...i think that maybe is about the way retrofit read the response.
I'm using retrofit-2.0.2, gson-2.6.1, converter-gson-2.0.2, okhttp-3.2.0.
Any help? please
You should check Content-type in the response headers. Look for the charset value and try to change that on the backend side to application/josn;charset=UTF-8. That worked for me.

How to handle null param values in Retrofit

We're moving from Apache's http client to Retrofit and we've found some edge cases where param values can be null.
Apache used to intercept these and turn them into empty strings, but Retrofit throws an IllegalArgumentException.
We want to replicate the old behavior so that it doesn't cause any unexpected issues out in production. Is there a way for me to swap these null values with empty strings before ParameterHandler throws an exception?
You can try the following:
My web service (Asp.Net WebAPI):
[Route("api/values/getoptional")]
public IHttpActionResult GetOptional(string id = null)
{
var response = new
{
Code = 200,
Message = id != null ? id : "Response Message"
};
return Ok(response);
}
Android client:
public interface WebAPIService {
...
#GET("/api/values/getoptional")
Call<JsonObject> getOptional(#Query("id") String id);
}
MainActivity.java:
...
Call<JsonObject> jsonObjectCall1 = service.getOptional("240780"); // or service.getOptional(null);
jsonObjectCall1.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
Log.i(LOG_TAG, response.body().toString());
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.e(LOG_TAG, t.toString());
}
});
...
Logcat output:
If using service.getOptional(null);
04-15 13:56:56.173 13484-13484/com.example.asyncretrofit I/AsyncRetrofit: {"Code":200,"Message":"Response Message"}
If using service.getOptional("240780");
04-15 13:57:56.378 13484-13484/com.example.asyncretrofit I/AsyncRetrofit: {"Code":200,"Message":"240780"}

Categories

Resources