lightning-i2p/src/acr/browser/lightning/IncognitoActivity.java
Anthony Restaino 97f86630d8 Bugfixes
Fixed bug where homescreen didn't display for custom search URLS.

Fixed bug where exit button on tabs didn't work.

Fixed bug where special characters weren't properly encoded in searches

Updated homepage to be more modern and holo styled
2014-05-10 11:32:29 -04:00

2277 lines
64 KiB
Java

/*
* Copyright 2014 A.C.R. Development
*/
package acr.browser.lightning;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import acr.browser.lightning.BrowserActivity.SortIgnoreCase;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Message;
import android.provider.Browser;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient.CustomViewCallback;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebIconDatabase;
import android.webkit.WebView;
import android.webkit.WebView.HitTestResult;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.AutoCompleteTextView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;
import android.widget.TextView.OnEditorActionListener;
public class IncognitoActivity extends Activity implements BrowserController {
private static DrawerLayout mDrawerLayout;
private static ListView mDrawerList;
private static RelativeLayout mDrawer;
private static LinearLayout mDrawerRight;
private static ListView mDrawerListRight;
private static TextView mNewTab;
private static ActionBarDrawerToggle mDrawerToggle;
private List<LightningView> mWebViews = new ArrayList<LightningView>();
private static List<Integer> mIdList = new ArrayList<Integer>();
private LightningView mCurrentView;
private static int mIdGenerator;
private static LightningViewAdapter mTitleAdapter;
private static List<HistoryItem> mBookmarkList;
private static BookmarkViewAdapter mBookmarkAdapter;
private static AutoCompleteTextView mSearch;
private static ClickHandler mClickHandler;
private static ProgressBar mProgress;
private static boolean mSystemBrowser = false;
private static ValueCallback<Uri> mUploadMessage;
private static View mCustomView;
private static int mOriginalOrientation;
private static int mActionBarSize;
private static ActionBar mActionBar;
private static boolean mFullScreen;
private static FrameLayout mBrowserFrame;
private static FullscreenHolder mFullscreenContainer;
private static CustomViewCallback mCustomViewCallback;
private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
private static Bitmap mDefaultVideoPoster;
private static View mVideoProgressView;
private static DatabaseHandler mHistoryHandler;
private static SQLiteDatabase mHistoryDatabase;
private static SharedPreferences mPreferences;
private static SharedPreferences.Editor mEditPrefs;
private static Context mContext;
private static Bitmap mWebpageBitmap;
private static String mSearchText;
private static Activity mActivity;
private static CookieManager mCookieManager;
private static final int API = android.os.Build.VERSION.SDK_INT;
private static Drawable mDeleteIcon;
private static Drawable mRefreshIcon;
private static Drawable mCopyIcon;
private static Drawable mIcon;
private static int mActionBarSizeDp;
private static String mHomepage;
private static boolean mIsNewIntent = false;
private static VideoView mVideoView;
private static SearchAdapter mSearchAdapter;
private static BitmapDrawable mIncognitoIcon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initialize();
}
private synchronized void initialize() {
setContentView(R.layout.activity_main);
TypedValue typedValue = new TypedValue();
Theme theme = getTheme();
theme.resolveAttribute(R.attr.numberColor, typedValue, true);
mPreferences = getSharedPreferences(PreferenceConstants.PREFERENCES, 0);
mEditPrefs = mPreferences.edit();
mContext = this;
if (mIdList != null) {
mIdList.clear();
} else {
mIdList = new ArrayList<Integer>();
}
if (mWebViews != null) {
mWebViews.clear();
} else {
mWebViews = new ArrayList<LightningView>();
}
mActivity = this;
mClickHandler = new ClickHandler(this);
mBrowserFrame = (FrameLayout) findViewById(R.id.content_frame);
mProgress = (ProgressBar) findViewById(R.id.activity_bar);
mProgress.setVisibility(View.GONE);
mNewTab = (TextView) findViewById(R.id.new_tab_button);
mDrawer = (RelativeLayout) findViewById(R.id.drawer);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerRight = (LinearLayout) findViewById(R.id.right_drawer);
mDrawerListRight = (ListView) findViewById(R.id.right_drawer_list);
Bitmap bm = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_action_incognito);
mIncognitoIcon = new BitmapDrawable(getResources(), bm);
mWebpageBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_webpage);
mActionBar = getActionBar();
final TypedArray styledAttributes = mContext.getTheme()
.obtainStyledAttributes(
new int[] { android.R.attr.actionBarSize });
mActionBarSize = (int) styledAttributes.getDimension(0, 0);
if (pixelsToDp(mActionBarSize) < 48) {
mActionBarSize = getDp(48);
}
mActionBarSizeDp = pixelsToDp(mActionBarSize);
styledAttributes.recycle();
mHomepage = mPreferences.getString(PreferenceConstants.HOMEPAGE,
Constants.HOMEPAGE);
mTitleAdapter = new LightningViewAdapter(this, R.layout.tab_list_item,
mWebViews);
mDrawerList.setAdapter(mTitleAdapter);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
mDrawerList
.setOnItemLongClickListener(new DrawerItemLongClickListener());
mBookmarkList = getBookmarks();
mBookmarkAdapter = new BookmarkViewAdapter(this,
R.layout.bookmark_list_item, mBookmarkList);
mDrawerListRight.setAdapter(mBookmarkAdapter);
mDrawerListRight
.setOnItemClickListener(new BookmarkItemClickListener());
mDrawerListRight
.setOnItemLongClickListener(new BookmarkItemLongClickListener());
if (mHistoryHandler == null) {
mHistoryHandler = new DatabaseHandler(this);
} else if (!mHistoryHandler.isOpen()) {
mHistoryHandler = new DatabaseHandler(this);
}
mHistoryDatabase = mHistoryHandler.getReadableDatabase();
// set display options of the ActionBar
mActionBar.setDisplayShowTitleEnabled(false);
mActionBar.setDisplayShowCustomEnabled(true);
mActionBar.setDisplayShowHomeEnabled(true);
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setCustomView(R.layout.search);
RelativeLayout back = (RelativeLayout) findViewById(R.id.action_back);
RelativeLayout forward = (RelativeLayout) findViewById(R.id.action_forward);
if (back != null) {
back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrentView != null) {
if (mCurrentView.canGoBack()) {
mCurrentView.goBack();
} else {
deleteTab(mDrawerList.getCheckedItemPosition());
}
}
}
});
}
if (forward != null) {
forward.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrentView != null) {
if (mCurrentView.canGoForward()) {
mCurrentView.goForward();
}
}
}
});
}
// create the search EditText in the ActionBar
mSearch = (AutoCompleteTextView) mActionBar.getCustomView()
.findViewById(R.id.search);
mDeleteIcon = getResources().getDrawable(R.drawable.ic_action_delete);
mDeleteIcon.setBounds(0, 0, Utils.convertToDensityPixels(mContext, 24),
Utils.convertToDensityPixels(mContext, 24));
mRefreshIcon = getResources().getDrawable(R.drawable.ic_action_refresh);
mRefreshIcon.setBounds(0, 0,
Utils.convertToDensityPixels(mContext, 24),
Utils.convertToDensityPixels(mContext, 24));
mCopyIcon = getResources().getDrawable(R.drawable.ic_action_copy);
mCopyIcon.setBounds(0, 0, Utils.convertToDensityPixels(mContext, 24),
Utils.convertToDensityPixels(mContext, 24));
mIcon = mRefreshIcon;
mSearch.setCompoundDrawables(null, null, mRefreshIcon, null);
mSearch.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
switch (arg1) {
case KeyEvent.KEYCODE_ENTER:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearch.getWindowToken(), 0);
searchTheWeb(mSearch.getText().toString());
if (mCurrentView != null) {
mCurrentView.requestFocus();
}
return true;
default:
break;
}
return false;
}
});
mSearch.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus && mCurrentView != null) {
if (mCurrentView != null) {
if (mCurrentView.getProgress() < 100) {
setIsLoading();
} else {
setIsFinishedLoading();
}
}
updateUrl(mCurrentView.getUrl());
} else if (hasFocus) {
mIcon = mCopyIcon;
mSearch.setCompoundDrawables(null, null, mCopyIcon, null);
}
}
});
mSearch.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView arg0, int actionId,
KeyEvent arg2) {
// hide the keyboard and search the web when the enter key
// button is pressed
if (actionId == EditorInfo.IME_ACTION_GO
|| actionId == EditorInfo.IME_ACTION_DONE
|| actionId == EditorInfo.IME_ACTION_NEXT
|| actionId == EditorInfo.IME_ACTION_SEND
|| actionId == EditorInfo.IME_ACTION_SEARCH
|| (arg2.getAction() == KeyEvent.KEYCODE_ENTER)) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearch.getWindowToken(), 0);
searchTheWeb(mSearch.getText().toString());
if (mCurrentView != null) {
mCurrentView.requestFocus();
}
return true;
}
return false;
}
});
mSearch.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mSearch.getCompoundDrawables()[2] != null) {
boolean tappedX = event.getX() > (mSearch.getWidth()
- mSearch.getPaddingRight() - mIcon
.getIntrinsicWidth());
if (tappedX) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (mSearch.hasFocus()) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label",
mSearch.getText().toString());
clipboard.setPrimaryClip(clip);
Utils.showToast(
mContext,
mContext.getResources().getString(
R.string.message_text_copied));
} else {
refreshOrStop();
}
}
return true;
}
}
return false;
}
});
mSystemBrowser = getSystemBrowser();
Thread initialize = new Thread(new Runnable() {
@Override
public void run() {
initializeSearchSuggestions(mSearch);
}
});
initialize.run();
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
if (view.equals(mDrawer)) {
mDrawerLayout.setDrawerLockMode(
DrawerLayout.LOCK_MODE_UNLOCKED, mDrawerRight);
} else if (view.equals(mDrawerRight)) {
mDrawerLayout.setDrawerLockMode(
DrawerLayout.LOCK_MODE_UNLOCKED, mDrawer);
}
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (drawerView.equals(mDrawer)) {
mDrawerLayout.closeDrawer(mDrawerRight);
mDrawerLayout.setDrawerLockMode(
DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawerRight);
} else if (drawerView.equals(mDrawerRight)) {
mDrawerLayout.closeDrawer(mDrawer);
mDrawerLayout.setDrawerLockMode(
DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawer);
}
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
}
};
mNewTab.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
newTab(null, true);
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
initializePreferences();
initializeTabs();
if (API < 19) {
WebIconDatabase.getInstance().open(
getDir("icons", MODE_PRIVATE).getPath());
}
}
public synchronized void initializeTabs() {
mIdGenerator = 0;
String url = null;
newTab(url, true);
}
public static String[] getArray(String input) {
return input.split("\\|\\$\\|SEPARATOR\\|\\$\\|");
}
public void initializePreferences() {
if (mPreferences == null) {
mPreferences = getSharedPreferences(
PreferenceConstants.PREFERENCES, 0);
}
mFullScreen = mPreferences.getBoolean(PreferenceConstants.FULL_SCREEN,
false);
if (mPreferences.getBoolean(PreferenceConstants.HIDE_STATUS_BAR, false)) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
switch (mPreferences.getInt(PreferenceConstants.SEARCH, 1)) {
case 0:
mSearchText = mPreferences.getString(
PreferenceConstants.SEARCH_URL, Constants.GOOGLE_SEARCH);
if (!mSearchText.startsWith(Constants.HTTP)
&& !mSearchText.startsWith(Constants.HTTPS)) {
mSearchText = Constants.GOOGLE_SEARCH;
}
break;
case 1:
mSearchText = Constants.GOOGLE_SEARCH;
break;
case 2:
mSearchText = Constants.ANDROID_SEARCH;
break;
case 3:
mSearchText = Constants.BING_SEARCH;
break;
case 4:
mSearchText = Constants.YAHOO_SEARCH;
break;
case 5:
mSearchText = Constants.STARTPAGE_SEARCH;
break;
case 6:
mSearchText = Constants.STARTPAGE_MOBILE_SEARCH;
break;
case 7:
mSearchText = Constants.DUCK_SEARCH;
break;
case 8:
mSearchText = Constants.DUCK_LITE_SEARCH;
break;
case 9:
mSearchText = Constants.BAIDU_SEARCH;
break;
case 10:
mSearchText = Constants.YANDEX_SEARCH;
break;
}
mCookieManager = CookieManager.getInstance();
CookieSyncManager.createInstance(this);
mCookieManager.setAcceptCookie(mPreferences.getBoolean(
PreferenceConstants.INCOGNITO_COOKIES, true));
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
if (mSearch.hasFocus()) {
searchTheWeb(mSearch.getText().toString());
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.incognito, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content
// view
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch (item.getItemId()) {
case android.R.id.home:
if (mDrawerLayout.isDrawerOpen(mDrawerRight)) {
mDrawerLayout.closeDrawer(mDrawerRight);
}
mDrawerToggle.syncState();
return true;
case R.id.action_back:
if (mCurrentView != null) {
if (mCurrentView.canGoBack())
mCurrentView.goBack();
}
return true;
case R.id.action_forward:
if (mCurrentView != null) {
if (mCurrentView.canGoForward())
mCurrentView.goForward();
}
return true;
case R.id.action_new_tab:
newTab(null, true);
return true;
case R.id.action_incognito:
startActivity(new Intent(Constants.INCOGNITO_INTENT));
return true;
case R.id.action_share:
if (!mCurrentView.getUrl().startsWith(Constants.FILE)) {
Intent shareIntent = new Intent(
android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
mCurrentView.getTitle());
String shareMessage = mCurrentView.getUrl();
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT,
shareMessage);
startActivity(Intent.createChooser(shareIntent, getResources()
.getString(R.string.dialog_title_share)));
}
return true;
case R.id.action_bookmarks:
openBookmarks();
return true;
case R.id.action_copy:
if (mCurrentView != null) {
if (!mCurrentView.getUrl().startsWith(Constants.FILE)) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label", mCurrentView
.getUrl().toString());
clipboard.setPrimaryClip(clip);
Utils.showToast(mContext, mContext.getResources()
.getString(R.string.message_link_copied));
}
}
return true;
case R.id.action_settings:
startActivity(new Intent(Constants.SETTINGS_INTENT));
return true;
case R.id.action_history:
openHistory();
return true;
case R.id.action_add_bookmark:
if (!mCurrentView.getUrl().startsWith(Constants.FILE)) {
addBookmark(this, mCurrentView.getTitle(),
mCurrentView.getUrl());
}
return true;
case R.id.action_find:
findInPage();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* refreshes the underlying list of the Bookmark adapter since the bookmark
* adapter doesn't always change when notifyDataChanged gets called.
*/
private void notifyBookmarkDataSetChanged() {
mBookmarkAdapter.clear();
mBookmarkAdapter.addAll(mBookmarkList);
mBookmarkAdapter.notifyDataSetChanged();
}
/**
* method that shows a dialog asking what string the user wishes to search
* for. It highlights the text entered.
*/
private void findInPage() {
final AlertDialog.Builder finder = new AlertDialog.Builder(mActivity);
finder.setTitle(getResources().getString(R.string.action_find));
final EditText getHome = new EditText(this);
getHome.setHint(getResources().getString(R.string.search_hint));
finder.setView(getHome);
finder.setPositiveButton(
getResources().getString(R.string.search_hint),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String text = getHome.getText().toString();
if (mCurrentView != null) {
mCurrentView.find(text);
}
}
});
finder.show();
}
/** The click listener for ListView in the navigation drawer */
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
mIsNewIntent = false;
selectItem(position);
}
}
/** long click listener for Navigation Drawer */
private class DrawerItemLongClickListener implements
ListView.OnItemLongClickListener {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
deleteTab(position);
return false;
}
}
private class BookmarkItemClickListener implements
ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
if (mCurrentView != null) {
mCurrentView.loadUrl(mBookmarkList.get(position).getUrl());
}
mDrawerLayout.closeDrawer(mDrawerRight);
}
}
private class BookmarkItemLongClickListener implements
ListView.OnItemLongClickListener {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
final int position, long arg3) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(mContext.getResources().getString(
R.string.action_bookmarks));
builder.setMessage(
getResources().getString(R.string.dialog_bookmark))
.setCancelable(true)
.setPositiveButton(
getResources().getString(R.string.action_new_tab),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int id) {
newTab(mBookmarkList.get(position).getUrl(),
false);
mDrawerLayout.closeDrawers();
}
})
.setNegativeButton(
getResources().getString(R.string.action_delete),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
deleteBookmark(mBookmarkList.get(position)
.getUrl());
}
})
.setNeutralButton(
getResources().getString(R.string.action_edit),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
editBookmark(position);
}
});
AlertDialog alert = builder.create();
alert.show();
return true;
}
}
/**
* Takes in the id of which bookmark was selected and shows a dialog that
* allows the user to rename and change the url of the bookmark
*
* @param id
* which id in the list was chosen
*/
public synchronized void editBookmark(final int id) {
final AlertDialog.Builder homePicker = new AlertDialog.Builder(
mActivity);
homePicker.setTitle(getResources().getString(
R.string.title_edit_bookmark));
final EditText getTitle = new EditText(mContext);
getTitle.setHint(getResources().getString(R.string.hint_title));
getTitle.setText(mBookmarkList.get(id).getTitle());
getTitle.setSingleLine();
final EditText getUrl = new EditText(mContext);
getUrl.setHint(getResources().getString(R.string.hint_url));
getUrl.setText(mBookmarkList.get(id).getUrl());
getUrl.setSingleLine();
LinearLayout layout = new LinearLayout(mContext);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(getTitle);
layout.addView(getUrl);
homePicker.setView(layout);
homePicker.setPositiveButton(
getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mBookmarkList.get(id).setTitle(
getTitle.getText().toString());
mBookmarkList.get(id).setUrl(
getUrl.getText().toString());
notifyBookmarkDataSetChanged();
File book = new File(getFilesDir(), "bookmarks");
File bookUrl = new File(getFilesDir(), "bookurl");
try {
BufferedWriter bookWriter = new BufferedWriter(
new FileWriter(book));
BufferedWriter urlWriter = new BufferedWriter(
new FileWriter(bookUrl));
Iterator<HistoryItem> iter = mBookmarkList
.iterator();
HistoryItem item;
while (iter.hasNext()) {
item = iter.next();
bookWriter.write(item.getTitle());
urlWriter.write(item.getUrl());
bookWriter.newLine();
urlWriter.newLine();
}
bookWriter.close();
urlWriter.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
Collections.sort(mBookmarkList, new SortIgnoreCase());
notifyBookmarkDataSetChanged();
if (mCurrentView != null) {
if (mCurrentView.getUrl()
.startsWith(Constants.FILE)
&& mCurrentView.getUrl().endsWith(
"bookmarks.html")) {
openBookmarkPage(mCurrentView.getWebView());
}
}
}
});
homePicker.show();
}
/**
* displays the WebView contained in the LightningView Also handles the
* removal of previous views
*
* @param view
* the LightningView to show
*/
private synchronized void showTab(LightningView view) {
if (view == null) {
return;
}
if (mCurrentView != null) {
mCurrentView.onPause();
}
mCurrentView = view;
if (view.getWebView() != null) {
updateUrl(view.getUrl());
updateProgress(view.getProgress());
} else {
updateUrl("");
updateProgress(0);
}
mBrowserFrame.removeAllViews();
mCurrentView.onResume();
mBrowserFrame.addView(view.getWebView());
}
/**
* creates a new tab with the passed in URL if it isn't null
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (mCurrentView == null) {
initialize();
}
String url = null;
if (intent != null) {
url = intent.getDataString();
}
int num = 0;
if (intent != null && intent.getExtras() != null)
num = intent.getExtras().getInt(getPackageName() + ".Origin");
if (num == 1) {
mCurrentView.loadUrl(url);
} else if (url != null) {
url = null;
newTab(url, true);
mIsNewIntent = true;
}
}
private void selectItem(int position) {
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
showTab(mWebViews.get(position));
mDrawerLayout.closeDrawer(mDrawer);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
private synchronized void newTab(String url, boolean show) {
mIsNewIntent = false;
LightningView startingTab = new LightningView(mActivity, url);
if (mIdGenerator == 0) {
startingTab.resumeTimers();
}
mIdList.add(mIdGenerator);
mIdGenerator++;
mWebViews.add(startingTab);
Drawable icon = writeOnDrawable(mWebViews.size());
mActionBar.setIcon(icon);
mTitleAdapter.notifyDataSetChanged();
if (show) {
mDrawerList.setItemChecked(mWebViews.size() - 1, true);
showTab(startingTab);
}
}
private synchronized void deleteTab(int position) {
if (position >= mWebViews.size()) {
return;
}
int current = mDrawerList.getCheckedItemPosition();
LightningView reference = mWebViews.get(position);
if (reference == null) {
return;
}
boolean isShown = reference.isShown();
if (current > position) {
mIdList.remove(position);
mWebViews.remove(position);
mDrawerList.setItemChecked(current - 1, true);
reference.onDestroy();
} else if (mWebViews.size() > position + 1) {
mIdList.remove(position);
showTab(mWebViews.get(position + 1));
mWebViews.remove(position);
mDrawerList.setItemChecked(position, true);
reference.onDestroy();
} else if (mWebViews.size() > 1) {
mIdList.remove(position);
showTab(mWebViews.get(position - 1));
mWebViews.remove(position);
mDrawerList.setItemChecked(position - 1, true);
reference.onDestroy();
} else {
if (mCurrentView.getUrl().startsWith(Constants.FILE)
|| mCurrentView.getUrl().equals(mHomepage)) {
finish();
} else {
mIdList.remove(position);
mWebViews.remove(position);
if (mPreferences.getBoolean(
PreferenceConstants.CLEAR_CACHE_EXIT, false)
&& mCurrentView != null) {
mCurrentView.clearCache(true);
Log.i("Lightning", "Cache Cleared");
}
if (reference != null) {
reference.pauseTimers();
reference.onDestroy();
}
mCurrentView = null;
mTitleAdapter.notifyDataSetChanged();
finish();
}
}
mTitleAdapter.notifyDataSetChanged();
Drawable icon = writeOnDrawable(mWebViews.size());
mActionBar.setIcon(icon);
if (mIsNewIntent && isShown) {
mIsNewIntent = false;
finish();
}
Log.i("Lightning", "deleted tab");
}
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mPreferences.getBoolean(PreferenceConstants.CLEAR_CACHE_EXIT,
false) && mCurrentView != null) {
mCurrentView.clearCache(true);
Log.i("Lightning", "Cache Cleared");
}
mCurrentView = null;
for (int n = 0; n < mWebViews.size(); n++) {
if (mWebViews.get(n) != null)
mWebViews.get(n).onDestroy();
}
mWebViews.clear();
mTitleAdapter.notifyDataSetChanged();
finish();
}
return true;
}
@Override
public void onBackPressed() {
if (!mActionBar.isShowing()) {
mActionBar.show();
}
if (mDrawerLayout.isDrawerOpen(mDrawer)) {
mDrawerLayout.closeDrawer(mDrawer);
} else if (mDrawerLayout.isDrawerOpen(mDrawerRight)) {
mDrawerLayout.closeDrawer(mDrawerRight);
} else {
if (mCurrentView != null) {
Log.i("Lightning", "onBackPressed");
if (mCurrentView.canGoBack()) {
if (!mCurrentView.isShown()) {
onHideCustomView();
} else {
mCurrentView.goBack();
}
} else {
deleteTab(mDrawerList.getCheckedItemPosition());
}
} else {
Log.e("Lightning Browser",
"So madness. Much confusion. Why happen.");
super.onBackPressed();
}
}
}
@Override
protected void onPause() {
super.onPause();
Log.i("Lightning", "onPause");
if (mCurrentView != null) {
mCurrentView.pauseTimers();
mCurrentView.onPause();
}
if (mHistoryDatabase != null) {
if (mHistoryDatabase.isOpen())
mHistoryDatabase.close();
}
if (mHistoryHandler != null) {
if (mHistoryHandler.isOpen())
mHistoryHandler.close();
}
}
@Override
protected void onDestroy() {
Log.i("Lightning", "onDestroy");
if (mHistoryDatabase != null) {
if (mHistoryDatabase.isOpen())
mHistoryDatabase.close();
}
if (mHistoryHandler != null) {
if (mHistoryHandler.isOpen())
mHistoryHandler.close();
}
super.onDestroy();
}
@Override
protected void onPostResume() {
Log.i("Lightning", "onPostResume");
super.onPostResume();
}
@Override
protected void onRestart() {
Log.i("Lightning", "onRestart");
super.onRestart();
}
@Override
protected void onStart() {
Log.i("Lightning", "onStart");
super.onStart();
}
@Override
protected void onStop() {
Log.i("Lightning", "onStop");
super.onStop();
}
@Override
protected void onResume() {
super.onResume();
Log.i("Lightning", "onResume");
if (SettingsController.getClearHistory()) {
}
if (mSearchAdapter != null) {
mSearchAdapter.refreshPreferences();
mSearchAdapter.refreshBookmarks();
}
if (mActionBar != null) {
if (!mActionBar.isShowing()) {
mActionBar.show();
}
}
if (mCurrentView != null) {
mCurrentView.resumeTimers();
mCurrentView.onResume();
if (mHistoryHandler == null) {
mHistoryHandler = new DatabaseHandler(this);
} else if (!mHistoryHandler.isOpen()) {
mHistoryHandler = new DatabaseHandler(this);
}
mHistoryDatabase = mHistoryHandler.getReadableDatabase();
mBookmarkList = getBookmarks();
notifyBookmarkDataSetChanged();
} else {
initialize();
}
initializePreferences();
if (mWebViews != null) {
for (int n = 0; n < mWebViews.size(); n++) {
if (mWebViews.get(n) != null) {
mWebViews.get(n).initializePreferences(this);
} else {
mWebViews.remove(n);
}
}
} else {
initialize();
}
}
/**
* searches the web for the query fixing any and all problems with the input
* checks if it is a search, url, etc.
*/
void searchTheWeb(String query) {
if (query.equals("")) {
return;
}
String SEARCH = mSearchText;
query = query.trim();
mCurrentView.stopLoading();
if (query.startsWith("www.")) {
query = Constants.HTTP + query;
} else if (query.startsWith("ftp.")) {
query = "ftp://" + query;
}
boolean containsPeriod = query.contains(".");
boolean isIPAddress = (TextUtils.isDigitsOnly(query.replace(".", ""))
&& (query.replace(".", "").length() >= 4) && query
.contains("."));
boolean aboutScheme = query.contains("about:");
boolean validURL = (query.startsWith("ftp://")
|| query.startsWith(Constants.HTTP)
|| query.startsWith(Constants.FILE) || query
.startsWith(Constants.HTTPS)) || isIPAddress;
boolean isSearch = ((query.contains(" ") || !containsPeriod) && !aboutScheme);
if (isIPAddress
&& (!query.startsWith(Constants.HTTP) || !query
.startsWith(Constants.HTTPS))) {
query = Constants.HTTP + query;
}
if (isSearch) {
try {
query = URLEncoder.encode(query, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
mCurrentView.loadUrl(SEARCH + query);
} else if (!validURL) {
mCurrentView.loadUrl(Constants.HTTP + query);
} else {
mCurrentView.loadUrl(query);
}
}
public void deleteBookmark(String url) {
File book = new File(getFilesDir(), "bookmarks");
File bookUrl = new File(getFilesDir(), "bookurl");
try {
BufferedWriter bookWriter = new BufferedWriter(new FileWriter(book));
BufferedWriter urlWriter = new BufferedWriter(new FileWriter(
bookUrl));
Iterator<HistoryItem> iter = mBookmarkList.iterator();
HistoryItem item;
int num = 0;
int deleteIndex = -1;
while (iter.hasNext()) {
item = iter.next();
if (!item.getUrl().equalsIgnoreCase(url)) {
bookWriter.write(item.getTitle());
urlWriter.write(item.getUrl());
bookWriter.newLine();
urlWriter.newLine();
} else {
deleteIndex = num;
}
num++;
}
if (deleteIndex != -1) {
mBookmarkList.remove(deleteIndex);
}
bookWriter.close();
urlWriter.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
notifyBookmarkDataSetChanged();
mSearchAdapter.refreshBookmarks();
openBookmarks();
}
/**
* converts the int num into density pixels
*
* @param num
* @return density pixels
*/
private int getDp(int num) {
float scale = getResources().getDisplayMetrics().density;
return (int) (num * scale + 0.5f);
}
private int pixelsToDp(int num) {
float scale = getResources().getDisplayMetrics().density;
return (int) ((num - 0.5f) / scale);
}
/**
* writes the number of open tabs on the icon.
*/
public BitmapDrawable writeOnDrawable(int number) {
return mIncognitoIcon;
}
public class LightningViewAdapter extends ArrayAdapter<LightningView> {
Context context;
int layoutResourceId;
List<LightningView> data = null;
public LightningViewAdapter(Context context, int layoutResourceId,
List<LightningView> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
View row = convertView;
LightningViewHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new LightningViewHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.text1);
holder.favicon = (ImageView) row.findViewById(R.id.favicon1);
holder.exit = (ImageView) row.findViewById(R.id.delete1);
holder.exit.setTag(position);
row.setTag(holder);
} else {
holder = (LightningViewHolder) row.getTag();
}
holder.exit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
deleteTab(position);
}
});
LightningView web = data.get(position);
holder.txtTitle.setText(web.getTitle());
Bitmap favicon = web.getFavicon();
holder.favicon.setImageBitmap(favicon);
return row;
}
class LightningViewHolder {
TextView txtTitle;
ImageView favicon;
ImageView exit;
}
}
public class BookmarkViewAdapter extends ArrayAdapter<HistoryItem> {
Context context;
int layoutResourceId;
List<HistoryItem> data = null;
public BookmarkViewAdapter(Context context, int layoutResourceId,
List<HistoryItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
BookmarkViewHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context)
.getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new BookmarkViewHolder();
holder.txtTitle = (TextView) row.findViewById(R.id.text1);
holder.favicon = (ImageView) row.findViewById(R.id.favicon1);
row.setTag(holder);
} else {
holder = (BookmarkViewHolder) row.getTag();
}
HistoryItem web = data.get(position);
holder.txtTitle.setText(web.getTitle());
holder.favicon.setImageBitmap(mWebpageBitmap);
if (web.getBitmap() == null) {
getImage(holder.favicon, web);
} else {
holder.favicon.setImageBitmap(web.getBitmap());
}
return row;
}
class BookmarkViewHolder {
TextView txtTitle;
ImageView favicon;
}
}
public void getImage(ImageView image, HistoryItem web) {
try {
new DownloadImageTask(image, web).execute(Constants.HTTP
+ getDomainName(web.getUrl()) + "/favicon.ico");
} catch (URISyntaxException e) {
new DownloadImageTask(image, web)
.execute("https://www.google.com/s2/favicons?domain_url="
+ web.getUrl());
e.printStackTrace();
}
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
HistoryItem mWeb;
public DownloadImageTask(ImageView bmImage, HistoryItem web) {
this.bmImage = bmImage;
this.mWeb = web;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon = null;
// unique path for each url that is bookmarked.
String hash = String.valueOf(urldisplay.hashCode());
File image = new File(mContext.getCacheDir(), hash + ".png");
// checks to see if the image exists
if (!image.exists()) {
try {
// if not, download it...
InputStream in = new java.net.URL(urldisplay).openStream();
if (in != null) {
mIcon = BitmapFactory.decodeStream(in);
}
// ...and cache it
if (mIcon != null) {
FileOutputStream fos = new FileOutputStream(image);
mIcon.compress(Bitmap.CompressFormat.PNG, 85, fos);
fos.flush();
fos.close();
}
} catch (Exception e) {
}
} else {
// if it exists, retrieve it from the cache
mIcon = BitmapFactory.decodeFile(image.getPath());
}
if (mIcon == null) {
try {
// if not, download it...
InputStream in = new java.net.URL(
"https://www.google.com/s2/favicons?domain_url="
+ urldisplay).openStream();
if (in != null) {
mIcon = BitmapFactory.decodeStream(in);
}
// ...and cache it
if (mIcon != null) {
FileOutputStream fos = new FileOutputStream(image);
mIcon.compress(Bitmap.CompressFormat.PNG, 85, fos);
fos.flush();
fos.close();
}
} catch (Exception e) {
}
}
if (mIcon == null) {
return mWebpageBitmap;
} else {
return mIcon;
}
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
mWeb.setBitmap(result);
notifyBookmarkDataSetChanged();
}
}
public static String getDomainName(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
if (domain == null) {
return url;
}
return domain.startsWith("www.") ? domain.substring(4) : domain;
}
@Override
public void updateUrl(String url) {
if (url == null)
return;
url = url.replaceFirst(Constants.HTTP, "");
if (url.startsWith(Constants.FILE)) {
url = "";
}
mSearch.setText(url);
}
@Override
public void updateProgress(int n) {
if (!mProgress.isShown())
mProgress.setVisibility(View.VISIBLE);
mProgress.setProgress(n);
if (n == 100) {
mProgress.setVisibility(View.INVISIBLE);
setIsFinishedLoading();
} else {
setIsLoading();
}
}
@Override
public void updateHistory(final String title, final String url) {
}
/**
* 1, 2, 3, testing... is there a system browser that has some nice
* bookmarks for us?
*/
public boolean isSystemBrowserAvailable() {
return mSystemBrowser;
}
/**
* 1, 2, 3, testing... is there a system browser that has some nice
* bookmarks for us? helper method for isSystemBrowserAvailable
*/
public boolean getSystemBrowser() {
Cursor c = null;
String[] columns = new String[] { "url", "title" };
boolean browserFlag = false;
try {
Uri bookmarks = Browser.BOOKMARKS_URI;
c = getContentResolver()
.query(bookmarks, columns, null, null, null);
} catch (SQLiteException ignored) {
} catch (IllegalStateException ignored) {
} catch (NullPointerException ignored) {
}
if (c != null) {
Log.i("Browser", "System Browser Available");
browserFlag = true;
} else {
Log.e("Browser", "System Browser Unavailable");
browserFlag = false;
}
if (c != null) {
c.close();
c = null;
}
mEditPrefs.putBoolean("SystemBrowser", browserFlag);
mEditPrefs.commit();
return browserFlag;
}
/**
* method to generate search suggestions for the AutoCompleteTextView from
* previously searched URLs
*/
private void initializeSearchSuggestions(final AutoCompleteTextView getUrl) {
getUrl.setThreshold(1);
getUrl.setDropDownWidth(-1);
getUrl.setDropDownAnchor(R.id.progressWrapper);
getUrl.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
try {
String url;
url = ((TextView) arg1.findViewById(R.id.url)).getText()
.toString();
if (url.startsWith(mContext.getString(R.string.suggestion))) {
url = ((TextView) arg1.findViewById(R.id.title))
.getText().toString();
} else {
getUrl.setText(url);
}
searchTheWeb(url);
url = null;
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getUrl.getWindowToken(), 0);
if (mCurrentView != null) {
mCurrentView.requestFocus();
}
} catch (NullPointerException e) {
Log.e("Browser Error: ",
"NullPointerException on item click");
}
}
});
getUrl.setSelectAllOnFocus(true);
mSearchAdapter = new SearchAdapter(mContext, true);
getUrl.setAdapter(mSearchAdapter);
}
/**
* returns a list of bookmarks in the style (Title, Url) that is useful. the
* boolean addStarChar just adds an ASCII star character to each title if
* you want, primarily for use in search suggestions where the star
* indicates that it is a bookmarked url. All other uses can just supply
* false to this method.
*/
private List<HistoryItem> getBookmarks() {
List<HistoryItem> bookmarks = new ArrayList<HistoryItem>();
File bookUrl = new File(getApplicationContext().getFilesDir(),
"bookurl");
File book = new File(getApplicationContext().getFilesDir(), "bookmarks");
try {
BufferedReader readUrl = new BufferedReader(new FileReader(bookUrl));
BufferedReader readBook = new BufferedReader(new FileReader(book));
String u, t;
while ((u = readUrl.readLine()) != null
&& (t = readBook.readLine()) != null) {
HistoryItem map = new HistoryItem(u, t);
bookmarks.add(map);
}
readBook.close();
readUrl.close();
} catch (FileNotFoundException ignored) {
} catch (IOException ignored) {
}
Collections.sort(bookmarks, new SortIgnoreCase());
return bookmarks;
}
/**
* returns a list of HistoryItems
*
* @return
*/
private List<HistoryItem> getLatestHistory() {
DatabaseHandler historyHandler = new DatabaseHandler(mContext);
return historyHandler.getLastHundredItems();
}
/**
* function that opens the HTML history page in the browser
*/
private void openHistory() {
Thread history = new Thread(new Runnable() {
@Override
public void run() {
String historyHtml = HistoryPageVariables.Heading;
List<HistoryItem> historyList = getLatestHistory();
Iterator<HistoryItem> it = historyList.iterator();
HistoryItem helper;
while (it.hasNext()) {
helper = it.next();
historyHtml += HistoryPageVariables.Part1 + helper.getUrl()
+ HistoryPageVariables.Part2 + helper.getTitle()
+ HistoryPageVariables.Part3 + helper.getUrl()
+ HistoryPageVariables.Part4;
}
historyHtml += HistoryPageVariables.End;
File historyWebPage = new File(getFilesDir(), "history.html");
try {
FileWriter hWriter = new FileWriter(historyWebPage, false);
hWriter.write(historyHtml);
hWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
mCurrentView.loadUrl(Constants.FILE + historyWebPage);
mSearch.setText("");
}
});
history.run();
}
/**
* helper function that opens the bookmark drawer
*/
private void openBookmarks() {
if (mDrawerLayout.isDrawerOpen(mDrawer)) {
mDrawerLayout.closeDrawers();
}
mDrawerToggle.syncState();
mDrawerLayout.openDrawer(mDrawerRight);
}
@Override
/**
* open the HTML bookmarks page, parameter view is the WebView that should show the page
*/
public void openBookmarkPage(WebView view) {
String bookmarkHtml = BookmarkPageVariables.Heading;
Iterator<HistoryItem> iter = mBookmarkList.iterator();
HistoryItem helper;
while (iter.hasNext()) {
helper = iter.next();
bookmarkHtml += (BookmarkPageVariables.Part1 + helper.getUrl()
+ BookmarkPageVariables.Part2 + helper.getUrl()
+ BookmarkPageVariables.Part3 + helper.getTitle() + BookmarkPageVariables.Part4);
}
bookmarkHtml += BookmarkPageVariables.End;
File bookmarkWebPage = new File(mContext.getCacheDir(),
"bookmarks.html");
try {
FileWriter bookWriter = new FileWriter(bookmarkWebPage, false);
bookWriter.write(bookmarkHtml);
bookWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
view.loadUrl(Constants.FILE + bookmarkWebPage);
}
/**
* adds a bookmark with a title and url. Simple.
*/
public void addBookmark(Context context, String title, String url) {
File book = new File(context.getFilesDir(), "bookmarks");
File bookUrl = new File(context.getFilesDir(), "bookurl");
HistoryItem bookmark = new HistoryItem(url, title);
try {
BufferedReader readUrlRead = new BufferedReader(new FileReader(
bookUrl));
String u;
while ((u = readUrlRead.readLine()) != null) {
if (u.contentEquals(url)) {
readUrlRead.close();
return;
}
}
readUrlRead.close();
} catch (FileNotFoundException ignored) {
} catch (IOException ignored) {
} catch (NullPointerException ignored) {
}
try {
BufferedWriter bookWriter = new BufferedWriter(new FileWriter(book,
true));
BufferedWriter urlWriter = new BufferedWriter(new FileWriter(
bookUrl, true));
bookWriter.write(title);
urlWriter.write(url);
bookWriter.newLine();
urlWriter.newLine();
bookWriter.close();
urlWriter.close();
mBookmarkList.add(bookmark);
Collections.sort(mBookmarkList, new SortIgnoreCase());
notifyBookmarkDataSetChanged();
} catch (FileNotFoundException ignored) {
} catch (IOException ignored) {
} catch (NullPointerException ignored) {
}
mSearchAdapter.refreshBookmarks();
}
@Override
public void update() {
mTitleAdapter.notifyDataSetChanged();
}
@Override
/**
* opens a file chooser
* param ValueCallback is the message from the WebView indicating a file chooser
* should be opened
*/
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
startActivityForResult(Intent.createChooser(i, "File Chooser"), 1);
}
@Override
/**
* used to allow uploading into the browser, doesn't get called in KitKat :(
*/
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == 1) {
if (null == mUploadMessage)
return;
Uri result = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
@Override
/**
* handles long presses for the browser, tries to get the
* url of the item that was clicked and sends it (it can be null)
* to the click handler that does cool stuff with it
*/
public void onLongPress() {
if (mClickHandler == null) {
mClickHandler = new ClickHandler(mContext);
}
Message click = mClickHandler.obtainMessage();
if (click != null) {
click.setTarget(mClickHandler);
}
mCurrentView.getWebView().requestFocusNodeHref(click);
}
@Override
public void onShowCustomView(View view, int requestedOrientation,
CustomViewCallback callback) {
if (view == null) {
return;
}
if (mCustomView != null && callback != null) {
callback.onCustomViewHidden();
return;
}
view.setKeepScreenOn(true);
mOriginalOrientation = getRequestedOrientation();
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
mFullscreenContainer = new FullscreenHolder(this);
mCustomView = view;
mFullscreenContainer.addView(mCustomView, COVER_SCREEN_PARAMS);
decor.addView(mFullscreenContainer, COVER_SCREEN_PARAMS);
setFullscreen(true);
mCurrentView.setVisibility(View.GONE);
if (view instanceof FrameLayout) {
if (((FrameLayout) view).getFocusedChild() instanceof VideoView) {
mVideoView = (VideoView) ((FrameLayout) view).getFocusedChild();
mVideoView.setOnErrorListener(new VideoCompletionListener());
mVideoView
.setOnCompletionListener(new VideoCompletionListener());
}
}
mCustomViewCallback = callback;
}
@Override
public void onHideCustomView() {
if (mCustomView == null || mCustomViewCallback == null
|| mCurrentView == null)
return;
Log.i("Lightning", "onHideCustomView");
mCurrentView.setVisibility(View.VISIBLE);
mCustomView.setKeepScreenOn(false);
setFullscreen(mPreferences.getBoolean(
PreferenceConstants.HIDE_STATUS_BAR, false));
FrameLayout decor = (FrameLayout) getWindow().getDecorView();
if (decor != null) {
decor.removeView(mFullscreenContainer);
}
if (API < 19) {
try {
mCustomViewCallback.onCustomViewHidden();
} catch (Throwable ignored) {
}
}
mFullscreenContainer = null;
mCustomView = null;
if (mVideoView != null) {
mVideoView.setOnErrorListener(null);
mVideoView.setOnCompletionListener(null);
mVideoView = null;
}
setRequestedOrientation(mOriginalOrientation);
}
private class VideoCompletionListener implements
MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
@Override
public void onCompletion(MediaPlayer mp) {
onHideCustomView();
}
}
/**
* turns on fullscreen mode in the app
*
* @param enabled
* whether to enable fullscreen or not
*/
public void setFullscreen(boolean enabled) {
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
final int bits = WindowManager.LayoutParams.FLAG_FULLSCREEN;
if (enabled) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
if (mCustomView != null) {
mCustomView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
} else {
mBrowserFrame
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
}
win.setAttributes(winParams);
}
/**
* a class extending FramLayout used to display fullscreen videos
*/
static class FullscreenHolder extends FrameLayout {
public FullscreenHolder(Context ctx) {
super(ctx);
setBackgroundColor(ctx.getResources().getColor(
android.R.color.black));
}
@Override
public boolean onTouchEvent(MotionEvent evt) {
return true;
}
}
@Override
/**
* a stupid method that returns the bitmap image to display in place of
* a loading video
*/
public Bitmap getDefaultVideoPoster() {
if (mDefaultVideoPoster == null) {
mDefaultVideoPoster = BitmapFactory.decodeResource(getResources(),
android.R.drawable.ic_media_play);
}
return mDefaultVideoPoster;
}
@Override
/**
* dumb method that returns the loading progress for a video
*/
public View getVideoLoadingProgressView() {
if (mVideoProgressView == null) {
LayoutInflater inflater = LayoutInflater.from(this);
mVideoProgressView = inflater.inflate(
R.layout.video_loading_progress, null);
}
return mVideoProgressView;
}
@Override
/**
* handles javascript requests to create a new window in the browser
*/
public void onCreateWindow(boolean isUserGesture, Message resultMsg) {
if (resultMsg == null) {
return;
}
newTab("", true);
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(mCurrentView.getWebView());
resultMsg.sendToTarget();
}
@Override
/**
* returns the Activity instance for this activity,
* very helpful when creating things in other classes... I think
*/
public Activity getActivity() {
return mActivity;
}
/**
* it hides the action bar, seriously what else were you expecting
*/
@Override
public void hideActionBar() {
if (mActionBar.isShowing() && mFullScreen) {
mActionBar.hide();
}
}
@Override
/**
* obviously it shows the action bar if it's hidden
*/
public void showActionBar() {
if (!mActionBar.isShowing() && mFullScreen) {
mActionBar.show();
}
}
@Override
/**
* handles a long click on the page, parameter String url
* is the url that should have been obtained from the WebView touch node
* thingy, if it is null, this method tries to deal with it and find a workaround
*/
public void longClickPage(final String url) {
HitTestResult result = null;
if (mCurrentView.getWebView() != null) {
result = mCurrentView.getWebView().getHitTestResult();
}
if (url != null) {
if (url != null) {
if (result != null) {
if (result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE
|| result.getType() == HitTestResult.IMAGE_TYPE) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(url, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(url);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
if (API > 8) {
Utils.downloadFile(mActivity, url,
mCurrentView.getUserAgent(),
"attachment", false);
}
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(url.replace(Constants.HTTP, ""))
.setMessage(
getResources().getString(
R.string.dialog_image))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_download),
dialogClickListener).show();
} else {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(url, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(url);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(
"label", url);
clipboard.setPrimaryClip(clip);
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(url)
.setMessage(
getResources().getString(
R.string.dialog_link))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_copy),
dialogClickListener).show();
}
} else {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(url, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(url);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label",
url);
clipboard.setPrimaryClip(clip);
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(url)
.setMessage(
getResources().getString(
R.string.dialog_link))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_copy),
dialogClickListener).show();
}
}
} else if (result != null) {
if (result.getExtra() != null) {
final String newUrl = result.getExtra();
if (result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE
|| result.getType() == HitTestResult.IMAGE_TYPE) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(newUrl, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(newUrl);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
if (API > 8) {
Utils.downloadFile(mActivity, newUrl,
mCurrentView.getUserAgent(),
"attachment", false);
}
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(newUrl.replace(Constants.HTTP, ""))
.setMessage(
getResources().getString(
R.string.dialog_image))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_download),
dialogClickListener).show();
} else {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE: {
newTab(newUrl, false);
break;
}
case DialogInterface.BUTTON_NEGATIVE: {
mCurrentView.loadUrl(newUrl);
break;
}
case DialogInterface.BUTTON_NEUTRAL: {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label",
newUrl);
clipboard.setPrimaryClip(clip);
break;
}
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(
mActivity); // dialog
builder.setTitle(newUrl)
.setMessage(
getResources().getString(
R.string.dialog_link))
.setPositiveButton(
getResources().getString(
R.string.action_new_tab),
dialogClickListener)
.setNegativeButton(
getResources().getString(
R.string.action_open),
dialogClickListener)
.setNeutralButton(
getResources().getString(
R.string.action_copy),
dialogClickListener).show();
}
}
}
}
/**
* This method lets the search bar know that the page is currently loading
* and that it should display the stop icon to indicate to the user that
* pressing it stops the page from loading
*/
public void setIsLoading() {
if (!mSearch.hasFocus()) {
mIcon = mDeleteIcon;
mSearch.setCompoundDrawables(null, null, mDeleteIcon, null);
}
}
/**
* This tells the search bar that the page is finished loading and it should
* display the refresh icon
*/
public void setIsFinishedLoading() {
if (!mSearch.hasFocus()) {
mIcon = mRefreshIcon;
mSearch.setCompoundDrawables(null, null, mRefreshIcon, null);
}
}
/**
* handle presses on the refresh icon in the search bar, if the page is
* loading, stop the page, if it is done loading refresh the page.
*
* See setIsFinishedLoading and setIsLoading for displaying the correct icon
*/
public void refreshOrStop() {
if (mCurrentView != null) {
if (mCurrentView.getProgress() < 100) {
mCurrentView.stopLoading();
} else {
mCurrentView.reload();
}
}
}
@Override
public boolean isActionBarShowing() {
if (mActionBar != null) {
return mActionBar.isShowing();
} else {
return false;
}
}
public class SortIgnoreCase implements Comparator<HistoryItem> {
public int compare(HistoryItem o1, HistoryItem o2) {
return o1.getTitle().toLowerCase(Locale.getDefault())
.compareTo(o2.getTitle().toLowerCase(Locale.getDefault()));
}
}
}