Android Studio GET-запрос java

133
08 декабря 2021, 01:20

Проблема такая: На главном активити у меня есть кнопка. По нажатмю на неё я запускаю сканнер QR от ZXING, считываю сам код и сохраняю его. Перехожу обратно в приложение. Далее у меня идёт метод, который должен отправить GET запрос к серверу и получить ответ. Затем ответ вывести с помощью toast. Сделал как ИНВАЛИД, но мне многого и не нужно.

Что происходит: QR считывается (проверял), при вызове метода с GET запросом приложение просто сворачивается (в списке запущенных оно есть, а переходить в него сам - не хочет. Без метода с GET - нормально переходит после считывания QR). Не использовал ни асинхронный способ ни потоки (всё делаю в одном как ИНВАЛИД). Мне совсем не понятно как этим пользоваться и нужно ли оно вообще, кроме как "так лучше" и т.д.

Вот сам метод:

public void SendToBase()
{

    URL url;
    HttpsURLConnection connection = null;
    try {
        url = new URL("https://mysite.com/mainapi.php?test=test");
        connection = (HttpsURLConnection) url.openConnection();
        BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));

        String line = br.readLine();
        //Log.d("HTTP-GET", line);
        Toast toast = Toast.makeText(this, "Ответ: " + line, Toast.LENGTH_LONG);
        toast.show();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
    }

}

А вот всё вместе (с вызовом этого метода после сканирования):

public class MainActivity extends Activity {
static final String ACTION_SCAN = "com.google.zxing.client.android.SCAN";
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //SendToBase();//это потом удалить отсюда. Просто для теста вызываю тут
}
// Запускаемм сканер штрих кода:
public void scanBar(View v) {
    try {
        // Запускаем переход на com.google.zxing.client.android.SCAN с помощью intent:
        Intent intent = new Intent(ACTION_SCAN);
        intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
        startActivityForResult(intent, 0);
    } catch (ActivityNotFoundException anfe) {
        // Предлагаем загрузить с Play Market:
        showDialog(MainActivity.this, "Сканнер не найден", "Установить сканер с Play Market?", "Да", "Нет").show();
    }
}
// Запуск сканера qr-кода:
public void scanQR(View v) {
    try {
        // Запускаем переход на com.google.zxing.client.android.SCAN с помощью intent:
        Intent intent = new Intent(ACTION_SCAN);
        intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
        startActivityForResult(intent, 0);
    } catch (ActivityNotFoundException anfe) {
        // Предлагаем загрузить с Play Market:
        showDialog(MainActivity.this, "Сканнер не найден", "Установить сканер с Play Market?", "Да", "Нет").show();
    }
}
// alert dialog для перехода к загрузке приложения сканера:
private static AlertDialog showDialog(final Activity act, CharSequence title,
                                      CharSequence message,CharSequence buttonYes, CharSequence buttonNo) {
    AlertDialog.Builder downloadDialog = new AlertDialog.Builder(act);
    downloadDialog.setTitle(title);
    downloadDialog.setMessage(message);
    downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialogInterface, int i) {
            // Ссылка поискового запроса для загрузки приложения:
            Uri uri = Uri.parse("market://search?q=pname:" + "com.google.zxing.client.android");
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            try {
                act.startActivity(intent);
            } catch (ActivityNotFoundException anfe) {
            }
        }
    });
    downloadDialog.setNegativeButton(buttonNo, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialogInterface, int i) {
        }
    });
    return downloadDialog.show();
}
// Обрабатываем результат, полученный от приложения сканера:
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (requestCode == 0) {
        if (resultCode == RESULT_OK) {
            // Получаем данные после работы сканера и выводим их в Toast сообщении:
            String contents = intent.getStringExtra("SCAN_RESULT");
            String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
            //Toast toast = Toast.makeText(this, "Содержание: " + contents + " Формат: " + format, Toast.LENGTH_LONG);
            //toast.show();
            SendToBase();
        }
    }
}

А вот разрешения в манифесте:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

API использую минимум 22, запускаю на Redmi 3s (Android 6.0.1)

под андроид пробую создать приложение впервые. Запуска эмулятора ждал 2 часа - плюнул. Что с этим делать - тоже не знаю. Поэтому делаю элементарно: компилю, копирую на у-во и смотрю работает ли... Но как только доходит до вызова метода с GET запросом - свернулся (или вылетил). Вообще, я собираюсь отправить QR в этом самом запросе, но сейчас хочу хоть тест отправить.

Answer 1

В Android есть особенность: http запросы должны выполняться не в главном потоке, иначе будет приложение падать с ошибкой NetworkOnMainThreadException.

То есть часть метода SendToBase, которая выполняет запрос и получает ответ, нужно выполнить в другом потоке, а отображение результата в главном потоке. Сделать это можно, например, так:

public void SendToBase()
{
    new Thread(new Runnable() {
        @Override
        public void run() {
            URL url;
            HttpsURLConnection connection = null;
            try {
                url = new URL("https://mysite.com/mainapi.php?test=test");
                connection = (HttpsURLConnection) url.openConnection();
                BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line = br.readLine();
                //Log.d("HTTP-GET", line);
                new Handler(Looper.getMainLooper()).post(() -> {
                    Toast toast = Toast.makeText(MainActivity.this, "Ответ: " + line, Toast.LENGTH_LONG);
                    toast.show();
                });
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }
    }).start();
}
READ ALSO
Морфинг маски на растровом изображении

Морфинг маски на растровом изображении

Вопрос инициирован топиком: Плавный морфинг одного path в другой path

131
Новичок в bootstrap, есть пара проблем

Новичок в bootstrap, есть пара проблем

решил читься верстать на bootstrap, но сразу возникло пару проблем

118
stl: не удаётся сделать emplace_back в вектор

stl: не удаётся сделать emplace_back в вектор

Подскажите в чем может быть проблема:

104