На сегодняшний день если не все, то большинство Android-устройств имеют доступ к сети интернет. А большое количество мобильных приложений так или иначе взаимодействуют с средой интернет: загружают файлы, авторизуются и получают информацию с внешних веб-сервисов и т.д. Рассмотрим, как мы можем использовать в своем приложении доступ к сети интернет.
Среди стандартных элементов нам доступен виджет WebView, который может загружать контент с определенного url-адреса. Но этим возможности работы с сетью в Android не ограничиваются. Для получения данных с определенного интернет-ресурса мы можем использовать классы HttpUrlConnection (для протокола HTTP) и HttpsUrlConnection (для протокола HTTPS) из стандартной библиотеки Java.
Итак, создадим новый проект с пустой MainActivity. Первым делом для работы с сетью нам надо установить в файле манифеста AndroidManifest.xml соответствующее разрешение:
<uses-permission android:name="android.permission.INTERNET"/>
В файле activity_main.xml, который представляет разметку для MainActivity, определим следующий код:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/downloadBtn" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Загрузка" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <WebView android:id="@+id/webView" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/downloadBtn" app:layout_constraintBottom_toTopOf="@id/scrollView" /> <ScrollView android:id="@+id/scrollView" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/webView" app:layout_constraintBottom_toBottomOf="parent"> <TextView android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" /> </ScrollView> </androidx.constraintlayout.widget.ConstraintLayout>
Здесь определена кнопка для загрузки данных, а сами данные для примера загружаются одновременно в виде строки в текстовое поле и в элемент WebView. Так как данных может быть очень много, то текстовое поле помещено в элемент ScrollView.
Поскольку загрузка данных может занять некоторое время, то обращение к интернет-ресурсу определим в отдельном потоке и для этого изменим код MainActivity следующим образом:
package com.example.httpapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.webkit.WebView; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import javax.net.ssl.HttpsURLConnection; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView contentView = findViewById(R.id.content); WebView webView = findViewById(R.id.webView); webView.getSettings().setJavaScriptEnabled(true); Button btnFetch = findViewById(R.id.downloadBtn); btnFetch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { contentView.setText("Загрузка..."); new Thread(new Runnable() { public void run() { try{ String content = getContent("https://stackoverflow.com/"); webView.post(new Runnable() { public void run() { webView.loadDataWithBaseURL("https://stackoverflow.com/",content, "text/html", "UTF-8", "https://stackoverflow.com/"); Toast.makeText(getApplicationContext(), "Данные загружены", Toast.LENGTH_SHORT).show(); } }); contentView.post(new Runnable() { public void run() { contentView.setText(content); } }); } catch (IOException ex){ contentView.post(new Runnable() { public void run() { contentView.setText("Ошибка: " + ex.getMessage()); Toast.makeText(getApplicationContext(), "Ошибка", Toast.LENGTH_SHORT).show(); } }); } } }).start(); } }); } private String getContent(String path) throws IOException { BufferedReader reader=null; InputStream stream = null; HttpsURLConnection connection = null; try { URL url=new URL(path); connection =(HttpsURLConnection)url.openConnection(); connection.setRequestMethod("GET"); connection.setReadTimeout(10000); connection.connect(); stream = connection.getInputStream(); reader= new BufferedReader(new InputStreamReader(stream)); StringBuilder buf=new StringBuilder(); String line; while ((line=reader.readLine()) != null) { buf.append(line).append("\n"); } return(buf.toString()); } finally { if (reader != null) { reader.close(); } if (stream != null) { stream.close(); } if (connection != null) { connection.disconnect(); } } } }
Непосредственно для самой загрузки определен метод getContent()
, который будет загружать веб-страницу с помощью класса
HttpsURLConnection и возвращать код загруженной страницы в виде строки.
Вначале создается элемент HttpsURLConnection
:
URL url=new URL(path); connection =(HttpsURLConnection)url.openConnection(); connection.setRequestMethod("GET"); // установка метода получения данных -GET connection.setReadTimeout(10000); // установка таймаута перед выполнением - 10 000 миллисекунд connection.connect(); // подключаемся к ресурсу
После подключение происходит считывание со входного потока:
stream = connection.getInputStream(); reader= new BufferedReader(new InputStreamReader(stream));
Используя входной поток, мы можем считать его в строку.
Этот метод getContent()
затем будет вызываться в обработчике нажатия кнопки:
Button btnFetch = (Button)findViewById(R.id.downloadBtn); btnFetch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { contentView.setText("Загрузка..."); new Thread(new Runnable() { public void run() { try{ String content = getContent("https://stackoverflow.com/");
Поскольку загрузка может занять долгое время, то метод getContent()
в отдельном потоке с помощью объектов Thread и Runnable. Для примера в данном
случае обращение идет к ресурсу "https://stackoverflow.com/".
Запустим приложение и нажмем на кнопку. И при наличии интернета приложение загрузит гравную страницу с "https://stackoverflow.com/" и отобразит ее в WebView и TextView:
Конечно, данный способ вряд ли подходит для просмотра интернет-страниц, однако таким образом, мы можем получать какие-либо данные (не интернет-страницы) от различных веб-сервисов, например, в формате xml или json (например, различные курсы валют, показатели погоды), используя специальные api, и затем после обработки показывать их пользователю.