На самом деле я использую Retrofit2 в своем приложении для отправки некоторого текста на мой сервер.
Проблема в том, когда я использую радиочастотное устройство, когда сеть прерывается, поэтому я получаювызов должен быть отменен, но как только устройство снова подключается к сети, кажется, что оно повторно отправляет текст или что-то подобное, этот текст остается в очереди, и я бы обработал его.
Вот мой метод, в котором я отправляютекст (я еще пытался использовать call.cancel () в onFailure, но это не имеет никакого эффекта)
@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();
}
});
}
В моем классе, где я создаю OkHttpClient, я установил retryOnConnectionFailure (false), но все ещене может решить проблему, что даже при сбое я получаю запрос POST.
ОБНОВЛЕНИЕ:
После некоторых исследований я обнаружил, что OkHttp делает тихую повторную попытку POST при сбое соединения.
Так, как я могу предотвратить клиентуповторить попытку?
НЕКОТОРАЯ ИНФОРМАЦИЯ:
Мое приложение - приложение для официанта, поэтому, когда я получаю сообщение onFailure
, я уведомляю официанта о том, что квитанция не поступила.не был получен POS и не был распечатан, но, поскольку OkHttpClient
все еще повторяет попытку отправки файла, и я заставляю официанта повторно отправить квитанцию после onFailure
, это вызывает печать дублированных квитанций.
Вот мой класс ApiUtils, интерфейс APIService и класс RetrofitClient
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;
}
}