I want to show 3 fragments in my Activity and load data from json in any fragments! I need to show website data into Recyclerview with OkHTTP v3 library.
I want to show this data for offline, I mean, if user turn off data/wifi show this datas for offline. but i do not want use SQLite Database!
For this idea i use okHttpClient cache , but not found setCache for client and show me this Error : Image link
MainActivity codes:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ArrayList<AndroidVersion> data;
private DataAdapter adapter;
private static Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
initViews();
}
private void initViews() {
recyclerView = (RecyclerView) findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
loadJSON();
}
private void loadJSON() {
OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR);
//setup cache
File httpCacheDirectory = new File(context.getCacheDir(), "responses");
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(httpCacheDirectory, cacheSize);
//add cache to the client
client.setCache(cache);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.learn2crack.com")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface request = retrofit.create(RequestInterface.class);
Call<JSONResponse> call = request.getJSON();
call.enqueue(new Callback<JSONResponse>() {
#Override
public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
JSONResponse jsonResponse = response.body();
data = new ArrayList<>(Arrays.asList(jsonResponse.getAndroid()));
adapter = new DataAdapter(data);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<JSONResponse> call, Throwable t) {
Log.d("Error", t.getMessage());
}
});
}
private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
okhttp3.Response originalResponse = chain.proceed(chain.request());
if (isNetworkAvailable(context)) {
int maxAge = 60; // read from cache for 1 minute
return originalResponse.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
}
};
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
}
How can i fix this and use okHttpClient cache?
From the screenshot, it is apparent you are using an outdated version of OkHttp. Retrofit 2 requires OkHttp 3. (The latest right now is 3.4.1.)
Also, to set the cache on the client in OkHttp 3, new OkHttpClient.Builder().cache(cache).build().
Related
I am using spoonacular API for a recipe app project. The problem occurs when trying to making multiple GET requests to the API. The first request is a simple search with a query parameter. The resulting JSON of the first request contains a Recipe ID and I use that ID to make the second GET request , where the problem occurs.
The API responds only when I make the request the first time but after that it responds with error code 500 [Internal Server Error].
I have tested the GET request on Postman but there it works fine every time.
I'm new to working with API's and any help would be immensely appreciated.
This is my Retrofit Service Class
public class ServiceGenerator {
public static final String API_BASE_URL = "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.build();
public static <S> S createService(Class<S> serviceClass, final String HostName, final String KeyVal)
{
if (!TextUtils.isEmpty(HostName) && !TextUtils.isEmpty(KeyVal))
{
HeadersInterceptor interceptor = new HeadersInterceptor(HostName,KeyVal);
if (!httpClient.interceptors().contains(interceptor))
{
httpClient.addInterceptor(interceptor);
builder.client(httpClient.build());
retrofit = builder.build();
}
}
return retrofit.create(serviceClass);
}
This is the Interceptor I am using to add Headers with the request.
public class HeadersInterceptor implements Interceptor {
private String HostName,KeyVal;
HeadersInterceptor(final String HostName,final String KeyVal) {
this.HostName = HostName;
this.KeyVal = KeyVal;
}
#NotNull
#Override
public Response intercept(#NotNull Chain chain) throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.addHeader("X-RapidAPI-Host",HostName)
.addHeader("X-RapidAPI-Key",KeyVal);
Request request = builder.build();
return chain.proceed(request);
}
}
This is my Fragment which makes a search query and SUCCESSFULLY return results[Receipe ID's]
public class ListSelectedFragments extends Fragment {
private ProgressBar PreviewFragPrg;
private final String TAG = "ListSelectedFragment->";
private PreviewRecipeAdapter adapter;
private RecyclerView SelectedItemRV;
private ArrayList<RecipePreviewHolder> RecipePreviewsList = new ArrayList<>();
public ListSelectedFragments() {
// Required empty public constructor
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_list_selected_fragments, container, false);
SelectedItemRV = view.findViewById(R.id.SelectedItemRV);
TextView DisplayNameTV = view.findViewById(R.id.DisplayNameTV);
PreviewFragPrg = view.findViewById(R.id.PreviewFragPrg);
ImageView BackBtn = view.findViewById(R.id.BackBtn);
BackBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (getFragmentManager() != null) {
getFragmentManager().popBackStackImmediate();
}
}
});
if (getArguments() != null) {
final String QueryTag = getArguments().getString("QueryTag");
final String CuisineName = getArguments().getString("CuisineName");
if(CuisineName!=null){
DisplayNameTV.setText(CuisineName);
}
if(QueryTag!=null){
ProcessQuery(QueryTag);
}
}
return view;
}
private void ProcessQuery(final String QueryStr){
String hostname = getResources().getString(R.string.spoonacular_host_name);
String key = getResources().getString(R.string.spoonacular_apikey_val);
final ServiceGenerator.GetDataService mService =
ServiceGenerator.createService(ServiceGenerator.GetDataService.class, hostname,key);
Call<RecipeInfoModel> call = mService.getRecipes(QueryStr);
call.enqueue(new Callback<RecipeInfoModel>() {
#Override
public void onResponse(#NonNull Call<RecipeInfoModel> call,
#NonNull Response<RecipeInfoModel> response)
{
Log.d(TAG, "Request Response Received");
Log.d(TAG, response.toString());
if (response.body() != null) {
Results[] mRES = response.body().getResults();
SetUpRecipePreviews(mRES);
PreviewFragPrg.setVisibility(View.GONE);
}
}
#Override
public void onFailure(#NonNull Call<RecipeInfoModel> call, #NonNull Throwable t) {
Log.d(TAG, "Request Failed");
Log.d(TAG, call.toString());
Log.d(TAG, "Throwable ->" + t);
PreviewFragPrg.setVisibility(View.GONE);
Toast.makeText(getActivity(),"Could not get required recipes",Toast.LENGTH_SHORT).show();
}
});
Log.d(TAG, "User Inputed Request\n"+call.request().url().toString());
}
private void SetUpRecipePreviews(final Results[] mRES) {
RecipePreviewsList.clear();
adapter = new PreviewRecipeAdapter(getActivity(),RecipePreviewsList);
SelectedItemRV.setLayoutManager(new GridLayoutManager(getActivity(), 2));
SelectedItemRV.setAdapter(adapter);
for (Results mRE : mRES) {
String ImgUrls = mRE.getImage();
RecipePreviewHolder obj = new RecipePreviewHolder(Integer.valueOf(mRE.getId()),
mRE.getTitle(), ImgUrls);
Log.d("GlideLogs->","Rid->"+mRE.getId());
Log.d("GlideLogs->","Img URL->"+ ImgUrls);
Log.d("GlideLogs->","Name->"+mRE.getTitle());
RecipePreviewsList.add(obj);
}
if(RecipePreviewsList.size()>1){
adapter.notifyDataSetChanged();
}
}
This is the Activity I transition to from my Fragment after clicking on a Recipe Card... Sending the Recipe ID in the extras. This function is called immediately after receiving intent extras.
private void RetrieveRecipeInfo(final int recipeID) {
String hostname = getResources().getString(R.string.spoonacular_host_name);
String key = getResources().getString(R.string.spoonacular_apikey_val);
final ServiceGenerator.GetDataService mService =
ServiceGenerator.createService(ServiceGenerator.GetDataService.class, hostname,key);
Call<RecipeDetailedInfo> call = mService.getInformation(185071);
Log.d(TAG , "Your GET Request:\n"+call.request().url().toString());
call.enqueue(new Callback<RecipeDetailedInfo>() {
#Override
public void onResponse(#NonNull Call<RecipeDetailedInfo> call, #NonNull Response<RecipeDetailedInfo> response)
{
Log.d(TAG,"OnResponse() Called\n");
Log.d(TAG,"Response = "+ response);
if(response.body()!=null) {
String obj = response.body().getSourceUrl();
Log.d(TAG,"Getting Recipe Info\n");
Log.d(TAG, String.valueOf(obj));
}
}
#Override
public void onFailure(#NonNull Call<RecipeDetailedInfo> call, #NonNull Throwable t){
}
});
}
Using postman I get the results every time but in my application the API stops responding after the first request. Is there a problem with the way I'm including headers?
So I finally got things working. The problem was with the HeadersInterceptor.java. I was using the Interceptor to add the Headers with the call but I found out a much easier way and it works like a charm.
Simply add #Header with the call to add headers without interceptor in Retrofit.
public interface GetDataService {
#GET("recipes/complexSearch?")
Call<RecipeInfoModel> getRecipes(
#Header("X-RapidAPI-Host") String api,
#Header("X-RapidAPI-Key") String apiKey,
#Query("query") String query_str);
}
I am currently recording a video on a device, compressing this video and then uploading the compressed video to the server using Retrofit 2. I am also using the Worker class to perform all this in the background. A Progress is also being displayed in the notification bar while the upload is happening. My problem is when the app is Killed the entire upload process stops. I have tried to return WorkerResult.RETRY, which does work but it just repeats and thus one file is uploaded multiple times.The code is mentioned below :
Worker Class
public class UploadWorker extends Worker implements ProgressRequestBody.UploadCallBacks {
private static final String LOG_TAG = UploadWorker.class.getSimpleName();
public static final int UPDATE_PROGRESS = 8344;
Context context;
WorkerParameters parameters;
private static final String SERVER_PATH = "";
String filePath;
/*For notification update*/
private NotificationCompat.Builder notificationBuilder;
private NotificationManager notificationManager;
public UploadWorker(Context context,
WorkerParameters parameters) {
super(context, parameters);
this.context = context;
this.parameters = parameters;
}
#NonNull
#Override
public Result doWork() {
showNotificationUpdate();
compressVideo(getInputData().getString("currentPhotoPath");,
getInputData().getString("fileDestination"););
constructFile(filePath);
// Indicate success or failure with your return value:
return Result.SUCCESS;
}
private void uploadVideoToServer(File fileToUpload) {
ProgressRequestBody fileBody = new ProgressRequestBody(fileToUpload, this);
Gson gson = new GsonBuilder()
.setLenient()
.create();
MultipartBody.Part vFile = MultipartBody.Part.createFormData("fileToUpload", fileToUpload.getName(), fileBody);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(SERVER_PATH)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(provideClient())
.build();
VideoInterface vInterface = retrofit.create(VideoInterface.class);
Call<ResponseBody> serverCom = vInterface.uploadVideo(vFile);
serverCom.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
if (response.body() != null) {
Log.d(LOG_TAG, "Resposne == " + response.body().string());
}
} catch (IOException e) {
e.printStackTrace();
}
Log.d(LOG_TAG, "Response In String == " + response);
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d(LOG_TAG, "Error == " + t.getLocalizedMessage());
}
});
}
#Override
public void onProgressUpdate(int percentage) {
updateNotification(percentage);
}
#Override
public void onError() {
sendProgressUpdate(false);
}
#Override
public void onFinish() {
sendProgressUpdate(true);
notificationManager.cancel(0);
notificationBuilder.setProgress(0, 0, false);
notificationBuilder.setContentTitle("Upload Done");
notificationBuilder.setSmallIcon(android.R.drawable.stat_sys_upload_done);
notificationManager.notify(0, notificationBuilder.build());
}
}
This is how I am setting up the worker in my activity
Data inputData = new Data.Builder()
.putString("currentPhotoPath", mCurrentPhotoPath)
.putString("fileDestination", f.getPath())
.build();
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresStorageNotLow(true)
.build();
OneTimeWorkRequest compressionWork =
new OneTimeWorkRequest.Builder(UploadWorker.class)
.setConstraints(constraints)
.addTag("CompressVideo")
.setInputData(inputData)
.build();
WorkManager.getInstance()
.enqueue(compressionWork);
WorkManager.getInstance().getStatusById(compressionWork.getId())
.observe(this, new Observer<WorkStatus>() {
#Override
public void onChanged(#Nullable WorkStatus workStatus) {
Log.d(LOG_TAG, "WORKER STATE == " + workStatus.getState().name());
if (workStatus != null && workStatus.getState().isFinished()) {
Log.d(LOG_TAG, "Is WOrk Finished == " + workStatus.getState().isFinished());
}
}
});
Can someone please help me out in finding an appropriate solution so that when the app is closed, the file upload still continues and stops when it is done?
I am new to Android rest api, basically I was trying to retrieve some information from a demo website using rest api together with the retrofit. Somehow my api call always on failure, hope someone could help.
Api.class
String BASE_URL = "https://demo.openmrs.org/openmrs/ws/rest/v1/";
#GET("location?tag=Login%20Location")
Call<List<RetroLocation>> getLocation();
Location.class
#SerializedName("display")
#Expose
protected String display;
#Expose
private String name;
public RetroLocation() {}
public RetroLocation(String display) {
this.display = display;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Call the api from the main class
private void retriveLocation() {
//create object for the RetrofitInstance
RestApi api = RetrofitInstance.getRetrofitInstance().create(RestApi.class);
//making the call object using the api method created in the api class
Call<List<RetroLocation>> call = api.getLocation();
//making the call using enqueue(), it takes callback interface as an argument
call.enqueue(new Callback<List<RetroLocation>>() {
#Override
public void onResponse(Call<List<RetroLocation>> call, Response<List<RetroLocation>> response) {
progressDoalog.dismiss();
if (response.body() != null) {
//goes to my list
List<RetroLocation> locationList = response.body();
//creating an string array for the listview
String[] location = new String[locationList.size()];
//fill in the array with the response data from json
for (int i = 0; i < locationList.size(); i++) {
location[i] = locationList.get(i).getName();
}
//displaying the string array into the listView
ArrayAdapter adapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.custom_row, R.id.location, location);
listviewLocation.setAdapter(adapter);
Log.d("result", "Respond");
//generateDataList(response.body());
}else
Log.d("result", "No response");
}
#Override
public void onFailure(Call<List<RetroLocation>> call, Throwable t) {
//if(progressDoalog != null && progressDoalog.isShowing())
//progressDoalog.dismiss();
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
Log.d("result", "onFailuer");
}
});
RestInstance.class
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(RestApi.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
}
if(retrofit!=null)
Log.d("result", "logged in");
return retrofit;
}
static OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("Authorization", "Basic "+ getAuth())
.header("Accept", "application/json")
.method(original.method(),original.body())
.build();
return chain.proceed(request);
}
}).build();
Update: Here is the throwable error message
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:80)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:119)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:218)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:112)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
The output of base_url
<org.openmrs.module.webservices.rest.SimpleObject serialization="custom">
<unserializable-parents/>
<map>
<default>
<loadFactor>0.75</loadFactor>
<threshold>12</threshold>
</default>
<int>16</int>
<int>3</int>
<string>uuid</string>
<string>b1a8b05e-3542-4037-bbd3-998ee9c40574</string>
<string>display</string>
<string>Inpatient Ward</string>
<string>links</string>
<list>
<org.openmrs.module.webservices.rest.web.Hyperlink>
<rel>self</rel>
<uri>
http://demo.openmrs.org/openmrs/ws/rest/v1/location/b1a8b05e-3542-4037-bbd3-998ee9c40574
</uri>
</org.openmrs.module.webservices.rest.web.Hyperlink>
</list>
</map>
<linked-hash-map>
<default>
<accessOrder>false</accessOrder>
</default>
</linked-hash-map>
</org.openmrs.module.webservices.rest.SimpleObject>
<org.openmrs.module.webservices.rest.SimpleObject serialization="custom">
<unserializable-parents/>
<map>
<default>
<loadFactor>0.75</loadFactor>
<threshold>12</threshold>
</default>
<int>16</int>
<int>3</int>
<string>uuid</string>
<string>2131aff8-2e2a-480a-b7ab-4ac53250262b</string>
<string>display</string>
<string>Isolation Ward</string>
<string>links</string>
<list>
<org.openmrs.module.webservices.rest.web.Hyperlink>
<rel>self</rel>
<uri>
http://demo.openmrs.org/openmrs/ws/rest/v1/location/2131aff8-2e2a-480a-b7ab-4ac53250262b
</uri>
</org.openmrs.module.webservices.rest.web.Hyperlink>
</list>
</map>
<linked-hash-map>
<default>
<accessOrder>false</accessOrder>
</default>
</linked-hash-map>
</org.openmrs.module.webservices.rest.SimpleObject>
try this
BASE URL https://demo.openmrs.org/
Retrofit Interface
#GET("openmrs/ws/rest/v1/location")
Call<List<RetroLocation>> getLocation(#Query("tag") String tag);
Change like this may work.
String BASE_URL = "https://demo.openmrs.org/";
#GET("openmrs/ws/rest/v1/location?tag=Login%20Location")
Call<List<RetroLocation>> getLocation();
I am just trying to do post api call using Retrofit.The server is responding with correct data.I checked with Postman(Chrome). My code is as follows
public class MainActivity extends Activity implements retrofit2.Callback>{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(6, TimeUnit.MINUTES)
.readTimeout(6, TimeUnit.MINUTES)
.writeTimeout(6, TimeUnit.MINUTES)
.build();
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://kokanplaces.com/")
.addConverterFactory(GsonConverterFactory.create(gson)).client(okHttpClient)
.build();
// prepare call in Retrofit 2.0
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
Call<List<CityModel>> call = apiService.getCitiesList();;
//asynchronous call
call.enqueue(this);
}
#Override
public void onResponse(Call<List<CityModel>> call, Response<List<CityModel>> response) {
int code = response.code();
if (code == 200) {
for (CityModel cityModel : response.body()) {
System.out.println(
cityModel.getCityname() + " (" + cityModel.getCityId() + ")");
}
} else {
Toast.makeText(this, "Did not work: " + String.valueOf(code), Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<List<CityModel>> call, Throwable t) {
Toast.makeText(this, "failure", Toast.LENGTH_LONG).show();
System.out.println(t.fillInStackTrace());
t.printStackTrace();
}
}
public interface ApiInterface {
#POST("wp-json/getCities")
Call<List<CityModel>> getCitiesList();
}
Every time it is throwing Socket timeout exception.
Any solution will be great help.
I met the problems like you before. I fixed by adding custom OkHttpClient:
Constants.TIMEOUT_CONNECTION = 60;
private OkHttpClient getOkHttpClient() {
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(0, TimeUnit.NANOSECONDS)
.connectTimeout(Constants.TIMEOUT_CONNECTION, TimeUnit.SECONDS)
.writeTimeout(Constants.TIMEOUT_CONNECTION, TimeUnit.SECONDS)
// .sslSocketFactory(getSSLSocketFactory())
.build();
return okHttpClient;
}
and retrofitAdapter:
retrofitAdapter = new Retrofit.Builder()
.baseUrl(ConstantApi.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(getOkHttpClient())
.build();
Remember readTimeout is 0, I am using retrofit 2.1.0. Default timeout of retrofit is 10 seconds. I tried to set readTimeout is 60 seconds but no effect.
Topic tags: Socket closed, socket timeout
Explanation: Retrofit maintains connection which is locking socket.
More: https://github.com/square/okhttp/issues/3146
SOLUTION:
configure connectionPool like in below example:
private OkHttpClient getOkHttpClient() {
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectionPool(new ConnectionPool(0,1,TimeUnit.NANOSECONDS))
.build();
return okHttpClient;
}
Please remember to mark answer as correct :)
I'm new to rx java, so can you help with it. I have simple retrofit implementation and i'm using it to get data about radio. I need to get this data every 10 seconds. The only way i know to do it is using Service with AlarmManager, but i don't like it. How can i do it using rx java? Can i get data every 10 seconds.
Here is the code of retrofit implementation
public class ApiProvider {
public static final String PRODUCTION_API_URL = "http://radio.somesite.org";
static final int DISK_CACHE_SIZE = (int) MEGABYTES.toBytes(50);
private static ApiProvider instance;
private Application application;
private ApiProvider( ) {
this.application = CApplication.getApplication();
}
public static ApiProvider getInstance() {
if (instance != null)
return instance;
else {
instance = new ApiProvider();
return instance;
}
}
public static OkHttpClient createOkHttpClient(Application app) {
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(10, SECONDS);
client.setReadTimeout(10, SECONDS);
client.setWriteTimeout(10, SECONDS);
// Install an HTTP cache in the application cache directory.
File cacheDir = new File(app.getCacheDir(), "http");
Cache cache = new Cache(cacheDir, DISK_CACHE_SIZE);
client.setCache(cache);
return client;
}
private RestAdapter getRestAdapter() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(DateTime.class, new DateTimeConverter())
.create();
OkHttpClient client = createOkHttpClient(application);
Endpoint endpoint = Endpoints.newFixedEndpoint(PRODUCTION_API_URL);
return new RestAdapter.Builder() //
.setClient(new OkClient(client)) //
.setEndpoint(endpoint) //
.setConverter(new GsonConverter(gson)) //
.build();
}
private RadioLiveInfoService getRadioInfo() {
return getRestAdapter().create(RadioLiveInfoService.class);
}
private RadioWeekInfoService getRadioWeek() {
return getRestAdapter().create(RadioWeekInfoService.class);
}
public void getRadioInfo(Type type, final CallbackInfoListener listener) {
Callback callback = new Callback() {
#Override
public void success(Object o, Response response) {
try {
LiveInfo liveInfo = (LiveInfo) o;
listener.dataLoaded(liveInfo, true);
Log.d("Success", response.toString());
} catch (ClassCastException ex) {
ex.printStackTrace();
}
}
#Override
public void failure(RetrofitError retrofitError) {
listener.dataLoaded(new LiveInfo(), false);
Log.e("Error", retrofitError.toString());
}
};
getRadioInfo().commits(type, callback);
}
public void getRadioWeekInfo(final CallbackWeekListener listener) {
Callback callback = new Callback() {
#Override
public void success(Object o, Response response) {
try {
WeekInfo weekInfo = (WeekInfo) o;
listener.dataLoaded(weekInfo, true);
Log.d("Success", response.toString());
} catch (ClassCastException ex) {
ex.printStackTrace();
}
}
#Override
public void failure(RetrofitError retrofitError) {
listener.dataLoaded(new WeekInfo(), false);
Log.e("Error", retrofitError.toString());
}
};
getRadioWeek().commits(callback);
}
}
Thanks in advance
I made it to work this way. Still i need to understand how to do it with composit subscription.
RadioLiveInfoObservableService radioLiveInfoObservableService=ApiProvider.getInstance().getRadioObserverInfo();
radioLiveInfoObservableService.commits(Type.INTERVAL)
.observeOn(AndroidSchedulers.mainThread())
.doOnError(trendingError)
.onErrorResumeNext(Observable.<LiveInfo>empty()).subscribe(new Action1<LiveInfo>() {
#Override
public void call(LiveInfo liveInfo) {
List<Current> currents=new ArrayList<Current>();
currents.add(liveInfo.getCurrent());
adapter.currentShows=currents;
adapter.notifyDataSetChanged();
rv.setAdapter(adapter);
}
});
I am using it this way
fun getEventDetails(eventId: Long) : MutableLiveData<Response> {
Log.d("Retrofit", "Get event detail")
compositeDisposable.add(useCase.getEvents()
.repeatWhen {
return#repeatWhen it.delay(10, TimeUnit.SECONDS) //Repeat every 10 seconds
}
.repeatUntil {
return#repeatUntil repeat //Boolean
}
.map(this::parseResponse)
.subscribeOn(Schedulers.io())
.unsubscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
dashboardResponse.postValue(Response().success(it))
}, {
Timber.d(it.message)
dashboardResponse.postValue(Response().error(it.getRetrofitErrorMessage()))
})
)
return dashboardResponse
}
And API Method is :
#GET("events")
fun getEvents(): Observable<String>