Модернизация не может выполнять запросы

#java #android #retrofit

#java #Android #модернизация

Вопрос:

Я выполнял запросы post на свой локальный сервер (на основе express), и я использую модернизацию для отправки сообщений на IP-адрес моего ПК и на оба устройства (Android и ПК подключены через точку доступа). Раньше это работало довольно хорошо, но теперь я сменил свое устройство на новое устройство, работающее на Android 10, и теперь оно перестало работать. И еще одна вещь, на которую следует обратить внимание, это то, что в Logcat нет ошибок, и когда я захожу в Chrome (Android) и выполняю запрос GET, он работает.

Вот как я выполняю запрос post

         retrofit = retro.getRetrofit();
        Data token = new Data();
        token.setToken("Anything");

        retroInterface service = retrofit.create(retroInterface.class);


        Call<Data> call = service.postToken(token);

        call.enqueue(new Callback<Data>() {
            @Override
            public void onResponse(Call<Data> call, Response<Data> response) {
                
                Toast.makeText(MainActivity.this,"Post done",Toast.LENGTH_SHORT).show();
                
            }

            @Override
            public void onFailure(Call<Data> call, Throwable t) {

            }
        });
  

Вот как я создаю модифицированный объект из класса retro

 import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class retro {
    private static final String BASE_URL = "http://192.168.43.72:3000";
private static Retrofit retrofit = null;

public static Retrofit getRetrofit() {
   if(retrofit == null){
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

   }
   return retrofit;
    }
}
  

Вот мой класс данных

 public class Data {
public String token;


public String getToken() {
    return token;
}

public void setToken(String token) {
    this.token = token;
}
}
  

Вот модифицированный интерфейс

   import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;

public interface retroInterface {
    @POST("/login")
    Call<Data> postToken(@Body Data data );

    @POST("/login")
    Call<username> postUsername(@Body username user);

    @POST("/userAvail")
    Call<username> checkUsername(@Body username user);
}
  

Комментарии:

1. Вы пытались войти в систему из метода OnFailure?

2. НиколаГаллацци Он передает мне сообщение ОТКРЫТЫМ ТЕКСТОМ на адрес 192.168.43.72, что не разрешено политикой сетевой безопасности

Ответ №1:

Я нашел ответ на это, что, поскольку я перешел с Android 8 на 10, мне нужно добавить android:usesCleartextTraffic="true" в свой файл манифеста, чтобы выполнять запросы.

Комментарии:

1. Пожалуйста, не забудьте удалить эту строку перед публикацией.

Ответ №2:

Devil TM правильно определил, что устройства Android 10 блокируют простые http соединения. При добавлении

 android:usesCleartextTraffic="true"
  

в этом случае манифест разблокирует вас для продолжения разработки, это очень опасно, и есть риск, что он превратится в опубликованное приложение.

Лучше устранить основную проблему — незашифрованное соединение — чем просто сказать приложению игнорировать его и продолжать.

Этого можно достичь двумя способами — выдать самозаверяющий сертификат и сообщить приложению доверять вашему сертификату — или получить выданный реальный сертификат. Здесь есть много вопросов и ответов о том, как заставить приложение доверять самозаверяющему сертификату, а документация находится в документах разработчика Android. Я не собираюсь описывать этот сценарий.

Другой способ — получить настоящий сертификат. Вы, конечно, могли бы купить его, но кто хочет сделать это для сайта разработки. Я предполагаю, что OP выполняет «разработку спальни» и все связанные с этим проблемы (без фиксированного IP и т. Д.). Чтобы получить зашифрованное соединение, вам необходимо;

  • Настройте провайдера DYNDNS так, чтобы он указывал на ваш домашний IP-адрес
  • Выберите поддомен любого домена, который у вас есть, и создайте CNAME запись, указывающую на ваш адрес DNYDNS
  • Настройте переадресацию портов на маршрутизаторе для маршрутизации 80 и 443 на сервер
  • Настройте сервер с конфигурацией vhost для обслуживания правильного сайта при запросе поддомена
  • Установите и запустите letsencrypt инструмент и попросите его выдать сертификат для поддомена на вашем сервере

Теперь у вас установлен бесплатный настоящий SSL-сертификат, и Android будет использовать соединение вполне успешно.

Если вы не хотите, чтобы сервер разработки постоянно был подключен к Интернету, вы можете удалить переадресацию портов (но для этого потребуется настроить HOSTS файл для сопоставления домена с IP-адресом сервера). Вам нужно будет только предоставлять доступ к серверу каждые 3 месяца, чтобы обновить ваш сертификат.