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