Я создал сервис, который извлекает контакты из имени устройства Android, номера мобильного телефона и электронной почты и сохраняет их в списке массивов с пользовательским объектом контактов.У меня 20 000 контактов в моем устройстве.Я конвертирую этот список массивов в массив JSON, используя Gson.И я отправляю данные на сервер, но запрос не выполняется.Если я отправляю небольшое количество данных, то API дает успешный ответ.Я хочу знать, почему я не могу получить успешный запрос, когда есть большие данные в формате JSON.Это пример формата данных, которые я отправлю на сервер
[
{
"Name": "FirstName Lastname",
"Phone": "[+123456789012]"
},
{
"Name": "FirstName Lastname",
"Phone": "[+123456789012, +123456789012, +123456789012]",
"Email": "abcd@gmail.com"
},
{
"Name": "FirstName Lastname",
"Phone": "[+123456789012]"
},
{
"Name": "FirstName Lastname",
"Phone": "[]"
}
]
Это трассировка стека печати, которую я получаю
06-25 17: 32: 21.816 19421-20008 / D / OkHttp: <- HTTP FAILED: javax.net.ssl.SSLException: Ошибка записи: ssl = 0x40d92618: ошибка ввода-вывода во время системного вызова, сломанный канал 06-25 17: 32: 21.826 19421-19421 / W / System.err:javax.net.ssl.SSLException: Ошибка записи: ssl = 0x40d92618: ошибка ввода-вывода во время системного вызова, сломанный канал 06-25 17: 32: 21.856 19421-19421 / W / System.err: at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_write (собственный метод) в org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl $ SSLOutputStream.write (OpenSSLSocketImpl.java:719) в okio.Okio $ 1.java:79) в okio.AsyncTimeout $ 1.write (AsyncTimeout.java:180) в okio.RealBufferedSink.emitCompleteSegments (RealBufferedSink.java:179) в okio.RealBufferedSink.writeUtf8 (RealBufferedSink.jtthp.phttp..writeRequest (Http1Codec.java:172) по адресу okhttp3.internal.http1.Http1Codec.writeRequestHeaders (Http1Codec.java:130) по адресу okhttp3.internal.http.CallServerInterceptor.intercept (CallServerInterceptor.java:50) по адресу okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.kh.intercept (ConnectInterceptor.java:45) в okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:147) </p>
Вот мой сервисный код, который выполняет все действия.
public class ContactService extends Service {
String strDate;
@Nullable
CompositeDisposable mDisposable = null;
private UploadContactsUseCase mUploadContactsUseCase;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Date date = Calendar.getInstance().getTime();
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
//to convert Date to String, use format method of SimpleDateFormat class.
strDate = dateFormat.format(date);
new GetContacts().execute();
stopSelf();
// I don't want this service to stay in memory, so I stop it
// immediately after doing what I wanted it to do.
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
if (mDisposable != null) {
mDisposable.dispose();
mDisposable = null;
}
// I want to restart this service again.
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1),
PendingIntent.getService(this, 0, new Intent(this, ContactService.class), 0));
}
private JSONArray displayContacts() {
int j = 1;
List<ContactUser> contactUserList = new ArrayList<ContactUser>();
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cur != null && cur.getCount() > 0) {
while (cur.moveToNext()) {
Log.i("COUNT: ", String.valueOf(j++));
List<String> listPhones = new ArrayList<String>();
ContactUser contactUser = new ContactUser();
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contactUser.setName(name);
if (Integer
.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)))
> 0) {
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
while (pCur != null && pCur.moveToNext()) {
String phoneNo = pCur
.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// Toast.makeText(NativeContentProvider.this, "Name: " + name + ", Phone No: " + phoneNo, Toast.LENGTH_SHORT).show();
// Log.i("Contact", name + " " + ":" + " " + phoneNo);
listPhones.add(phoneNo);
// mStoreContacts.add(name + " " + ":" + " " + phoneNo);
}
if (pCur != null) {
pCur.close();
}
}
// get the user's email address
String email = null;
Cursor ce = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id}, null);
if (ce != null && ce.moveToFirst()) {
email = ce.getString(ce.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
// mStoreContacts.add(name + " " + ":" + " " + email);
ce.close();
}
String[] array = listPhones.toArray(new String[0]);
contactUser.setPhone(Arrays.toString(array));
contactUser.setEmail(email);
contactUserList.add(contactUser);
}
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < contactUserList.size(); i++) {
jsonArray.put(contactUserList.get(i).getJSONObject());
}
if (cur != null) {
cur.close();
}
return jsonArray;
}
if (cur != null) {
cur.close();
}
return null;
}
class GetContacts extends AsyncTask<Void, Void, JSONArray> {
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(ContactService.this, "Starting reading contacts", Toast.LENGTH_SHORT).show();
}
@Override
protected JSONArray doInBackground(Void... voids) {
JSONArray contacts = displayContacts();
return contacts;
}
@Override
protected void onPostExecute(final JSONArray contact) {
super.onPostExecute(contact);
// new JobTask(contact).execute();
try {
Log.i("Contacts:", contact.toString(2));
} catch (JSONException e) {
e.printStackTrace();
}
mDisposable = new CompositeDisposable();
mUploadContactsUseCase = new UploadContactsUseCaseImpl();
mDisposable.add(mUploadContactsUseCase
.execute(Preferences.getInstance().getUserEmail(), contact.toString())
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action() {
@Override
public void run() throws Exception {
// handle completion
Toast.makeText(ContactService.this, "Complete", Toast.LENGTH_SHORT).show();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
throwable.printStackTrace();
// handle error
Toast.makeText(ContactService.this, throwable.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}));
}
}
}
Это мой сетевой менеджер класса Retrofit
public class NetworkManager {
/**
* The Constant CONNECTION_TIMEOUT_TIME.
*/
private static final long CONNECTION_TIMEOUT_TIME = 30;
private static final String CURRENT_LANG =
Locale.getDefault().getLanguage().toString() + "-" + Locale.getDefault().getCountry();
private static final String GZIP_DEFLATE = "gzip,deflate";
/**
* The Constant ACCEPT_ENCODING.
*/
private static final String ACCEPT_ENCODING = "Accept-Encoding";
/**
* The Constant CONTENT_TYPE.
*/
private static final String CONTENT_TYPE = "Content-Type";
/**
* The Constant APPLICATION_JSON.
*/
private static final String APPLICATION_JSON = "application/json";
private static final String BASE_URL = "https://mybaseurl.in";
private static SafecodeApiService sInstanceV2 = null;
private static SafecodeApiService sInstanceV2_1 = null;
public static SafecodeApiService getService() {
if (sInstanceV2 == null) {
OkHttpClient client = getHttpClient();
sInstanceV2 = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(GsonFactory.create())).client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build()
.create(SafecodeApiService.class);
}
return sInstanceV2;
}
@NonNull
private static OkHttpClient getHttpClient() {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return new OkHttpClient.Builder().followRedirects(true).followSslRedirects(true)
.retryOnConnectionFailure(true).connectTimeout(CONNECTION_TIMEOUT_TIME, TimeUnit.SECONDS)
.writeTimeout(CONNECTION_TIMEOUT_TIME, TimeUnit.SECONDS)
.readTimeout(CONNECTION_TIMEOUT_TIME, TimeUnit.SECONDS)
.readTimeout(CONNECTION_TIMEOUT_TIME, TimeUnit.SECONDS).cache(null)
.addInterceptor(loggingInterceptor).addInterceptor(new ResponseInterceptor()).build();
}
private static class ResponseInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
try {
Request original = chain.request();
Request request = original.newBuilder().addHeader(CONTENT_TYPE, APPLICATION_JSON)
.addHeader("Connection", "Keep-Alive").addHeader(ACCEPT_ENCODING, GZIP_DEFLATE)
.method(original.method(), original.body()).build();
Response response = chain.proceed(request);
String rawJson = response.body().string();
Log.i("RESPONSE: ", String.format("raw JSON response is: %s", rawJson));
switch (response.code()) {
case HttpURLConnection.HTTP_OK:
// Re-create the response before returning it because body can be read only once
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), rawJson)).build();
case HttpURLConnection.HTTP_UNAVAILABLE:
throw new MaintenanceException("Service Unavailable.");
default:
break;
}
return response;
} catch (SocketTimeoutException exception) {
throw new SocketTimeoutException("timeout");
}
}
}
private static class MaintenanceException extends RuntimeException {
public MaintenanceException(String message) {
super(message);
}
}
}