Пишем полноценный браузер под Aндроид. WebView - создай свой браузер Добавление разрешений в манифест

Мы уже начали полноценно обеспечивать себя личным софтом, вспомните наши чудесные калькулятор и конвертер. И в этом уроке мы научимся создавать простой браузер, с помощью которого будет бороздить просторы интернета. Согласитесь, серфить сеть на своем собственном браузере - это в разы приятнее чем делать это на Opera или Chrome (вряд ли удобнее, но приятнее:)). Создаем новый проект, названия традиционно выбирайте сами. Лично я вообще не создаю каждый раз все с нуля, а просто открываю, что есть, и зачищаю весь код до исходного состояния Blank Activity. Делайте, как вам удобней.

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

Начнем. Открываем файл activity_main.xml . Создаем там один единственный элемент , которого нам вполне достаточно для реализации веб-обозревателя:

< WebView xmlns: android= "http://schemas.android.com/apk/res/android" android: layout_height= "match_parent" android: layout_width= "match_parent" android: id= "@+id/web" />

Окно разметки будет выглядеть так:

После этого давайте сразу разберемся с файлом AndroidManifest.xml . Открываем его и добавляем туда две строчки, одна - это разрешение для приложения использовать Интернет, другая - изменение стиля приложения, а точнее сокрытие панели "Title" приложения (панели с заголовком приложения) с той целью, чтобы предоставить окну браузера больше пространства для отображения страниц.

Пишем строку разрешения использовать интернет до открытия тега ...:

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

Теперь добавим к строке настройки нашего Activity команду для скрытия заголовка (нижняя строка, выделенная жирным, это также находиться в AndroidManifest.xml ):

< activity android: name= ".MainActivity" android: label= android: theme= "@android:style/Theme.NoTitleBar" >

Теперь переходим к самой важной и ответственной части работы - написанию java кода. Открываем файл MainActivity.java и пишем так следующее (объяснения даны в коде после знаков //, кто не заметил):

package home.myapplication ; import android.app.Activity ; import android.app.AlertDialog ; import android.content.ContentValues ; import android.content.Intent ; import android.database.Cursor ; import android.database.sqlite.SQLiteDatabase ; import android.database.sqlite.SQLiteOpenHelper ; import android.support.v7.app.ActionBarActivity ; import android.os.Bundle ; import android.util.Log ; import android.view.KeyEvent ; import android.view.Menu ; import android.view.MenuItem ; import android.view.View ; import android.webkit.WebView ; import android.webkit.WebViewClient ; import android.widget.Button ; import android.widget.EditText ; import android.widget.RadioButton ; import android.widget.TextView ; public class MainActivity extends Activity { // Объявляем переменную типа WebView private WebView mWeb; // Создаем класс типа Веб-обозреватель (WebViewClient), которому настраиваем // по умолчанию разрешение обрабатывать все ссылки внутри этого класса, // не обращаясь к сторонним программам: private class WebViewer extends WebViewClient { (WebView view , String url ) { view. loadUrl(url); return true ; } } public void onCreate (Bundle savedInstanceState ) { super. onCreate(savedInstanceState); setContentView(R . layout. activity_main); // Привязываем объявленную переменную типа WebView к созданному нами // элементу WebView в файле activity_main.xml: mWeb= (WebView )findViewById(R . id. web); // Подключаем для этого элемента поддержку Java скриптов: mWeb. getSettings(). setJavaScriptEnabled(true ); // Настраиваем страницу, которая будет загружать при запуске, можете ввести любую: mWeb. loadUrl("http://developeroleg.ucoz.ru/" ); // Настраиваем обозреватель для нашего элемента WebView, подключаем созданный нами выше // Веб-клиент, с помощью которого будет проходить просмотр страниц: mWeb. setWebViewClient(new WebViewer ()); } // Пишем код обработки нажатия кнопки назад на устройстве, что позволит нам при нажатии // на кнопку "Назад" перейти к предыдущей странице, а не просто закрывать приложения. // Оно будет закрываться кнопкой "Назад" лишь в том случае, если мы находимся на стартовой // странице, которую указали выше: @Override public void onBackPressed () { if (mWeb. canGoBack()) { mWeb. goBack();} else { super. onBackPressed(); } } }

Вот и все! На самом деле все довольно просто и после недолгих трудов у нас есть собственный браузер, конечно он довольно прост и не имеет никаких опций, но для понимания сути создания подобных приложений этого вполне достаточно.

Стандартные браузеры в устройствах на базе Android зачастую не отвечают повседневным запросам требовательных пользователей. На этой операционной системе существует масса качественных и функциональных интернет-обозревателей. Мы собрали лучшие браузеры для Android именно в этой статье.

Firefox по праву носит звание одного из лучших мобильных браузеров на Android. За годы присутствия на этой операционной системе разработка Mozilla обросла массой функций и получила облагороженный современный интерфейс. Firefox для Android - это баланс функционала, удобства и скорости использования. Мобильный браузер от Mozilla проигрывает по скорости тому же Google Chrome, но многие особенности Firefox сделаны куда более приятно и удобно.

Собственный движок Gecko, который использует Firefox, поддерживает практически все современные стандарты веба, а также для него имеются расширения с дополнительным функционалом, как и в десктопной версии браузера. Среди основных функций Fiefox: синхронизация всех данных между браузерами с помощью специального аккаунта, безопасный серфинг, удобная стартовая панель, масса расширений, режим чтения.



Самым популярным браузером не только на компьютерах, но и на мобильных устройствах является Google Chrome. Неудивительно, ведь он почти всегда предустанавливается на самую популярную мобильную ОС. Свою популярность Chrome завоевал вполне заслуженно - он быстрый, относительно функциональный, простой и удобный, а также он хорошо интегрирован с сервисами Google и десктопной версией браузера (есть полная сихронизация данных и вкладок). Интеграция с сервисами Google иногда может быть полезной, например - перевод текста на страницах с помощью Google Переводчика или голосовой поиск.

Также Chrome заботится о безопасности пользователя - в браузере встроен специальный фильтр сайтов, которые могут быть опасны для устройств с Android. Присутствует некое подобие технологии сжатия данных. Она не так совершенна, как у Opera, но все-таки неплохо экономит данные, передаваемые как по Wi-Fi, так и по мобильному интернету. Есть режим инкогнито для анонимного посещения сайтов. Пожалуй, единственный недостаток Chrome на данный момент - отсутствие поддержки расширений. Для тех, кто хочет пробовать все новые функции первым, есть Chrome Beta и Dev. Эти версии браузера обновляются быстрее и чаще - в них тестируются все нововведения.



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

Ребята из Opera собаку съели на технологиях экономии трафика. Мобильная Opera с активированным режимом Turbo может сократить расходы мобильного интернета в два, а то и в три раза. Для тех, кому особенно важен расход трафика, существует Opera Mini - в ней экономия включена по умолчанию, но от этого порой страдает внешний вид сайтов. Также мини-версия куда легче и быстрее обычной Opera. Еще одна сильная сторона одноименного браузера - красивый и приятный внешний вид. Opera всегда славилась одним из самых стильных интерфейсов в браузерах. Если вы хотите сжимать весь трафик на своем устройстве, то обратите внимание на приложение .



Dolphin - это альтернативный браузер на Android с массой дополнительных возможностей и функций «из-коробки». Среди таких стоит отметить поддержку Adobe Flash, от которого практически все отказались, но он еще много где используется, применение различных тем для изменения интерфейса, поддержку уникальных дополнений и управление удобными и простыми жестами. Все это доступно сразу - никаких дополнительных настроек. А еще Dolphin быстрый, безопасный, бесплатный и всегда современный - разработчики выпускают обновления браузера практически каждую неделю.


Puffin - мобильный веб-браузер, который по своей концепции напоминает Dolphin. Здесь тоже в наличии красивый и удобный интерфейс, есть много возможностей, а еще Puffin такой же быстрый, как и «дельфин». В основном браузер Puffin подходит для слабых устройств, так как в нем предусмотрена специальная технология «облегченного» веб-серфинга - страницы сначала загружаются на облачный сервис Puffin, там оптимизируются и уже в легком виде приходят на экран устройства. При этом качество и внешний вид страниц практически не страдают от сломанной верстки или уменьшения качества.

Также в Puffin стоит отметить ряд дополнительных возможностей:

  • полная поддержка Adobe Flash для игр (виртуальный джойстик на экране);
  • шифрование трафика через облачный сервис;
  • эмуляция мыши;
  • возможность загрузить файлы сначала в «облако», а потом на устройство;
  • установка расширений;
  • темы интерфейса.
Браузер Puffin является отличным выбором для слабых устройств, но при этом функционала в этом интернет-обозревателе не занимать.



Российская компания «Яндекс» преуспела в создании собственного браузера для мобильных устройств с Android. Яндекс.Браузер для этой платформы - это отличное решение для пользователей из СНГ. Этот интернет-обозреватель прямо таки пропитан интеграцией с сервисами самого «Яндекса» и других местных социальных сетей / порталов. Например, строка поиска в браузере подсказывает нужные сайты и понимает запросы с полуслова, а еще внутри приложения можно посмотреть информацию о погоде и пробках.

Изучать программирование под Андроид я начал не так давно. После того, как Eclips выдал мой первый Hello Word, сразу захотелось большего: возникло много планов и грандиозных идей. Одной такой идеей было написание своего Браузера. Думаю, у многих начинающих программистов возникало такое желание. Вот какие требования были мной поставлены и что получилось в итоге.

  • Программа должна открывать ссылки глобальной сети, свободно переходить по страничкам вперёд и назад;
  • Иметь возможность скачивать файлы и загружать обратно в сеть;
  • Создавать закладки и сохранять их;
  • Иметь возможность загружать ссылки, отправленные с других приложений;
  • Должна быть кнопка домашней страницы, меню с различными настройками и т.д.

В общем, полноценный браузер своими руками. Воплотим это в код.

Программа написана на основе стандартного webview, входящего в Android. В качестве стартовой страницы использую Яндекс, это дело вкуса. В качестве основного Activity будет MainActivity.

Первым делом задаём разметку xml файла -activity_main.xml. В качестве главного контейнера используем LinearLayout - в него заворачиваем ProgressBar для отображения процесса загрузки. Далее создаём ещё один контейнер LinearLayout - в него заворачиваем наш Webview и FrameLayout (его используем для растягивания воспроизводимого видео на весь экран).

Посмотреть код

LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">

Начнём писать код в MainActivity

Полный код MainActivity.

Посмотреть полный код

Import java.io.File; import android.R.menu; import android.annotation.SuppressLint; import android.app.ActionBar; import android.app.Activity; import android.app.AlertDialog; import android.app.DownloadManager; import android.app.DownloadManager.Request; import android.app.KeyguardManager; import android.app.SearchManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Parcelable; import android.os.PowerManager; import android.preference.PreferenceManager; import android.provider.MediaStore; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.webkit.ConsoleMessage; import android.webkit.DownloadListener; import android.webkit.ValueCallback; import android.webkit.WebBackForwardList; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.FrameLayout; import android.widget.SearchView; import android.widget.Toast; import android.graphics.Bitmap; import android.webkit.URLUtil; public class MainActivity extends Activity { //Логическая переменная для статуса соединения Boolean isInternetPresent = false; ConnectionDetector cd; private WebChromeClient.CustomViewCallback mFullscreenViewCallback; private FrameLayout mFullScreenContainer; private View mFullScreenView; private WebView mWebView; String urload; int cache = 1; SharedPreferences sPref; final Activity activity = this; public Uri imageUri; private static final int FILECHOOSER_RESULTCODE = 2888; private ValueCallback mUploadMessage; private Uri mCapturedImageURI = null; private DownloadManager downloadManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Создаем пример класса connection detector: cd = new ConnectionDetector(getApplicationContext()); // создаём кнопу home final ActionBar actionBar = getActionBar(); actionBar.setHomeButtonEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true); // ловим intent что файл загружен и оповещаем BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) { loadEnd(); } } }; // ловим intent что файл загружен registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); mWebView = (WebView) findViewById(R.id.web_view); mFullScreenContainer = (FrameLayout) findViewById(R.id.fullscreen_container); mWebView.setWebChromeClient(mWebChromeClient); mWebView.loadUrl("http://yandex.ru"); handleIntent(getIntent()); class HelloWebViewClient extends WebViewClient { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); findViewById(R.id.progress1).setVisibility(View.VISIBLE); setTitle(url); urload=mWebView.getUrl(); ConnectingToInternet (); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); // запускаем ссылки на маркет Uri uri = Uri.parse(url); if (uri.getScheme().equals("market")) { Intent i = new Intent(android.content.Intent.ACTION_VIEW); i.setData(uri); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(i); mWebView.canGoBack(); { mWebView.goBack(); } } // запускаем email if (uri.getScheme().equals("mailto")) { Intent i = new Intent(android.content.Intent.ACTION_SEND); i.setType("text/html"); i.putExtra(Intent.EXTRA_SUBJECT, "Введите тему"); i.putExtra(Intent.EXTRA_TEXT, "Введите текст"); i.putExtra(Intent.EXTRA_EMAIL, new String{url}); startActivity(i); mWebView.canGoBack(); { mWebView.goBack(); } } // запускаем звонилку if (uri.getScheme().equals("tel")) { Intent i = new Intent(android.content.Intent.ACTION_DIAL); i.setData(uri); startActivity(i); mWebView.canGoBack(); { mWebView.goBack(); } } // запускаем лoкцию if (uri.getScheme().equals("geo")) { Intent i = new Intent(android.content.Intent.ACTION_VIEW); i.setData(uri); startActivity(i); mWebView.canGoBack(); { mWebView.goBack(); } } return true; } @Override public void onPageFinished(WebView view, String url) { findViewById(R.id.progress1).setVisibility(View.GONE); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { ConnectingToInternet (); mWebView.loadUrl("file:///android_asset/error.png"); } } mWebView.setWebViewClient(new HelloWebViewClient()); // загрузка файлов на устройство mWebView.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(final String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { final String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype); final AlertDialog.Builder downloadDialog = new AlertDialog.Builder(MainActivity.this); downloadDialog.setTitle("Менеджер загрузок"); downloadDialog.setMessage("Загрузить этот файл в папку Donwload ?" + "n" + mimetype + "n" + url); downloadDialog.setPositiveButton("Да", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialogInterface, int i) { doDownload(url, fileName); dialogInterface.dismiss(); } }); downloadDialog.setNegativeButton("Нет", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialogInterface, int i) { } }); downloadDialog.show(); } }); } // **************************************** //***************************************** //***************************************** public void ConnectingToInternet (){ //Получаем статус Интернет соединения isInternetPresent = cd.ConnectingToInternet(); //Проверяем Интернет статус: if (isInternetPresent) { //Интернет соединение есть //делаем HTTP запросы: } else { //Интернет соединения нет Toast.makeText(this, " Интернет отвалился!!!", Toast.LENGTH_SHORT).show(); } } @SuppressLint("SetJavaScriptEnabled") @Override // настройки public void onResume(){ super.onResume(); SharedPreferences sPref = PreferenceManager.getDefaultSharedPreferences(this); if (sPref.getBoolean("img", false)) { mWebView.getSettings().setLoadsImagesAutomatically(false); } else { mWebView.getSettings().setLoadsImagesAutomatically(true); } if (sPref.getBoolean("js", false)) { mWebView.getSettings().setJavaScriptEnabled(false); } else { mWebView.getSettings().setJavaScriptEnabled(true); } if (sPref.getBoolean("cache", false)) { cache = 2; } else { cache = 1; } } // пишем закладку public void saveBm(String urlPage1, String urlTitle1) { Intent intent = new Intent(this, SaveBmActivity.class); intent.putExtra("urlTitle", urlTitle1); intent.putExtra("urlPage", urlPage1); startActivity(intent); } public void pref() { // настройки Intent intent = new Intent(this, PreferencesActivity.class); startActivity(intent); } // чистим кэш и историю private void clCache(){ clearCache(activity); mWebView.clearCache(true); mWebView.clearHistory(); Toast.makeText(this, "Кеш и История очищены", Toast.LENGTH_SHORT).show(); } @Override protected void onUserLeaveHint() { super.onUserLeaveHint(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) {// кнопка назад if ((keyCode == KeyEvent.KEYCODE_BACK)) { mWebView.canGoBack(); { mWebView.goBack(); } return true; } return super.onKeyDown(keyCode, event); } // ловим url запустившей программы private boolean handleIntent(Intent intent) { String action = intent.getAction(); if (Intent.ACTION_VIEW.equals(action)) { String url = intent.getDataString(); Toast.makeText(this, url, Toast.LENGTH_SHORT).show(); mWebView.loadUrl(url);// грузим страницу return true; } return false; } // менеджер загрузки private void doDownload(String url,String fileName) { Uri uriOriginal = Uri.parse(url); try { Toast.makeText(MainActivity.this, "Downloading " + fileName, Toast.LENGTH_LONG).show(); Request request = new DownloadManager.Request(Uri.parse(url)); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); final DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); dm.enqueue(request); } catch (Exception e) { Toast.makeText(this, "Ошибка", Toast.LENGTH_SHORT).show(); Log.e("", "Problem downloading: " + uriOriginal, e); } } // тянем видео на весь экран private final WebChromeClient mWebChromeClient = new WebChromeClient() { @Override @SuppressWarnings("deprecation") public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) { onShowCustomView(view, callback); } @Override public void onShowCustomView(View view, CustomViewCallback callback) { if (mFullScreenView != null) { callback.onCustomViewHidden(); return; } mFullScreenView = view; mWebView.setVisibility(View.GONE); mFullScreenContainer.setVisibility(View.VISIBLE); mFullScreenContainer.addView(view); mFullscreenViewCallback = callback; } @Override public void onHideCustomView() { super.onHideCustomView(); if (mFullScreenView == null) { return; } mWebView.setVisibility(View.VISIBLE); mFullScreenView.setVisibility(View.GONE); mFullScreenContainer.setVisibility(View.GONE); mFullScreenContainer.removeView(mFullScreenView); mFullscreenViewCallback.onCustomViewHidden(); mFullScreenView = null; } // ********************************************* грузим файлы в сеть // openFileChooser for Android 3.0+ public void openFileChooser(ValueCallback uploadMsg, String acceptType) { // Сообщение об обновлении mUploadMessage = uploadMsg; try { // Создать AndroidExampleFolder в sdcard File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) , "AndroidExampleFolder"); if (!imageStorageDir.exists()) { // Создать AndroidExampleFolder в sdcard imageStorageDir.mkdirs(); } // Создать камеру захваченное изображение путь к файлу и имя File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg"); mCapturedImageURI = Uri.fromFile(file); // Камера захвата изображения intent final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI); Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); // Создать файл селектора intent Intent chooserIntent = Intent.createChooser(i, "Image Chooser"); // Установить камеры намерении выбора файлов chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS , new Parcelable{captureIntent}); // На выбор изображения обхода метода onactivityresult вызов метода активности startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE); } catch (Exception e) { Toast.makeText(getBaseContext(), "Exception:" + e, Toast.LENGTH_LONG).show(); } } // openFileChooser for Android < 3.0 @SuppressWarnings("unused") public void openFileChooser(ValueCallback uploadMsg) { openFileChooser(uploadMsg, ""); } // @SuppressWarnings("unused") public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) { openFileChooser(uploadMsg, acceptType); } public boolean onConsoleMessage(ConsoleMessage cm) { onConsoleMessage(cm.message(), cm.lineNumber(), cm.sourceId()); return true; } public void onConsoleMessage(String message, int lineNumber, String sourceID) { //Log.d("androidruntime", "Show console messages, Used for debugging: " + message); }; };// End setWebChromeClient // Получаем результат @SuppressWarnings("unused") private Object data; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (data == null) { return; } String urlPage2 = data.getStringExtra("urlPage2"); mWebView.loadUrl(urlPage2); if (requestCode == FILECHOOSER_RESULTCODE) { if (null == this.mUploadMessage) { return; } Uri result = null; try { if (resultCode != RESULT_OK) { result = null; } else { // извлечь из собственной переменной, если намерение состоит в нуль result = data == null ? mCapturedImageURI: data.getData(); } } catch (Exception e) { Toast.makeText(getApplicationContext(), "activity:" + e, Toast.LENGTH_LONG).show(); } mUploadMessage.onReceiveValue(result); mUploadMessage = null; } } //***************************** public void loadEnd () { Toast.makeText(this, "Файл Загружен в папку Donwload", Toast.LENGTH_SHORT).show(); } // меню @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } // ******************************************************* @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home:// кнопка home mWebView.loadUrl("http://yandex.ru"); return true; case R.id.item1:// назад mWebView.canGoBack(); { mWebView.goBack(); } return true; case R.id.item2: // вперёд mWebView.canGoForward(); { mWebView.goForward(); } return true; case R.id.item3: // перезагрузка mWebView.reload(); { mWebView.reload(); } return true; case R.id.item4:// чистим кеш mWebView.clearCache(true); clearCache(activity); Toast.makeText(this, "Кэш чист.", Toast.LENGTH_SHORT).show(); return true; case R.id.item5: mWebView.clearHistory();// чистим историю Toast.makeText(this, "История чиста.", Toast.LENGTH_SHORT).show(); return true; case R.id.item6: saveBm(mWebView.getUrl(), mWebView.getTitle());// пишим закладку return true; case R.id.item7:// панель закладок Intent intent1 = new Intent(this, SaveBmActivity.class); startActivityForResult(intent1, 1); return true; case R.id.item8: // стоп загрузка mWebView.stopLoading(); return true; case R.id.item9: pref();// настройки return true; case R.id.item10: // пока пусто return true; case R.id.item11:// выход if (cache == 2) { clCache(); } finish(); return true; default: return super.onOptionsItemSelected(item); } } @SuppressWarnings("deprecation") @Override public void onDestroy() { super.onDestroy(); mWebView.stopLoading(); mWebView.clearCache(true); mWebView.clearView(); mWebView.freeMemory(); mWebView.destroy(); mWebView = null; } // чистим кеш void clearCache(Context context) { clearCacheFolder(context.getCacheDir()); } void clearCacheFolder(final File dir) { if (dir!= null && dir.isDirectory()) { try { for (File child:dir.listFiles()) { //рекурсивно чистим сначала каталоги if (child.isDirectory()) clearCacheFolder(child); else //потом собственно файлы child.delete(); } } catch(Exception e) { } } } }

Проект можно скачать

Android позволяет создать собственное окно для просмотра веб-страниц или даже создать свой клон браузера при помощи элемента . Сам элемент использует движок WebKit и имеет множество свойств и методов. Мы ограничимся базовым примером создания приложения, с помощью которого сможем просматривать страницы в интернете. В последних версиях используется движок от Chromium, но большой разницы в этом нет для простых задач.

Создадим новый проект MyBrowser и сразу заменим код в файле разметки res/layout/activity_main.xml :

Теперь откроем файл активности MainActivity.java и объявим компонент , а также инициализируем его - включим поддержку JavaScript и укажем страницу для загрузки.

Private WebView webView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = findViewById(R.id.webView); // включаем поддержку JavaScript webView.getSettings().setJavaScriptEnabled(true); // указываем страницу загрузки webView.loadUrl("http://сайт/android"); }

Так как приложение будет использовать интернет, необходимо установить разрешение на доступ к интернету в файле-манифесте.

Там же в манифесте модифицируем строчку для экрана, удалив заголовок из нашего приложения (выделено жирным):

android:theme="@style/Theme.AppCompat.NoActionBar" >

Запустим приложение. В нашем распоряжении появился простейший вьювер веб-страниц, но с одним недостатком. Если вы щёлкнете на любой ссылке, то у вас автоматически запустится браузер по умолчанию и новая страница отобразится уже там. Точнее так было раньше. На новых устройствах при запуске приложения сразу открывается браузер.

Чтобы решить данную проблему и открывать ссылки в своей программе, нужно переопределить класс WebViewClient и позволить нашему приложению обрабатывать ссылки. Добавим в коде вложенный класс:

Private class MyWebViewClient extends WebViewClient { @TargetApi(Build.VERSION_CODES.N) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { view.loadUrl(request.getUrl().toString()); return true; } // Для старых устройств @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }

Затем в методе onCreate() определим экземпляр MyWebViewClient . Он может находиться в любом месте после инициализации объекта :

WebView.setWebViewClient(new MyWebViewClient());

Теперь в нашем приложении создан WebViewClient , который позволяет загружать любой указанный URL, выбранный в , в сам контейнер , а не запускать браузер. За данную функциональность отвечает метод , в котором мы указываем текущий и нужный URL. Возвращаемое значение true говорит о том, что мы не нуждаемся в запуске стороннего браузера, а самостоятельно загрузим контент по ссылке. В версии API 24 добавили перегруженную версию метода, учитывайте это обстоятельство.

Повторно запустите программу и убедитесь, что ссылки загружаются теперь в самом приложении. Но теперь возникла ещё одна проблема. Мы не можем вернуться к предыдущей странице. Если мы нажмём на кнопку BACK (Назад) на своем устройстве, то просто закроем свое приложение. Для решения новой проблемы нам необходимо обрабатывать нажатие кнопки BACK. Добавляем новый метод:

@Override public void onBackPressed() { if(webView.canGoBack()) { webView.goBack(); } else { super.onBackPressed(); } }

Мы должны проверить, что поддерживает навигацию на предыдущую страницу. Если условие верно, тогда вызывается метод goBack() , который возвращает нас на предыдущую страницу на один шаг назад. Если таких страниц набралось несколько, то мы можем последовательно вернуться к самой первой странице. При этом метод всегда будет возвращать значение true . Когда мы вернёмся на самую первую страницу, с которой начали путешествие по интернету, то вернётся значение false и обработкой нажатия кнопки BACK займётся уже сама система, которая закроет экран приложения.

Запустите приложение ещё раз. У вас появился свой собственный веб-браузер, позволяющий ходить по ссылкам и возвращаться на предыдущую страницу. Изучив документацию, вы можете оснастить приложение и другим вкусными плюшками для своего браузера.

Если вам нужно часть ссылок, ведущих на ваш сайт открывать в браузере, а локальные ссылки открывать в приложении, то применяйте условие с разными возвращаемыми значениями.

Public class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if(Uri.parse(url).getHost()..ACTION_VIEW, Uri.parse(url)); view.getContext().startActivity(intent); return true; } }

Универсальный метод, который все локальные ссылки откроет в приложении, остальные в браузере (меняем одну строчку):

Public class MyAppWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if(Uri.parse(url).getHost().length() == 0) { return false; } Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); view.getContext().startActivity(intent); return true; } }

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

Чтобы было понятнее, переделаем пример следующим образом. Создайте две активности. На первой активности разместите кнопку для перехода на вторую активность, а на второй активности разместите компонент .

В манифесте прописываем у второй активности фильтр.

Код для кнопки для перехода на вторую активность.

Public void onClick(View view) { Intent intent = new Intent("ru.alexanderklimov.Browser"); intent.setData(Uri.parse("http://сайт/android/")); startActivity(intent); }

Мы создали собственное намерение с указанием фильтра и предоставили данные - адрес сайта.

Вторая активность должна принять данные:

Package ru.alexanderklimov.testapplication; import android.net.Uri; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.webkit.WebView; import android.webkit.WebViewClient; public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Uri url = getIntent().getData(); WebView webView = findViewById(R.id.webView); webView.setWebViewClient(new Callback()); webView.loadUrl(url.toString()); } private class Callback extends WebViewClient { @Override public boolean shouldOverrideUrlLoading (WebView view, String url) { return(false); } } }

В фильтре для второй активность мы указали два действия.

Это означает, что любые активности (читай, приложения) могут вызвать вашу активность с мини-браузером по такому же принципу. Запустите в студии в отдельном окне любой старый проект или создайте новый и добавьте в него кнопку и пропишите тот же код, который мы использовали для щелчка кнопки.

Запустите второе приложение (первое приложение можно закрыть) и нажмите на кнопку. У вас запустится не первое приложение с начальным экраном, а сразу вторая активность с мини-браузером. Таким образом, любое приложение может запустить браузер, не зная имени класса вашей активности, а используя только строку "ru.alexanderklimov.Browser" , передаваемую в Intent . При этом ваша активность с браузером должна иметь категорию по умолчанию и данные. Напомню:

Вы можете представить свою строку в виде строковой константы и сообщить всем потенциальным пользователям вашего браузера, как они могут запустить его у себя. Но в Android уже есть такая готовая константа ACTION_VIEW , которая по справке документации представляет собой следующее:

Public static final java.lang.String ACTION_VIEW = "android.intent.action.VIEW";

Перепишем код для кнопки у второго приложения

Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://сайт/android/")); startActivity(intent);

Что произойдёт на этот раз? Мы помним, что у нас прописано два действия, включая и android.intent.action.VIEW . А значит наше первое приложение с браузером тоже должно распознавать эту команду, когда какое-то приложение у пользователя использует этот код. На эмуляторе как минимум есть одна такая программа "Browser", и теперь к ней добавилась наша вторая активность из первого приложения. На экране появится выбор из двух приложений.

А если удалить все альтернативные браузеры и оставить только вашу программу, то и выбора не будет. Ваш браузер станет основным. И если какое-то приложение захочет запустить веб-страницу указанным способом, то откроется ваша программа.

Небольшое замечание. Если заменить последнюю строчку на такую:

StartActivity(Intent.createChooser(intent, "Мяу..."));

То в окне выбора программы вместо верхней строки "Open with" или её локального перевода появится ваша строка. Но не это главное. Если по каким-то причинам на устройстве не окажется ни одного браузера, то данный вариант кода не вызовет краха приложения, в отличие от первоначального варианта. Поэтому используйте предложенный вариант ради надёжности.

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

Приложение-браузер для android

Запустим android studio и создадим новый проект, application name My Site, company domain по своему усмотрению, я вписал домен сайта сайт. жмем Next, на следующей вкладке оставляем все без изменения, жмем next, далее уже выбрана Empty Activity , ее и оставим, затем в последней вкладке изменим Layout Name с activity_main на main, и нажмем финиш.

Android Studio подготовит файлы проекта, это займет некоторое время. В главном окне будет открыты два файла, main.xml и MainActivity.java , начнем работать в последнем. Изменим extended AppCompactActivity на Activity, сохранимся.

Добавление разрешений в манифест

Затем откроем файл AndroidManifest.xml и добавим после первой секции пользовательское разрешение user-permission ,

что бы наше приложение имело доступ в интернет. Сохраним и закроем AndroidManifest.xml.

Перейдем в файл Main.xml , он находится по пути res/layout/main.xml, удалим строку android:text="Hello Word!" полностью, изменим TextView на WebView, из свойств основного слоя RelativeLayout уберем ненужные отступы (paddingBottom, paddingLeft, paddingRight,paddingTop).

Для WebView добавим свойство android:id="@+id/webView",изменим android:layout_width="wrap_content" и android:layout_height="wrap_content" на android:layout_width="match_parent" и android:layout_height="match_parent", для того, что бы наш элемент WebView был на весь экран.

Кодим логику на Java

С файлом main.xml мы закончили, перейдем к MainActivity.java . Добавим переменную wv типа WebView , присвоим ей элемент, найдя его с помощью функции findViewById(), опишем настройки wv, в частности разрешим в WebView выполнять java скрипты, укажем адрес загрузки сайта в наш браузер, я для примера запущу Яндекс, применив функцию loadUrl("http://ya.ru").

public class MainActivity extends Activity { WebView wv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView)findViewById(R.id.webView); WebSettings settings = wv.getSettings(); settings.setJavaScriptEnabled(true); wv..setWebViewClient(new WebViewClient()); }

Так же ниже напишем обработку нажатия кнопки назад на устройстве.

@Override public void onBackPressed(){ if(wv.canGoBack()){ wv.goBack(); }else{ super.onBackPressed(); } }

Запуск приложения в эмуляторе

Нажмем кнопку Start, это зеленый треугольник на панели инструментов AndroidStudio , запустится наш эмулятор, и если все сделано правильно, через некоторое время в браузере запустится поиск Яндекс, можно понажимать на виртуальную клавиатуру и что-то поискать, все работает хорошо.

Закроем программу, не закрывая сам эмулятор, нажав на красный прямоугольник, это Stop вместо Start, изменим адрес на произвольный, я «пропиарю» свой сайт "https://сайт",

нажму сохранить и снова запущу программу, на этот раз все произойдет быстрее, поброжу по сайту, в разделе Программирование для андроид есть статьи и видео как установить и настроить AndroidStudio , сделать эмулятор android и простые примеры программ .

Полный текст AndroidManifest.xml

Полный текст main.xml

Полный текст MainActivity.java

package ru.maxfad.mysite; import android.app.Activity; import android.os.Bundle; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; public class MainActivity extends Activity { WebView wv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); wv = (WebView)findViewById(R.id.webView); WebSettings settings = wv.getSettings(); settings.setJavaScriptEnabled(true); wv..setWebViewClient(new WebViewClient()); } @Override public void onBackPressed(){ if(wv.canGoBack()){ wv.goBack(); }else{ super.onBackPressed(); } } }

В этом видео подробно показано как создать приложение-браузер для android устройств: