WebView — создай свой браузер
Android позволяет создать собственное окно для просмотра веб-страниц или даже создать свой клон браузера при помощи элемента WebView. Сам элемент использует движок WebKit и имеет множество свойств и методов. Мы ограничимся базовым примером создания приложения, с помощью которого сможем просматривать страницы в интернете. В последних версиях используется движок от Chromium, но большой разницы в этом нет для простых задач.
Создадим новый проект MyBrowser и сразу заменим код в файле разметки res/layout/activity_main.xml:
Теперь откроем файл активности MainActivity.java и объявим компонент WebView, а также инициализируем его — включим поддержку JavaScript и укажем страницу для загрузки.
Так как приложение будет использовать интернет, необходимо установить разрешение на доступ к интернету в файле-манифесте.
Там же в манифесте модифицируем строчку для экрана, удалив заголовок из нашего приложения (выделено жирным):
Запустим приложение. В нашем распоряжении появился простейший вьювер веб-страниц, но с одним недостатком. Если вы щёлкнете на любой ссылке, то у вас автоматически запустится браузер по умолчанию и новая страница отобразится уже там. Точнее так было раньше. На новых устройствах при запуске приложения сразу открывается браузер.
Чтобы решить данную проблему и открывать ссылки в своей программе, нужно переопределить класс WebViewClient и позволить нашему приложению обрабатывать ссылки. Добавим в коде вложенный класс:
Затем в методе onCreate() определим экземпляр MyWebViewClient. Он может находиться в любом месте после инициализации объекта WebView:
Теперь в нашем приложении создан WebViewClient, который позволяет загружать любой указанный URL, выбранный в WebView, в сам контейнер WebView, а не запускать браузер. За данную функциональность отвечает метод shouldOverrideUrlLoading(WebView, String), в котором мы указываем текущий WebView и нужный URL. Возвращаемое значение true говорит о том, что мы не нуждаемся в запуске стороннего браузера, а самостоятельно загрузим контент по ссылке. В версии API 24 добавили перегруженную версию метода, учитывайте это обстоятельство.
Повторно запустите программу и убедитесь, что ссылки загружаются теперь в самом приложении. Но теперь возникла ещё одна проблема. Мы не можем вернуться к предыдущей странице. Если мы нажмём на кнопку BACK (Назад) на своем устройстве, то просто закроем свое приложение. Для решения новой проблемы нам необходимо обрабатывать нажатие кнопки BACK. Добавляем новый метод:
Мы должны проверить, что WebView поддерживает навигацию на предыдущую страницу. Если условие верно, тогда вызывается метод goBack(), который возвращает нас на предыдущую страницу на один шаг назад. Если таких страниц набралось несколько, то мы можем последовательно вернуться к самой первой странице. При этом метод всегда будет возвращать значение true. Когда мы вернёмся на самую первую страницу, с которой начали путешествие по интернету, то вернётся значение false и обработкой нажатия кнопки BACK займётся уже сама система, которая закроет экран приложения.
Запустите приложение ещё раз. У вас появился свой собственный веб-браузер, позволяющий ходить по ссылкам и возвращаться на предыдущую страницу. Изучив документацию, вы можете оснастить приложение и другим вкусными плюшками для своего браузера.
Если вам нужно часть ссылок, ведущих на ваш сайт открывать в браузере, а локальные ссылки открывать в приложении, то применяйте условие с разными возвращаемыми значениями.
Универсальный метод, который все локальные ссылки откроет в приложении, остальные в браузере (меняем одну строчку):
А сейчас немного усложним пример, чтобы у пользователя появилась альтернатива стандартным браузерам.
Чтобы было понятнее, переделаем пример следующим образом. Создайте две активности. На первой активности разместите кнопку для перехода на вторую активность, а на второй активности разместите компонент WebView.
В манифесте прописываем у второй активности фильтр.
Код для кнопки для перехода на вторую активность.
Мы создали собственное намерение с указанием фильтра и предоставили данные — адрес сайта.
Вторая активность должна принять данные:
В фильтре для второй активность мы указали два действия.
Это означает, что любые активности (читай, приложения) могут вызвать вашу активность с мини-браузером по такому же принципу. Запустите в студии в отдельном окне любой старый проект или создайте новый и добавьте в него кнопку и пропишите тот же код, который мы использовали для щелчка кнопки.
Запустите второе приложение (первое приложение можно закрыть) и нажмите на кнопку. У вас запустится не первое приложение с начальным экраном, а сразу вторая активность с мини-браузером. Таким образом, любое приложение может запустить браузер, не зная имени класса вашей активности, а используя только строку «ru.alexanderklimov.Browser», передаваемую в Intent. При этом ваша активность с браузером должна иметь категорию по умолчанию и данные. Напомню:
Вы можете представить свою строку в виде строковой константы и сообщить всем потенциальным пользователям вашего браузера, как они могут запустить его у себя. Но в Android уже есть такая готовая константа ACTION_VIEW, которая по справке документации представляет собой следующее:
Перепишем код для кнопки у второго приложения
Что произойдёт на этот раз? Мы помним, что у нас прописано два действия, включая и android.intent.action.VIEW. А значит наше первое приложение с браузером тоже должно распознавать эту команду, когда какое-то приложение у пользователя использует этот код. На эмуляторе как минимум есть одна такая программа «Browser», и теперь к ней добавилась наша вторая активность из первого приложения. На экране появится выбор из двух приложений.
А если удалить все альтернативные браузеры и оставить только вашу программу, то и выбора не будет. Ваш браузер станет основным. И если какое-то приложение захочет запустить веб-страницу указанным способом, то откроется ваша программа.
Небольшое замечание. Если заменить последнюю строчку на такую:
То в окне выбора программы вместо верхней строки «Open with» или её локального перевода появится ваша строка. Но не это главное. Если по каким-то причинам на устройстве не окажется ни одного браузера, то данный вариант кода не вызовет краха приложения, в отличие от первоначального варианта. Поэтому используйте предложенный вариант ради надёжности.
Источник статьи: http://developer.alexanderklimov.ru/android/mybrowser.php
Полный список
На прошлом уроке мы увидели, что если вызвать Intent с action = ACTION_VIEW и data = Uri-объект с http-адресом, то запускается браузер и отображает содержимое страницы по этому http-адресу. Мы можем самостоятельно сделать простейший браузер, который будет реагировать на такой Intent и просто отобразит страницу. Для этого надо настроить Intent Filter и использовать компонент WebView.
На первом экране приложения у нас будет кнопка, отправляющая Intent. На втором экране будет WebView.
Project name: P0321_SimpleBrowser
Build Target: Android 2.3.3
Application name: SimpleBrowser
Package name: ru.startandroid.develop.p0321simplebrowser
Create Activity: MainActivity
Код немного непривычен. Обратите внимание я нигде не описываю объект класса Button. Метод findViewById возвращает View, и это View поддерживает метод setOnClickListener, который я вызываю. А в методе setOnClickListener я создаю объект, реализующий интерфейс OnClickListener и в нем пишу код в onClick. Также я создаю объект Intent не отдельно, а прямо в методе startActivity. Кода меньше получилось, чем обычно. Может быть вам подойдет такой вариант.
Итак, мы по нажатию на кнопку запускаем Intent, который означает, что мы хотим просмотреть сайт http://www.ya.ru.
Создадим второе Activity. Сначала layout-файл browser.xml:
На экране компонент WebView.
Определяем WebView, читаем data из Intent и передаем строку в WebView.
Теперь пропишем Activity в манифесте. К нему нам надо будет добавить Intent Filter, в нем указать action = ACTION_VIEW. А для data мы видим несколько параметров, используем Scheme = http.
Это значит, что Uri объект в Intent должен содержать http-адрес.
Не забываем про Category = Default. Label для BrowserActivity укажите, например, MyBrowser.
Также в манифесте надо добавить Uses Permission = android.permission.INTERNET на вкладке Permissions. Чтобы система дала приложению доступ в интернет.
Все сохраним и запустим приложение. Жмем кнопку и видим выбор: система предлагает нам на выбор системный браузер и наш, только что сделанный. Т.е. Intent c запросом на просмотр http-адреса нашел в системе два Activity, которые в своих Intent Filter заявили, что умеют отображать http-адреса.
Выбираем наше MyBrowser и видим страницу.
Мы увидели, что Activity в наших приложениях могут обрабатывать не только наши придуманные action, но и системные. И, тем самым, создавать альтернативу системным приложениям.
Но, как вы понимаете, мы запросто могли в нашем Activity не использовать WebView и не показывать страницу. Можно было использовать TextView и в нем просто отобразить в виде текста адрес из data. Или накодить http-запрос, который скачал бы эту страницу и отобразил ее html-содержимое. Мы могли вообще забить на http-адрес и показать какую-нибудь картинку левую или просто темный экран.
Т.е. для Activity можно создать Intent Filter, который будет сообщать системе, что приложение умеет что-то, но, при этом, внутри Activity будет какая-нибудь ерунда. Это уже вопросы программерской этики, здравого смысла и адекватности )
— хранение данных с помощью Preferences
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник статьи: http://startandroid.ru/ru/uroki/vse-uroki-spiskom/72-urok-32-pishem-prostoj-brauzer.html
Урок 32. Создаем простое приложение — интернет браузер для андроид | Уроки Android Studio
В этом уроке вы увидите, как сделать простейший браузер, который отобразит страницу в интернете по http-адресу. Для этого надо создать Intent, настроить Intent Filter и использовать WebView.
Исходный код классов — под видео:
Уроки Android Studio: тут
Инструменты android разработчика: тут
Дизайн android приложений: тут
Уроки создания игр для android: тут
Основы программирования на JAVA: тут
Привет. Спасибо за урок. У мне вопрос. Я разработал приложение оно работает хорошо. В моем сайте есть форма где пользователь заполняет. То есть загружает фото. В приложение не получается.
Я попробовал в системном приложение браузере работает. Вопрос как надо делать что бы в нашем приложение пользователь смог загрузить и скачать, как других браузерах.
Здравствуйте!
Подскажите, пожалуйста, есть ли решение, благодаря которому, при невозможности загрузки страницы (например, если сервер не отвечает, или отсутствует подключение) срабатывал определенный код, например, открывающий новое активити или выводящий сообщение?
В приложении на базе webview очень «не комильфо» получается, когда вылазит стандартная страница Хрома об ошибке.
Большое спасибо заранее!
Виталий спс за уроки, нравится по ним заниматься, пугает что будет когда они закончатся))) Мой вопрос вот в чем, хочу узнать String action других приложений,которые у меня на планшете(samsung galaxy tab 4.4.2 на котором я и веду отладку) — пытаюсь через pc залезть в планшет и найти хоть какое-нибудь приложение,расковырять от туда манифест но не могу найти загруж приложения, даже папку system искал поисковиком — винда пишет объекты не найдены в Tablet, в папке data(Tabletdatadatacom.sec.android.app.FileShareServerfiles) только два xml файла — описание устройства и файлтранспорт) — а должно быть кроме установленных ещё около 30 прилжений(после отладки по вашим урокам в ютубе остаются на планшете) Где они?) может без рут прав мне просто не показывают все дерево папок…
При переходе на активность браузера выбираю свою activity_web, после перехода предлагает снова выбрать приложение для открытия (хром, родной браузер). не получилось чего-то, объясните чайнику
Для отправки комментария вам необходимо авторизоваться.
Источник статьи: http://www.fandroid.info/urok-32-sozdaem-prostoe-prilozhenie-internet-brauzer-dlya-android-uroki-android-studio/
Простой клиент-сервер на Android (интернет-мессенджер)
Важно. Все написанное ниже не представляет собой какой либо ценности для профессионалов, но может служит полезным примером для начинающих Android разработчиков! В коде старался все действия комментировать и логировать.
Поехали. Многие мобильные приложения (и не только) используют архитектуру клиент-сервер. Общая схема, думаю, понятна.
Уделим внимание каждому элементу и отметим:
- сервер — представляет собой некую программу, работающую на удаленном компьютере, и реализующую функционал «общения» с приложениями-клиентами (слушает запросы, распознает переданные параметры и значения, корректно отвечает на них);
- клиент — в нашем случае, программа на мобильном устройстве, которая умеет формировать понятный серверу запрос и читать полученный ответ;
- интерфейс взаимодействия — некий формат и способ передачи/получения запросов/ответов обеими сторонами.
Неважно, как реализован любой из этих элементов, все они в любом случае присутствуют. Давайте реализуем примитивный сервер и Android клиент, работающий с ним. Как пример, будем использовать любой популярный мобильный интернет-мессенджер (Viber, ICQ), а приложение условно назовем «интернет-чат».
Схема взаимодействия следующая:
Клиент, установленный на устройстве А, посылает сообщение для клиента, установленного на устройстве Б. И наоборот. Сервер играет роль связующего звена между устройством А и Б… С, Д… и т.д. Также он играет роль «накопителя» сообщений, для их восстановления, на случай удаления на одном из клиентских устройств.
Для хранения сообщений используем SQL БД как на сервере, так и на устройствах-клиентах (в принципе, вся работа клиентов интернет-мессенджеров и сводится к постоянной синхронизации локальной и удаленной БД с сообщениями). Дополнительно, наш интернет-чат будет уметь стартовать вместе с запуском устройства и работать в фоне. Взаимодействие будет происходить путем HTTP запросов и JSON ответов.
Более логично, если синхронизация происходит через порт/сокет, это с одной стороны упрощает задачу (не нужно циклично слать HTTP запросы на проверку новых сообщений, достаточно проверять состояние прослушиваемого сокета), но с другой стороны, это усложняет создание серверной части приложения.
Делаем сервер
Для реализации «сервера», нам нужно зарегистрироваться на любом хостинге, который дает возможность работы с SQL и PHP.
Создаем пустую SQL БД, в ней создаем таблицу.
- author — автор сообщения;
- client — получатель сообщения;
- data — время и дата получения сообщения на сервере;
- text — сообщение.
В двух следующих файлах необходимо изменить переменные, содержащие данные для доступа к БД, на свои, полученные Вами при регистрации Вашего«сервера».
- обязательный атрибут action — может быть равен select (сервер ответит списком записей из своей БД), insert (сервер добавить новую запись в свою БД), delete (сервер очистит свою БД)
- если action=insert, нам нужно будет передать дополнительные параметры: author (кто написал сообщение), client (кому адресовано сообщение), text (сообщение)
- action=select может содержать дополнительный параметр data, в этом случае ответ сервера содержит не все сообщения из БД, а только те, у которых время создания позднее переданного
Примеры:
- chat.php?action=delete – удалит все записи на сервере
- chat.php?action=insert&author=Jon&client=Smith&text=Hello — добавит на сервере новую запись: автор Jon, получатель Smith, содержание Hello
- chat.php?action=select&data=151351333 — вернет все записи, полученные после переданного времени в long формате
Клиентская часть
Теперь структура Android приложения:
В фоне работает FoneService.java, который, в отдельном потоке, каждые 15 секунд делает запрос на сервер. Если ответ сервера содержит новые сообщения, FoneService.java записывает их в локальную БД и отправляет сообщение ChatActivity.java о необходимости обновить ListView, с сообщениями. ChatActivity.java (если она в этот момент открыта) получает сообщение и обновляет содержимое ListView из локальной БД.
Отправка нового сообщения из ChatActivity.java происходит сразу на сервер, минуя FoneService.java. При этом наше сообщение НЕ записывается в локальную БД! Там оно появится только после получения его назад в виде ответа сервера. Такую реализацию я использовал в связи с важным нюансом работы любого интернет-чата — обязательной группировкой сообщений по времени. Если не использовать группировку по времени, будет нарушена последовательность сообщений. Учитывая, что клиентские приложения просто физически не могут быть синхронизированы с точностью до миллисекунд, а возможно будут работать даже в разных часовых поясах, логичнее всего будет использовать время сервера. Так мы и делаем.
Создавая новое сообщение, мы передаем запросом на сервер: имя автора сообщения, имя получателя сообщения, текст сообщения. Получая эту запись назад, в виде ответа сервера, мы получаем то, что отправляли + четвертый параметр: время получения сообщения сервером.
Источник статьи: http://habr.com/ru/post/269135/