Как использовать HttpURLConnection в приложении для Android?

avatar
BenjaminFB
9 августа 2021 в 00:18
212
2
0

У меня проблема в приложении Android.
Я использую портал входа, сгенерированный действием Активность входа, и хочу отправить имя пользователя и пароль в свой веб-API. Поэтому я создал класс Java, который использует HttpURLConnection для связи с моим API. Этот класс был протестирован (с Netbeans), и все работает отлично!
Но когда я вызываю свою функцию, которая подключается к API в моем приложении для Android, ничего, любой запрос не отправляется. Я добавил разрешение на Интернет в androidManifest, всегда ничего

androidManifest.xml :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ben.myapp">
    <!-- Autorisation -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
.....
</manifest>

Мой класс Java:

public static String verifyLoginAndGetData (String userMail, String userPassword) throws IOException  {
           URL urlGetRequest = new URL("http://my.api.com/index?param1...");
           // HTTP Connexion
            HttpURLConnection apiConnexion = (HttpURLConnection) urlGetRequest.openConnection();
            // Method
            apiConnexion.setRequestMethod("GET");

            try {
                // Response code
                int responseCode = apiConnexion.getResponseCode();

                if (responseCode == HttpURLConnection.HTTP_OK) {
                    // Read the response
                    BufferedReader in = new BufferedReader(new InputStreamReader(apiConnexion.getInputStream()));
                    StringBuffer response = new StringBuffer();
                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();

                    // Return response
                    return response.toString();

                } else {
                    return "false";
                }

            } finally {
                apiConnexion.disconnect();
            }

        } catch (Exception e){
            Log.i("Exception", e.toString());
            return "false";
        }

Где я вызываю эту функцию:

public class LoginDataSource {
     public Result<LoggedInUser> login(String username, String password) {
          String resultAPI = my_class.verifyLoginAndGetData(username, password);
     }
}

переменные имя пользователя и пароль не пусты.

что я должен использовать? Или что мне делать?
Спасибо за помощь мне :)
БенджаминFB

Источник
Tippu Fisal Sheriff
9 августа 2021 в 01:12
0

Используйте рекомендованную библиотеку Retrofit для полного API REST.

Ответы (2)

avatar
BenjaminFB
12 августа 2021 в 18:20
0

Да, работает!!
Я сделал то, что сказал мне @code-demon:
Добавить в манифест

android:usesCleartextTraffic="true"

И использовать thred, но я не смог получить никакого значения из ответа API, поэтому я провел исследование и наткнулся на него: coderhelper post.
Наконец я понял, что:

ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> callable = new Callable<String>() {
      @Override
      public String call() throws IOException {
            // Call my API get function
            return verifyLoginAndGetData(username, password);
      }
};
Future<String> future = executor.submit(callable);
executor.shutdown();
// Get in String, the API response
String resultAPI = future.get();
avatar
Code Demon
9 августа 2021 в 01:35
0

Прежде всего, запустите это в отдельном потоке от пользовательского интерфейса, если это еще не сделано, для этого идентификатора сделайте это

new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Log.e("Download ",verifyLoginAndGetData("username","password"));
                    } catch (IOException e) {
                        Log.e("Exception ",""+e.getMessage());
                    }


                }
            }).start();
  • Следующая вещь. Я не уверен насчет API, с которым вы имеете дело, независимо от идентификатора рекомендуется использовать файл конфигурации сети, чтобы разрешить трафик открытого текста ваш сайт, если он использует трафик в открытом виде, и укажите это в своем приложении в манифесте.

  • Еще одно, помните о разрешении на доступ к Интернету в вашем манифесте

Кроме этого, для меня это работает с URL-адресом Google www.google.com с помощью get

  public static String verifyLoginAndGetData (String userMail, String userPassword) throws IOException {
    URL urlGetRequest = new URL("http://www.google.com");
    // HTTP Connexion
    HttpURLConnection apiConnexion = (HttpURLConnection) urlGetRequest.openConnection();
    // Method
    apiConnexion.setRequestMethod("GET");

    try {
        // Response code
        int responseCode = apiConnexion.getResponseCode();

        if (responseCode == HttpURLConnection.HTTP_OK) {
            // Read the response
            BufferedReader in = new BufferedReader(new InputStreamReader(apiConnexion.getInputStream()));
            StringBuffer response = new StringBuffer();
            String inputLine = null;

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // Return response
            return response.toString();

        } else {
            return "false";
        }

    } finally {
        Log.e("Disconnection", "e.toString()");
        apiConnexion.disconnect();
    }


}

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

  interface data_inter{
    void onDataReceived(String data);
}
data_inter inter=new data_inter() {
    @Override
    public void onDataReceived(String data) {
        Log.e("Downloaded: ",data);
        Toast.makeText(cntx,"Downloaded: "+data,Toast.LENGTH_LONG).show();
        ((EditText)findViewById(R.id.focuser)).setText("Downloaded: "+data);
    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    cntx=this;
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                String responce=verifyLoginAndGetData("","");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        inter.onDataReceived(responce);
                    }
                });

            } catch (IOException e) {
                Log.e("Exception ",""+e.getMessage());
            }


        }
    }).start();}
BenjaminFB
9 августа 2021 в 10:16
0

О, спасибо, это работа! Я добавляю android:usesCleartextTraffic="true" в <a приложение> из манифеста, и вызов запроса в потоке отправляется отлично. Но теперь, как я могу вернуть значения ответа API потока?