]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/Webview.java
Fix the updating of urlTextBox.
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / Webview.java
1 package com.stoutner.privacybrowser;
2
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;
29 import java.net.URL;
30 import java.net.URLEncoder;
31
32 public class Webview extends AppCompatActivity {
33
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";
41
42     @Override
43     protected void onCreate(Bundle savedInstanceState) {
44         super.onCreate(savedInstanceState);
45         setContentView(R.layout.activity_webview);
46
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);
52
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);
58         }
59
60         // Implement swipe down to refresh.
61         swipeToRefresh.setColorSchemeColors(0xFF0097FF);
62         swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
63             @Override
64             public void onRefresh() {
65                 mainWebView.loadUrl(formattedUrlString);
66             }
67         });
68
69         // Only enable swipeToRefresh if is mainWebView is scrolled to the top.
70         mainWebView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
71             @Override
72             public void onScrollChanged() {
73                 if (mainWebView.getScrollY() == 0) {
74                     swipeToRefresh.setEnabled(true);
75                 } else {
76                     swipeToRefresh.setEnabled(false);
77                 }
78             }
79         });
80
81         mainWebView.setWebViewClient(new WebViewClient() {
82
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.
85             @Override
86             public boolean shouldOverrideUrlLoading(WebView view, String url) {
87                 mainWebView.loadUrl(url);
88                 return true;
89             }
90
91             // Update the URL in urlTextBox when the page starts to load.
92             @Override
93             public void onPageStarted(WebView view, String url, Bitmap favicon) {
94                 urlTextBox.setText(url);
95             }
96
97             // Update formattedUrlString and urlTextBox.  It is necessary to do this after the page finishes loading because the final URL can change during load.
98             @Override
99             public void onPageFinished(WebView view, String url) {
100                 formattedUrlString = url;
101                 urlTextBox.setText(formattedUrlString);
102             }
103         });
104
105         mainWebView.setWebChromeClient(new WebChromeClient() {
106
107             // Update the progress bar when a page is loading.
108             @Override
109             public void onProgressChanged(WebView view, int progress) {
110                 progressBar.setProgress(progress);
111                 if (progress < 100) {
112                     progressBar.setVisibility(View.VISIBLE);
113                 } else {
114                     progressBar.setVisibility(View.GONE);
115
116                     // Stop the refreshing indicator if it is running.
117                     swipeToRefresh.setRefreshing(false);
118                 }
119             }
120
121             // Set the favorite icon when it changes.
122             @Override
123             public void onReceivedIcon(WebView view, Bitmap icon) {
124                 favoriteIcon.setImageBitmap(icon);
125             }
126         });
127
128         // Set the "go" button on the keyboard to load the URL.
129         urlTextBox.setOnKeyListener(new View.OnKeyListener() {
130             public boolean onKey(View v, int keyCode, KeyEvent event) {
131
132                 // If the event is a key-down event on the "enter" button, load the URL.
133                 if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
134                         (keyCode == KeyEvent.KEYCODE_ENTER)) {
135                     // Load the URL into the mainWebView and consume the event.
136                     try {
137                         loadUrlFromTextBox(mainWebView);
138                     } catch (UnsupportedEncodingException e) {
139                         e.printStackTrace();
140                     }
141                     // If the enter key was pressed, consume the event.
142                     return true;
143                 }
144                 // If any other key was pressed, do not consume the event.
145                 return false;
146             }
147         });
148
149         // Allow pinch to zoom.
150         mainWebView.getSettings().setBuiltInZoomControls(true);
151
152         // Hide zoom controls.
153         mainWebView.getSettings().setDisplayZoomControls(false);
154
155         // Enable JavaScript.
156         mainWebView.getSettings().setJavaScriptEnabled(true);
157
158         // Enable DOM Storage.
159         mainWebView.getSettings().setDomStorageEnabled(true);
160
161         // Get the intent information that started the app.
162         final Intent intent = getIntent();
163
164         if (intent.getData() != null) {
165             // Get the intent data and convert it to a string.
166             final Uri intentUriData = intent.getData();
167             formattedUrlString = intentUriData.toString();
168         }
169
170         // If formattedUrlString is null assign the homepage to it.
171         if (formattedUrlString == null) {
172             formattedUrlString = homepage;
173         }
174
175         // Load the initial website.
176         mainWebView.loadUrl(formattedUrlString);
177     }
178
179     @Override
180     public boolean onCreateOptionsMenu(Menu menu) {
181         // Inflate the menu; this adds items to the action bar if it is present.
182         getMenuInflater().inflate(R.menu.menu_webview, menu);
183         return true;
184     }
185
186     @Override
187     public boolean onOptionsItemSelected(MenuItem menuItem) {
188         int menuItemId = menuItem.getItemId();
189
190         // Sets the commands that relate to the menu entries.
191         switch (menuItemId) {
192             case R.id.home:
193                 mainWebView.loadUrl(homepage);
194                 break;
195
196             case R.id.back:
197                 mainWebView.goBack();
198                 break;
199
200             case R.id.forward:
201                 mainWebView.goForward();
202                 break;
203         }
204
205         return super.onOptionsItemSelected(menuItem);
206     }
207
208     // Override onBackPressed so that if mainWebView can go back it does when the system back button is pressed.
209     @Override
210     public void onBackPressed() {
211         if (mainWebView.canGoBack()) {
212             mainWebView.goBack();
213         } else {
214             super.onBackPressed();
215         }
216     }
217
218     public void loadUrlFromTextBox(View view) throws UnsupportedEncodingException {
219         // Get the text from urlTextInput and convert it to a string.
220         String unformattedUrlString = urlTextBox.getText().toString();
221         URL unformattedUrl = null;
222         Uri.Builder formattedUri = new Uri.Builder();
223         String scheme;
224
225         // Check to see if unformattedUrlString is a valid URL.  Otherwise, convert it into a Duck Duck Go search.
226         if (Patterns.WEB_URL.matcher(unformattedUrlString).matches()) {
227
228             // Add http:// at the beginning if it is missing.  Otherwise the app will segfault.
229             if (!unformattedUrlString.startsWith("http")) {
230                 unformattedUrlString = "http://" + unformattedUrlString;
231             }
232
233             // 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.
234             try {
235                 unformattedUrl = new URL(unformattedUrlString);
236             } catch (MalformedURLException e) {
237                 e.printStackTrace();
238             }
239
240             if (unformattedUrl.getProtocol() != null) {
241                 scheme = unformattedUrl.getProtocol();
242             } else {
243                 scheme = "http";
244             }
245
246             final String authority = unformattedUrl.getAuthority();
247             final String path = unformattedUrl.getPath();
248             final String query = unformattedUrl.getQuery();
249             final String fragment = unformattedUrl.getRef();
250
251             formattedUri.scheme(scheme).authority(authority).path(path).query(query).fragment(fragment);
252             formattedUrlString = formattedUri.build().toString();
253
254         } else {
255             // Sanitize the search input.
256             final String encodedUrlString = URLEncoder.encode(unformattedUrlString, "UTF-8");
257             formattedUrlString = "https://duckduckgo.com/?q=" + encodedUrlString;
258         }
259
260         // Place formattedUrlString back in the address bar and load the website.
261         mainWebView.loadUrl(formattedUrlString);
262
263         // Hides the keyboard so we can see the webpage.
264         InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
265         inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
266     }
267 }