1 package com.stoutner.privacybrowser;
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.net.Uri;
6 import android.os.Bundle;
7 import android.support.v4.widget.SwipeRefreshLayout;
8 import android.support.v7.app.AppCompatActivity;
9 import android.util.Patterns;
10 import android.view.KeyEvent;
11 import android.view.Menu;
12 import android.view.MenuItem;
13 import android.view.View;
14 import android.view.ViewTreeObserver;
15 import android.view.inputmethod.InputMethodManager;
16 import android.webkit.WebChromeClient;
17 import android.webkit.WebView;
18 import android.webkit.WebViewClient;
19 import android.widget.EditText;
20 import android.widget.ProgressBar;
21 import java.io.UnsupportedEncodingException;
22 import java.net.MalformedURLException;
24 import java.net.URLEncoder;
26 public class Webview extends AppCompatActivity {
28 static String formattedUrlString;
29 static WebView mainWebView;
30 static ProgressBar progressBar;
31 static SwipeRefreshLayout swipeToRefresh;
32 static EditText urlTextBox;
33 static final String homepage = "https://www.duckduckgo.com";
36 protected void onCreate(Bundle savedInstanceState) {
37 super.onCreate(savedInstanceState);
38 setContentView(R.layout.activity_webview);
40 urlTextBox = (EditText) findViewById(R.id.urlTextBox);
41 swipeToRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayoutContainer);
42 mainWebView = (WebView) findViewById(R.id.mainWebView);
43 progressBar = (ProgressBar) findViewById(R.id.progressBar);
45 // Implement swipe down to refresh.
46 swipeToRefresh.setColorSchemeColors(0xFF0097FF);
47 swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
49 public void onRefresh() {
50 mainWebView.loadUrl(formattedUrlString);
54 // Only enable swipeToRefresh if is mainWebView is scrolled to the top.
55 mainWebView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
57 public void onScrollChanged() {
58 if (mainWebView.getScrollY() == 0) {
59 swipeToRefresh.setEnabled(true);
61 swipeToRefresh.setEnabled(false);
66 // setWebViewClient makes this WebView the default handler for URLs inside the app, so that links are not kicked out to other apps.
67 // Save the URL to formattedUrlString and update urlTextBox before loading mainWebView.
68 mainWebView.setWebViewClient(new WebViewClient() {
69 public boolean shouldOverrideUrlLoading(WebView view, String url) {
70 formattedUrlString = url;
71 urlTextBox.setText(formattedUrlString);
72 mainWebView.loadUrl(formattedUrlString);
77 // Update the progress bar when a page is loading.
78 mainWebView.setWebChromeClient(new WebChromeClient() {
79 public void onProgressChanged(WebView view, int progress) {
80 progressBar.setProgress(progress);
82 progressBar.setVisibility(View.VISIBLE);
84 progressBar.setVisibility(View.GONE);
86 // Stop the refreshing indicator if it is running.
87 swipeToRefresh.setRefreshing(false);
89 // 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.
90 formattedUrlString = mainWebView.getUrl();
91 urlTextBox.setText(formattedUrlString);
96 // Allow pinch to zoom.
97 mainWebView.getSettings().setBuiltInZoomControls(true);
99 // Hide zoom controls.
100 mainWebView.getSettings().setDisplayZoomControls(false);
102 // Enable JavaScript.
103 mainWebView.getSettings().setJavaScriptEnabled(true);
105 // Enable DOM Storage.
106 mainWebView.getSettings().setDomStorageEnabled(true);
108 // Get the intent information that started the app.
109 final Intent intent = getIntent();
111 if (intent.getData() != null) {
112 // Get the intent data and convert it to a string.
113 final Uri intentUriData = intent.getData();
114 Webview.formattedUrlString = intentUriData.toString();
117 // If formattedUrlString is null assign the homepage to it.
118 if (formattedUrlString == null) {
119 formattedUrlString = homepage;
122 // Place the formattedUrlString in the address bar and load the website.
123 urlTextBox.setText(formattedUrlString);
124 mainWebView.loadUrl(formattedUrlString);
126 // Set the "go" button on the keyboard to load the URL.
127 urlTextBox.setOnKeyListener(new View.OnKeyListener() {
128 public boolean onKey(View v, int keyCode, KeyEvent event) {
129 // If the event is a key-down event on the "enter" button
130 if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
131 (keyCode == KeyEvent.KEYCODE_ENTER)) {
132 // Load the URL into the mainWebView and consume the event.
134 loadUrlFromTextBox(mainWebView);
135 } catch (UnsupportedEncodingException e) {
140 // Do not consume the event.
148 public boolean onCreateOptionsMenu(Menu menu) {
149 // Inflate the menu; this adds items to the action bar if it is present.
150 getMenuInflater().inflate(R.menu.menu_webview, menu);
155 public boolean onOptionsItemSelected(MenuItem menuItem) {
156 int menuItemId = menuItem.getItemId();
157 final WebView mainWebView = (WebView) findViewById(R.id.mainWebView);
159 // Sets the commands that relate to the menu entries.
160 switch (menuItemId) {
162 formattedUrlString = homepage;
163 urlTextBox.setText(formattedUrlString);
164 mainWebView.loadUrl(formattedUrlString);
167 mainWebView.goBack();
169 // 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%
170 formattedUrlString = mainWebView.getOriginalUrl();
171 urlTextBox.setText(formattedUrlString);
174 mainWebView.goForward();
176 // 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%
177 formattedUrlString = mainWebView.getOriginalUrl();
178 urlTextBox.setText(formattedUrlString);
182 return super.onOptionsItemSelected(menuItem);
185 // Override onBackPressed so that if mainWebView can go back it does when the system back button is pressed.
187 public void onBackPressed() {
188 if (mainWebView.canGoBack()) {
189 mainWebView.goBack();
191 // 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%
192 formattedUrlString = mainWebView.getOriginalUrl();
193 urlTextBox.setText(formattedUrlString);
195 super.onBackPressed();
199 public void loadUrlFromTextBox(View view) throws UnsupportedEncodingException {
200 // Get the text from urlTextInput and convert it to a string.
201 final EditText urlTextBox = (EditText) findViewById(R.id.urlTextBox);
202 final WebView mainWebView = (WebView) findViewById(R.id.mainWebView);
203 String unformattedUrlString = urlTextBox.getText().toString();
204 URL unformattedUrl = null;
205 Uri.Builder formattedUri = new Uri.Builder();
208 // Check to see if unformattedUrlString is a valid URL. Otherwise, convert it into a Duck Duck Go search.
209 if (Patterns.WEB_URL.matcher(unformattedUrlString).matches()) {
211 // Add http:// at the beginning if it is missing. Otherwise the app will segfault.
212 if (!unformattedUrlString.startsWith("http")) {
213 unformattedUrlString = "http://" + unformattedUrlString;
216 // 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.
218 unformattedUrl = new URL(unformattedUrlString);
219 } catch (MalformedURLException e) {
223 if (unformattedUrl.getProtocol() != null) {
224 scheme = unformattedUrl.getProtocol();
229 final String authority = unformattedUrl.getAuthority();
230 final String path = unformattedUrl.getPath();
231 final String query = unformattedUrl.getQuery();
232 final String fragment = unformattedUrl.getRef();
234 formattedUri.scheme(scheme).authority(authority).path(path).query(query).fragment(fragment);
235 formattedUrlString = formattedUri.build().toString();
238 // Sanitize the search input.
239 final String encodedUrlString = URLEncoder.encode(unformattedUrlString, "UTF-8");
240 formattedUrlString = "https://duckduckgo.com/?q=" + encodedUrlString;
243 // Place formattedUrlString back in the address bar and load the website.
244 urlTextBox.setText(formattedUrlString);
245 mainWebView.loadUrl(formattedUrlString);
247 // Hides the keyboard so we can see the webpage.
248 InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
249 inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);