1 package com.stoutner.privacybrowser;
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.graphics.Bitmap;
6 import android.graphics.drawable.BitmapDrawable;
7 import android.graphics.drawable.Drawable;
8 import android.net.Uri;
9 import android.os.Bundle;
10 import android.support.v4.widget.SwipeRefreshLayout;
11 import android.support.v7.app.ActionBar;
12 import android.support.v7.app.AppCompatActivity;
13 import android.util.Patterns;
14 import android.view.KeyEvent;
15 import android.view.Menu;
16 import android.view.MenuItem;
17 import android.view.View;
18 import android.view.ViewTreeObserver;
19 import android.view.inputmethod.InputMethodManager;
20 import android.webkit.ClientCertRequest;
21 import android.webkit.WebChromeClient;
22 import android.webkit.WebView;
23 import android.webkit.WebViewClient;
24 import android.widget.EditText;
25 import android.widget.ImageView;
26 import android.widget.ProgressBar;
27 import java.io.UnsupportedEncodingException;
28 import java.net.MalformedURLException;
30 import java.net.URLEncoder;
32 public class Webview extends AppCompatActivity {
34 static String formattedUrlString;
35 static WebView mainWebView;
36 static ProgressBar progressBar;
37 static SwipeRefreshLayout swipeToRefresh;
38 static EditText urlTextBox;
39 static ImageView favoriteIcon;
40 static final String homepage = "https://www.duckduckgo.com";
43 protected void onCreate(Bundle savedInstanceState) {
44 super.onCreate(savedInstanceState);
45 setContentView(R.layout.activity_webview);
47 urlTextBox = (EditText) findViewById(R.id.urlTextBox);
48 swipeToRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayoutContainer);
49 mainWebView = (WebView) findViewById(R.id.mainWebView);
50 progressBar = (ProgressBar) findViewById(R.id.progressBar);
51 favoriteIcon = (ImageView) findViewById(R.id.favoriteIcon);
53 // Remove the title from the action bar.
54 final ActionBar actionBar = getSupportActionBar();
55 if (actionBar != null) {
56 actionBar.setDisplayShowTitleEnabled(false);
57 // actionBar.setHideOnContentScrollEnabled(true);
60 // Implement swipe down to refresh.
61 swipeToRefresh.setColorSchemeColors(0xFF0097FF);
62 swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
64 public void onRefresh() {
65 mainWebView.loadUrl(formattedUrlString);
69 // Only enable swipeToRefresh if is mainWebView is scrolled to the top.
70 mainWebView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
72 public void onScrollChanged() {
73 if (mainWebView.getScrollY() == 0) {
74 swipeToRefresh.setEnabled(true);
76 swipeToRefresh.setEnabled(false);
81 mainWebView.setWebViewClient(new WebViewClient() {
83 // setWebViewClient makes this WebView the default handler for URLs inside the app, so that links are not kicked out to other apps.
84 // Save the URL to formattedUrlString and update urlTextBox before loading mainWebView.
86 public boolean shouldOverrideUrlLoading(WebView view, String url) {
87 formattedUrlString = url;
88 urlTextBox.setText(formattedUrlString);
89 mainWebView.loadUrl(formattedUrlString);
94 public void onPageFinished(WebView view, String url) {
95 // Update the URL in urlTextBox. It is necessary to do this after the page finishes loading to get the final URL, which can change during load.
96 formattedUrlString = mainWebView.getUrl();
97 urlTextBox.setText(formattedUrlString);
101 mainWebView.setWebChromeClient(new WebChromeClient() {
103 // Update the progress bar when a page is loading.
105 public void onProgressChanged(WebView view, int progress) {
106 progressBar.setProgress(progress);
107 if (progress < 100) {
108 progressBar.setVisibility(View.VISIBLE);
110 progressBar.setVisibility(View.GONE);
112 // Stop the refreshing indicator if it is running.
113 swipeToRefresh.setRefreshing(false);
117 // Set the favorite icon if it changes.
119 public void onReceivedIcon(WebView view, Bitmap icon) {
120 favoriteIcon.setImageBitmap(icon);
124 // Set the "go" button on the keyboard to load the URL.
125 urlTextBox.setOnKeyListener(new View.OnKeyListener() {
126 public boolean onKey(View v, int keyCode, KeyEvent event) {
128 // If the event is a key-down event on the "enter" button, load the URL.
129 if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
130 (keyCode == KeyEvent.KEYCODE_ENTER)) {
131 // Load the URL into the mainWebView and consume the event.
133 loadUrlFromTextBox(mainWebView);
134 } catch (UnsupportedEncodingException e) {
137 // If the enter key was pressed, consume the event.
140 // If any other key was pressed, do not consume the event.
145 // Allow pinch to zoom.
146 mainWebView.getSettings().setBuiltInZoomControls(true);
148 // Hide zoom controls.
149 mainWebView.getSettings().setDisplayZoomControls(false);
151 // Enable JavaScript.
152 mainWebView.getSettings().setJavaScriptEnabled(true);
154 // Enable DOM Storage.
155 mainWebView.getSettings().setDomStorageEnabled(true);
157 // Get the intent information that started the app.
158 final Intent intent = getIntent();
160 if (intent.getData() != null) {
161 // Get the intent data and convert it to a string.
162 final Uri intentUriData = intent.getData();
163 Webview.formattedUrlString = intentUriData.toString();
166 // If formattedUrlString is null assign the homepage to it.
167 if (formattedUrlString == null) {
168 formattedUrlString = homepage;
171 // Place the formattedUrlString in the address bar and load the website.
172 urlTextBox.setText(formattedUrlString);
173 mainWebView.loadUrl(formattedUrlString);
177 public boolean onCreateOptionsMenu(Menu menu) {
178 // Inflate the menu; this adds items to the action bar if it is present.
179 getMenuInflater().inflate(R.menu.menu_webview, menu);
184 public boolean onOptionsItemSelected(MenuItem menuItem) {
185 int menuItemId = menuItem.getItemId();
187 // Sets the commands that relate to the menu entries.
188 switch (menuItemId) {
190 formattedUrlString = homepage;
191 urlTextBox.setText(formattedUrlString);
192 mainWebView.loadUrl(formattedUrlString);
196 mainWebView.goBack();
198 // Update the URL in urlTextBox with the URL we are intending to load. Because this can be altered during load, the final URL is loaded after the progress bar reaches 100%
199 formattedUrlString = mainWebView.getOriginalUrl();
200 urlTextBox.setText(formattedUrlString);
204 mainWebView.goForward();
206 // Update the URL in urlTextBox with the URL we are intending to load. Because this can be altered during load, the final URL is loaded after the progress bar reaches 100%
207 formattedUrlString = mainWebView.getOriginalUrl();
208 urlTextBox.setText(formattedUrlString);
212 return super.onOptionsItemSelected(menuItem);
215 // Override onBackPressed so that if mainWebView can go back it does when the system back button is pressed.
217 public void onBackPressed() {
218 if (mainWebView.canGoBack()) {
219 mainWebView.goBack();
221 // Update the URL in urlTextBox with the URL we are intending to load. Because this can be altered during load, the final URL is loaded after the progress bar reaches 100%
222 formattedUrlString = mainWebView.getOriginalUrl();
223 urlTextBox.setText(formattedUrlString);
225 super.onBackPressed();
229 public void loadUrlFromTextBox(View view) throws UnsupportedEncodingException {
230 // Get the text from urlTextInput and convert it to a string.
231 String unformattedUrlString = urlTextBox.getText().toString();
232 URL unformattedUrl = null;
233 Uri.Builder formattedUri = new Uri.Builder();
236 // Check to see if unformattedUrlString is a valid URL. Otherwise, convert it into a Duck Duck Go search.
237 if (Patterns.WEB_URL.matcher(unformattedUrlString).matches()) {
239 // Add http:// at the beginning if it is missing. Otherwise the app will segfault.
240 if (!unformattedUrlString.startsWith("http")) {
241 unformattedUrlString = "http://" + unformattedUrlString;
244 // Convert unformattedUrlString to a URL, then to a URI, and then back to a string, which sanitizes the input and adds in any missing components.
246 unformattedUrl = new URL(unformattedUrlString);
247 } catch (MalformedURLException e) {
251 if (unformattedUrl.getProtocol() != null) {
252 scheme = unformattedUrl.getProtocol();
257 final String authority = unformattedUrl.getAuthority();
258 final String path = unformattedUrl.getPath();
259 final String query = unformattedUrl.getQuery();
260 final String fragment = unformattedUrl.getRef();
262 formattedUri.scheme(scheme).authority(authority).path(path).query(query).fragment(fragment);
263 formattedUrlString = formattedUri.build().toString();
266 // Sanitize the search input.
267 final String encodedUrlString = URLEncoder.encode(unformattedUrlString, "UTF-8");
268 formattedUrlString = "https://duckduckgo.com/?q=" + encodedUrlString;
271 // Place formattedUrlString back in the address bar and load the website.
272 urlTextBox.setText(formattedUrlString);
273 mainWebView.loadUrl(formattedUrlString);
275 // Hides the keyboard so we can see the webpage.
276 InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
277 inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);