Actually i'm using Retrofit2 in my app for sending some text to my server.
The issue is when i'm using a Radio Frequency Device when the network is interrupted so i'm getting onFailure the call should be cancelled but as soon as the device is reconnected to the network seems it's resending the text or something like that text remain in queue and i would handle it.
Here is my method where i'm sending the text ( i've yet tryed to use call.cancel() in onFailure but that has no effect )
@SuppressLint("DefaultLocale")
public void sendPost() {
@SuppressLint({"SdCardPath", "DefaultLocale"}) final File file = new File("/data/data/app/files/"+String.format("%03d", Integer.valueOf(nTerminalino))+"_"+nTavoli.getText().toString()+".txt");
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
RequestBody fbody = RequestBody.create(MediaType.parse("text/*"), file);
builder.addFormDataPart(String.format("%03d", Integer.valueOf(nTerminalino))+"_"+nTavoli.getText().toString(), file.getName(),fbody);
MultipartBody requestBody = builder.build();
final APIService apiService = ApiUtils.getAPIService(ipCASSA);
final Call<Void> calls = apiService.savePost(requestBody);
calls.enqueue(new Callback<Void>() {
@Override
public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
if (response.isSuccessful()) {
Log.i("RESPONSE: ", response.toString());
Print();
file.delete();
dialogLoading.dismiss();
Runtime.getRuntime().gc();
}else {
calls.cancel();
}
}
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
Log.e("TAG", t.toString());
MediaPlayer mpFound = MediaPlayer.create(pterm.this, R.raw.errorsound);
mpFound.start();
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (v.hasVibrator()) {
v.vibrate(6000);
}
new GlideToast.makeToast(pterm.this, "CONNESSIONE FALLITA!", GlideToast.LENGTHLONG, GlideToast.FAILTOAST).show();
dialogLoading.dismiss();
}
});
}
In my class where i'm building OkHttpClient i've set retryOnConnectionFailure(false) but still unable to solve the problem that even onFailure i'm getting the POST request.
UPDATE:
After some research i found that OkHttp make's silent retry of POST on connection failure.
So how can i prevent the client to retry?
SOME INFO:
My app is an app for waiter so when i get a onFailure
message i notify the waiter that the receipt hasn't been received by POS and hasn't been printed but as OkHttpClient
still retry to sending the file and i'm forcing the waiter to resend the receipt after onFailure
it cause printing duplicated receipts.
Here is my ApiUtils class , APIService interface and RetrofitClient class
class ApiUtils {
private ApiUtils() {}
static APIService getAPIService(String ipCASSA) {
String BASE_URL = "http://"+ipCASSA+"/web/";
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10000, TimeUnit.MILLISECONDS)
.writeTimeout(10000, TimeUnit.MILLISECONDS)
.readTimeout(10000, TimeUnit.MILLISECONDS)
.retryOnConnectionFailure(false)
.build();
return RetrofitClient.getClient(BASE_URL,okHttpClient).create(APIService.class);
}
}
public interface APIService {
@POST("CART=PTERM")
Call<Void> savePost(@Body RequestBody text);
}
class RetrofitClient {
private static Retrofit retrofit = null;
static Retrofit getClient(String baseUrl, OkHttpClient okHttpClient) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Calls may be executed synchronously with execute() , or asynchronously with enqueue(retrofit2. Callback<T>) . In either case the call can be canceled at any time with cancel() . A call that is busy writing its request or reading its response may receive a IOException ; this is working as designed.
Learn to execute synchronous and asynchronous calls (i.e. blocking and non-blocking calls) in an android app using Retrofit2 and OkHttp library.
You could try canceling the call directly. So when the call fails, in the onFailure
callback, you can do something like
@Override
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable t) {
if (!call.isCanceled()) {
// Do receipt logic
call.cancel();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With