Изучать программирование под Андроид я начал не так давно. После того, как 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"> <ProgressBar android:id="@+id/progress1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dip" android:indeterminateDrawable="@drawable/spinner_png" android:indeterminateOnly="true" android:layout_gravity="center_horizontal"/> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <WebView android:id="@+id/web_view" android:layout_width="match_parent" android:layout_height="match_parent" /> <FrameLayout android:id="@+id/fullscreen_container" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/black" android:visibility="gone"/> </LinearLayout> </LinearLayout>
Начнём писать код в 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<Uri> 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<Uri> 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<Uri> uploadMsg) { openFileChooser(uploadMsg, ""); } // @SuppressWarnings("unused") public void openFileChooser(ValueCallback<Uri> 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) { } } } }
Проект можно скачать отсюда.
ссылка на оригинал статьи https://habrahabr.ru/post/276113/
Добавить комментарий