import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
+import android.webkit.WebViewDatabase;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class MainWebViewActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, CreateHomeScreenShortcut.CreateHomeScreenSchortcutListener {
// favoriteIcon is public static so it can be accessed from CreateHomeScreenShortcut.
public static Bitmap favoriteIcon;
- // mainWebView is public static so it can be accessed from AboutDialog and SettingsFragment. It is also used in onCreate(), onOptionsItemSelected(), onNavigationItemSelected(), and loadUrlFromTextBox().
+ // mainWebView is public static so it can be accessed from SettingsFragment. It is also used in onCreate(), onOptionsItemSelected(), onNavigationItemSelected(), and loadUrlFromTextBox().
public static WebView mainWebView;
// mainMenu is public static so it can be accessed from SettingsFragment. It is also used in onCreateOptionsMenu() and onOptionsItemSelected().
public static boolean javaScriptEnabled;
// firstPartyCookiesEnabled is public static so it can be accessed from SettingsFragment. It is also used in onCreate(), onCreateOptionsMenu(), onPrepareOptionsMenu(), and onOptionsItemSelected().
public static boolean firstPartyCookiesEnabled;
- // thirdPartyCookiesEnabled is uesd in onCreate(), onCreateOptionsMenu(), onPrepareOptionsMenu(), and onOptionsItemSelected().
+ // thirdPartyCookiesEnabled is used in onCreate(), onCreateOptionsMenu(), onPrepareOptionsMenu(), and onOptionsItemSelected().
public static boolean thirdPartyCookiesEnabled;
// domStorageEnabled is public static so it can be accessed from SettingsFragment. It is also used in onCreate(), onCreateOptionsMenu(), and onOptionsItemSelected().
public static boolean domStorageEnabled;
+ // saveFormDataEnabled is public static so it can be accessed from SettingsFragment. It is also used in onCreate(), onCreateOptionsMenu(), and onOptionsItemSelected().
+ public static boolean saveFormDataEnabled;
// javaScriptDisabledSearchURL is public static so it can be accessed from SettingsFragment. It is also used in onCreate() and loadURLFromTextBox().
public static String javaScriptDisabledSearchURL;
// javaScriptEnabledSearchURL is public static so it can be accessed from SettingsFragment. It is also used in onCreate() and loadURLFromTextBox().
@SuppressLint("SetJavaScriptEnabled")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.coordinator_layout);
+ setContentView(R.layout.main_coordinatorlayout);
// We need to use the SupportActionBar from android.support.v7.app.ActionBar until the minimum API is >= 21.
Toolbar supportAppBar = (Toolbar) findViewById(R.id.appBar);
setSupportActionBar(supportAppBar);
+ final ActionBar appBar = getSupportActionBar();
- final FrameLayout fullScreenVideoFrameLayout = (FrameLayout) findViewById(R.id.fullScreenVideoFrameLayout);
+ // This is needed to get rid of the Android Studio warning that appBar might be null.
+ assert appBar != null;
+
+ // Add the custom url_bar layout, which shows the favoriteIcon, urlTextBar, and progressBar.
+ appBar.setCustomView(R.layout.url_bar);
+ appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+
+ // Set the "go" button on the keyboard to load the URL in urlTextBox.
+ urlTextBox = (EditText) appBar.getCustomView().findViewById(R.id.urlTextBox);
+ urlTextBox.setOnKeyListener(new View.OnKeyListener() {
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ // If the event is a key-down event on the "enter" button, load the URL.
+ if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
+ // Load the URL into the mainWebView and consume the event.
+ try {
+ loadUrlFromTextBox();
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ // If the enter key was pressed, consume the event.
+ return true;
+ } else {
+ // If any other key was pressed, do not consume the event.
+ return false;
+ }
+ }
+ });
- // We need to use the SupportActionBar from android.support.v7.app.ActionBar until the minimum API is >= 21.
- final ActionBar appBar = getSupportActionBar();
+ final FrameLayout fullScreenVideoFrameLayout = (FrameLayout) findViewById(R.id.fullScreenVideoFrameLayout);
// Implement swipe to refresh
swipeToRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
+ assert swipeToRefresh != null; //This assert removes the incorrect warning on the following line that swipeToRefresh might be null.
swipeToRefresh.setColorSchemeResources(R.color.blue);
swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
mainWebView = (WebView) findViewById(R.id.mainWebView);
- if (appBar != null) {
- // Add the custom url_bar layout, which shows the favoriteIcon, urlTextBar, and progressBar.
- appBar.setCustomView(R.layout.url_bar);
- appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
-
- // Set the "go" button on the keyboard to load the URL in urlTextBox.
- urlTextBox = (EditText) appBar.getCustomView().findViewById(R.id.urlTextBox);
- urlTextBox.setOnKeyListener(new View.OnKeyListener() {
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- // If the event is a key-down event on the "enter" button, load the URL.
- if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
- // Load the URL into the mainWebView and consume the event.
- try {
- loadUrlFromTextBox();
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- // If the enter key was pressed, consume the event.
- return true;
- } else {
- // If any other key was pressed, do not consume the event.
- return false;
- }
- }
- });
- }
-
// Create the navigation drawer.
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
// The DrawerTitle identifies the drawer in accessibility mode.
// Listen for touches on the navigation menu.
final NavigationView navigationView = (NavigationView) findViewById(R.id.navigationView);
+ assert navigationView != null; // This assert removes the incorrect warning on the following line that navigationView might be null.
navigationView.setNavigationItemSelectedListener(this);
// drawerToggle creates the hamburger icon at the start of the AppBar.
// Update the progress bar when a page is loading.
@Override
public void onProgressChanged(WebView view, int progress) {
- // Make sure that appBar is not null.
- if (appBar != null) {
- ProgressBar progressBar = (ProgressBar) appBar.getCustomView().findViewById(R.id.progressBar);
- progressBar.setProgress(progress);
- if (progress < 100) {
- progressBar.setVisibility(View.VISIBLE);
- } else {
- progressBar.setVisibility(View.GONE);
+ ProgressBar progressBar = (ProgressBar) appBar.getCustomView().findViewById(R.id.progressBar);
+ progressBar.setProgress(progress);
+ if (progress < 100) {
+ progressBar.setVisibility(View.VISIBLE);
+ } else {
+ progressBar.setVisibility(View.GONE);
- //Stop the SwipeToRefresh indicator if it is running
- swipeToRefresh.setRefreshing(false);
- }
+ //Stop the SwipeToRefresh indicator if it is running
+ swipeToRefresh.setRefreshing(false);
}
}
// Save a copy of the favorite icon for use if a shortcut is added to the home screen.
favoriteIcon = icon;
- // Place the favorite icon in the appBar if it is not null.
- if (appBar != null) {
- ImageView imageViewFavoriteIcon = (ImageView) appBar.getCustomView().findViewById(R.id.favoriteIcon);
- imageViewFavoriteIcon.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true));
- }
+ // Place the favorite icon in the appBar.
+ ImageView imageViewFavoriteIcon = (ImageView) appBar.getCustomView().findViewById(R.id.favoriteIcon);
+ imageViewFavoriteIcon.setImageBitmap(Bitmap.createScaledBitmap(icon, 64, 64, true));
}
// Enter full screen video
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
- if (appBar != null) {
- appBar.hide();
- }
+ appBar.hide();
// Show the fullScreenVideoFrameLayout.
+ assert fullScreenVideoFrameLayout != null; //This assert removes the incorrect warning on the following line that fullScreenVideoFrameLayout might be null.
fullScreenVideoFrameLayout.addView(view);
fullScreenVideoFrameLayout.setVisibility(View.VISIBLE);
BannerAd.hideAd(adView);
/* SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bars on the bottom or right of the screen.
- ** SYSTEM_UI_FLAG_FULLSCREEN hides the status bar across the top of the screen.
- ** SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the navigation and status bars ghosted overlays and automatically rehides them.
- */
-
- // Set the one flag supported by API >= 14.
- view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
-
- // Set the two flags that are supported by API >= 16.
- if (Build.VERSION.SDK_INT >= 16) {
- view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN);
- }
-
- // Set all three flags that are supported by API >= 19.
- if (Build.VERSION.SDK_INT >= 19) {
- view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
- }
+ * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar across the top of the screen.
+ * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the navigation and status bars ghosted overlays and automatically rehides them.
+ */
+ view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
// Exit full screen video
public void onHideCustomView() {
- if (appBar != null) {
- appBar.show();
- }
+ appBar.show();
// Show the mainWebView.
mainWebView.setVisibility(View.VISIBLE);
BannerAd.showAd(adView);
// Hide the fullScreenVideoFrameLayout.
+ assert fullScreenVideoFrameLayout != null; //This assert removes the incorrect warning on the following line that fullScreenVideoFrameLayout might be null.
fullScreenVideoFrameLayout.removeAllViews();
fullScreenVideoFrameLayout.setVisibility(View.GONE);
}
domStorageEnabled = savedPreferences.getBoolean("dom_storage_enabled", false);
mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
+ // Set the saved form data initial status. The default is false.
+ saveFormDataEnabled = savedPreferences.getBoolean("save_form_data_enabled", false);
+ mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
+
// Set the user agent initial status.
String userAgentString = savedPreferences.getString("user_agent", "Default user agent");
switch (userAgentString) {
MenuItem toggleFirstPartyCookies = menu.findItem(R.id.toggleFirstPartyCookies);
MenuItem toggleThirdPartyCookies = menu.findItem(R.id.toggleThirdPartyCookies);
MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
- /* toggleSaveFormData does nothing until database storage is implemented.
MenuItem toggleSaveFormData = menu.findItem(R.id.toggleSaveFormData);
- */
// Set the initial status of the privacy icon.
updatePrivacyIcon();
toggleFirstPartyCookies.setChecked(firstPartyCookiesEnabled);
toggleThirdPartyCookies.setChecked(thirdPartyCookiesEnabled);
toggleDomStorage.setChecked(domStorageEnabled);
- /* toggleSaveFormData does nothing until database storage is implemented.
toggleSaveFormData.setChecked(saveFormDataEnabled);
- */
return true;
}
toggleThirdPartyCookies.setEnabled(false);
}
+ // Enable DOM Storage if JavaScript is enabled.
+ MenuItem toggleDomStorage = menu.findItem(R.id.toggleDomStorage);
+ toggleDomStorage.setEnabled(javaScriptEnabled);
+
// Enable Clear Cookies if there are any.
MenuItem clearCookies = menu.findItem(R.id.clearCookies);
clearCookies.setEnabled(cookieManager.hasCookies());
+ // Enable Clear Form Data is there is any.
+ MenuItem clearFormData = menu.findItem(R.id.clearFormData);
+ WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this);
+ clearFormData.setEnabled(mainWebViewDatabase.hasFormData());
+
// Run all the other default commands.
super.onPrepareOptionsMenu(menu);
public boolean onOptionsItemSelected(MenuItem menuItem) {
int menuItemId = menuItem.getItemId();
- // Some options need to update the drawable for toggleJavaScript.
- MenuItem toggleJavaScript = mainMenu.findItem(R.id.toggleJavaScript);
-
// Set the commands that relate to the menu entries.
switch (menuItemId) {
case R.id.toggleJavaScript:
if (javaScriptEnabled) {
Snackbar.make(findViewById(R.id.mainWebView), R.string.javascript_enabled, Snackbar.LENGTH_SHORT).show();
} else {
- if (domStorageEnabled || firstPartyCookiesEnabled) {
+ if (firstPartyCookiesEnabled) {
Snackbar.make(findViewById(R.id.mainWebView), R.string.javascript_disabled, Snackbar.LENGTH_SHORT).show();
} else {
Snackbar.make(findViewById(R.id.mainWebView), R.string.privacy_mode, Snackbar.LENGTH_SHORT).show();
// Apply the new DOM Storage status.
mainWebView.getSettings().setDomStorageEnabled(domStorageEnabled);
- // Update the privacy icon.
- updatePrivacyIcon();
+ // Reload the WebView.
+ mainWebView.reload();
+ return true;
+
+ case R.id.toggleSaveFormData:
+ // Switch the status of saveFormDataEnabled.
+ saveFormDataEnabled = !saveFormDataEnabled;
+
+ // Update the menu checkbox.
+ menuItem.setChecked(saveFormDataEnabled);
+
+ // Apply the new form data status.
+ mainWebView.getSettings().setSaveFormData(saveFormDataEnabled);
// Reload the WebView.
mainWebView.reload();
Snackbar.make(findViewById(R.id.mainWebView), R.string.dom_storage_deleted, Snackbar.LENGTH_SHORT).show();
return true;
+ case R.id.clearFormData:
+ WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(this);
+ mainWebViewDatabase.clearFormData();
+ mainWebView.reload();
+ return true;
+
case R.id.share:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
startActivity(downloadManagerIntent);
break;
+ case R.id.guide:
+ // Launch GuideActivity.
+ Intent guideIntent = new Intent(this, GuideActivity.class);
+ startActivity(guideIntent);
+ break;
+
case R.id.settings:
- // Launch PreferenceFragment.
- Intent intent = new Intent(this, SettingsActivity.class);
- startActivity(intent);
+ // Launch SettingsActivity.
+ Intent settingsIntent = new Intent(this, SettingsActivity.class);
+ startActivity(settingsIntent);
break;
case R.id.about:
- // Show the AboutDialog AlertDialog and name this instance aboutDialog.
- AppCompatDialogFragment aboutDialog = new AboutDialog();
- aboutDialog.show(getSupportFragmentManager(), "aboutDialog");
+ // Launch AboutActivity.
+ Intent aboutIntent = new Intent(this, AboutActivity.class);
+ startActivity(aboutIntent);
break;
case R.id.clearAndExit:
- // Clear DOM storage.
- WebStorage domStorage = WebStorage.getInstance();
- domStorage.deleteAllData();
-
// Clear cookies. The commands changed slightly in API 21.
if (Build.VERSION.SDK_INT >= 21) {
cookieManager.removeAllCookies(null);
cookieManager.removeAllCookie();
}
+ // Clear DOM storage.
+ WebStorage domStorage = WebStorage.getInstance();
+ domStorage.deleteAllData();
+
+ // Clear cache. The argument of "true" includes disk files.
+ mainWebView.clearCache(true);
+
+ // Clear the back/forward history.
+ mainWebView.clearHistory();
+
// Destroy the internal state of the webview.
mainWebView.destroy();
// Reload the ad if this is the free flavor.
BannerAd.reloadAfterRotate(adView, getApplicationContext(), getString(R.string.ad_id));
- // Reinitialize the adView variable, as the View will have been removed and readded in the free flavor by BannerAd.reloadAfterRotate().
+ // Reinitialize the adView variable, as the View will have been removed and re-added in the free flavor by BannerAd.reloadAfterRotate().
adView = findViewById(R.id.adView);
}
drawerLayout.closeDrawer(GravityCompat.START);
} else {
// Load the previous URL if available.
+ assert mainWebView != null; //This assert removes the incorrect warning in Android Studio on the following line that mainWebView might be null.
if (mainWebView.canGoBack()) {
mainWebView.goBack();
} else {
}
private void loadUrlFromTextBox() throws UnsupportedEncodingException {
- // Get the text from urlTextBox and convert it to a string.
- String unformattedUrlString = urlTextBox.getText().toString();
+ // Get the text from urlTextBox and convert it to a string. trim() removes white spaces from the beginning and end of the string.
+ String unformattedUrlString = urlTextBox.getText().toString().trim();
+
URL unformattedUrl = null;
Uri.Builder formattedUri = new Uri.Builder();
if (javaScriptEnabled) {
privacyIcon.setIcon(R.drawable.javascript_enabled);
} else {
- if (domStorageEnabled || firstPartyCookiesEnabled) {
+ if (firstPartyCookiesEnabled) {
privacyIcon.setIcon(R.drawable.warning);
} else {
privacyIcon.setIcon(R.drawable.privacy_mode);