/** * Copyright 2010 Eric Taix Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions and limitations under the * License. */ package com.bigpupdev.synodroid.ui; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import com.bigpupdev.synodroid.R; import com.bigpupdev.synodroid.Synodroid; import com.bigpupdev.synodroid.action.AddTaskAction; import com.bigpupdev.synodroid.adapter.BookmarkMenuAdapter; import com.bigpupdev.synodroid.server.DownloadIntentService; import com.bigpupdev.synodroid.utils.BookmarkDBHelper; import com.bigpupdev.synodroid.utils.BookmarkMenuItem; import com.bigpupdev.synodroid.utils.UIUtils; import de.keyboardsurfer.android.widget.crouton.Crouton; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.os.Message; import android.support.v4.app.FragmentActivity; import android.util.Log; import android.view.ContextMenu; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnFocusChangeListener; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.webkit.CookieManager; import android.webkit.DownloadListener; import android.webkit.WebChromeClient; import android.webkit.WebIconDatabase; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.AdapterView; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; /** * This activity displays a help page * * @author Steve Garon (synodroid at gmail dot com) */ @SuppressLint({ "SetJavaScriptEnabled", "NewApi" }) public class BrowserFragment extends SynodroidFragment { private static final String PREFERENCE_DEFAULT_URL = "bookmark_cat.default_ur"; private static final String PREFERENCE_BOOKMARK = "bookmark_cat"; private ImageButton bookmark_btn = null; private ImageButton stop_btn = null; private EditText url_text = null; private ImageView url_favicon = null; private WebView myWebView = null; private String default_url = "http://www.google.com"; private BookmarkMenuAdapter adapter = null; private Comparator<BookmarkMenuItem> comp = null; private String url_last = "http://www.google.com"; @Override public void onConfigurationChanged(Configuration newConfig) { // ignore orientation change super.onConfigurationChanged(newConfig); } /** * Activity creation */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); try { if (((Synodroid) getActivity().getApplication()).DEBUG) Log.v(Synodroid.DS_TAG, "BrowserFragment: Creating Browser fragment"); } catch (Exception ex) {/* DO NOTHING */} View browser = inflater.inflate(R.layout.browser, null, false); String curBrowserUrl = ((Synodroid)getActivity().getApplication()).getBrowserUrl(); comp = new Comparator<BookmarkMenuItem>() { public int compare(BookmarkMenuItem arg0, BookmarkMenuItem arg1) { try{ return arg0.title.compareTo(arg1.title); } catch (Exception e){ return 0; } } }; WebIconDatabase.getInstance().open(getActivity().getDir("icons", FragmentActivity.MODE_PRIVATE).getPath()); View secMenu = ((BrowserActivity)getActivity()).getSlidingMenu().getSecondaryMenu(); adapter = new BookmarkMenuAdapter(getActivity()); HashMap<String, String> map = getUrlsFromDB(); for (Map.Entry<String, String> entry : map.entrySet()){ adapter.add(new BookmarkMenuItem(entry.getValue(), entry.getKey(), null)); } adapter.sort(comp); final ListView menuList = (ListView) secMenu.findViewById(R.id.lvBookmarks); menuList.setAdapter(adapter); menuList.setOnItemClickListener(new ListView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { BookmarkMenuItem menuListSelectedItem = (BookmarkMenuItem) menuList.getItemAtPosition(position); ((BrowserActivity)getActivity()).getSlidingMenu().showContent(true); myWebView.loadUrl(menuListSelectedItem.url); } }); menuList.setOnItemLongClickListener(new ListView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> adapterView, View clickedView, int position, long arg3) { final BookmarkMenuItem menuListSelectedItem = (BookmarkMenuItem) menuList.getItemAtPosition(position); ConfirmDialog dialog = new ConfirmDialog(); Runnable ok = new Runnable(){ @Override public void run() { SharedPreferences preferences = getActivity().getSharedPreferences(PREFERENCE_BOOKMARK, Activity.MODE_PRIVATE); preferences.edit().putString(PREFERENCE_DEFAULT_URL, menuListSelectedItem.url).commit(); ((BrowserActivity)getActivity()).getSlidingMenu().showContent(true); Crouton.makeText(getActivity(), getText(R.string.home_set)+" "+menuListSelectedItem.url, Synodroid.CROUTON_CONFIRM).show(); } }; dialog.Confirm(getActivity(), getActivity().getText(R.string.menu_default_url).toString(), menuListSelectedItem.url, getActivity().getText(R.string.button_cancel).toString(), getActivity().getText(R.string.button_ok).toString(), ok, ConfirmDialog.empty); return true; } }); myWebView = (WebView) browser.findViewById(R.id.webview); url_favicon = (ImageView) browser.findViewById(R.id.favicon); stop_btn = (ImageButton) browser.findViewById(R.id.stop); bookmark_btn = (ImageButton) browser.findViewById(R.id.bookmark); url_text = (EditText) browser.findViewById(R.id.url); url_text.setOnEditorActionListener(new OnEditorActionListener(){ @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { String url = url_text.getText().toString(); if (!url.equals("")){ if (!url.contains(".")){ try { url = "http://www.google.com/m?q=" + URLEncoder.encode(url, "utf-8"); } catch (UnsupportedEncodingException e) {} } if (!url.contains("://")){ url = "http://" + url; } myWebView.loadUrl(url); url_text.clearFocus(); } return true; } }); url_text.setOnFocusChangeListener(new OnFocusChangeListener(){ @Override public void onFocusChange(View view, boolean hasFocus) { if (!hasFocus){ InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(url_text.getWindowToken(), 0); imm.hideSoftInputFromWindow(url_text.getWindowToken(), 0); } } }); bookmark_btn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View clickedView) { Activity a = getActivity(); try{ if (((Synodroid)a.getApplication()).DEBUG) Log.v(Synodroid.DS_TAG,"BrowserFragment: Add bookark button selected."); }catch (Exception ex){/*DO NOTHING*/} WebView webView = (WebView) getView().findViewById(R.id.webview); String cur_url = webView.getUrl(); if (cur_url != null){ HashMap<String, String> bookmarks = getUrlsFromDB(); if (!bookmarks.containsKey(cur_url)){ bookmark_btn.setImageDrawable(getResources().getDrawable(R.drawable.ic_resethome)); //Save to DB saveToDB(webView.getTitle(), cur_url); Crouton.makeText(getActivity(), getText(R.string.add_bookmark), Synodroid.CROUTON_CONFIRM).show(); } else{ bookmark_btn.setImageDrawable(getResources().getDrawable(R.drawable.ic_sethome)); //Delete from DB deleteFromDB(cur_url); Crouton.makeText(getActivity(), getText(R.string.del_bookmark), Synodroid.CROUTON_ALERT).show(); } bookmarks = getUrlsFromDB(); adapter.clear(); for (Map.Entry<String, String> entry : bookmarks.entrySet()){ adapter.add(new BookmarkMenuItem(entry.getValue(), entry.getKey(), null)); } adapter.sort(comp); adapter.notifyDataSetChanged(); } } }); stop_btn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View clickedView) { myWebView.stopLoading(); } }); final ProgressBar Pbar = (ProgressBar) browser.findViewById(R.id.browser_progress); MyWebViewClient webViewClient = new MyWebViewClient(); MyDownloadListener downloadListener = new MyDownloadListener(); MyWebChromeClient webChromeClient = new MyWebChromeClient(); webChromeClient.setPB(Pbar); myWebView.setWebViewClient(webViewClient); myWebView.setDownloadListener(downloadListener); myWebView.setWebChromeClient(webChromeClient); myWebView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: if (!v.hasFocus()) { v.requestFocus(); } break; } return false; } }); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setBuiltInZoomControls(true); if(UIUtils.isICS()) webSettings.setDisplayZoomControls(false); webSettings.setUseWideViewPort(true); webSettings.setLoadWithOverviewMode(true); webSettings.setAppCacheMaxSize(1024*1024*8); webSettings.setAppCachePath("/data/data/com.bigpupdev.synodroid/cache"); webSettings.setAppCacheEnabled(true); webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); if (curBrowserUrl != null){ myWebView.loadUrl(curBrowserUrl); } else{ SharedPreferences preferences = getActivity().getSharedPreferences(PREFERENCE_BOOKMARK, Activity.MODE_PRIVATE); default_url = preferences.getString(PREFERENCE_DEFAULT_URL, default_url); url_last = default_url; myWebView.loadUrl(default_url); } registerForContextMenu(myWebView); return browser; } @Override public void onDestroy(){ WebIconDatabase.getInstance().close(); super.onDestroy(); } public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { ConfirmDialog dialog = new ConfirmDialog(); WebView.HitTestResult hitTestResult = myWebView.getHitTestResult(); final String okUrl = hitTestResult.getExtra(); if (okUrl != null){ Runnable ok = new Runnable(){ @Override public void run() { AddTaskAction addTask = new AddTaskAction(Uri.parse(okUrl), true, false); Synodroid app = (Synodroid) getActivity().getApplication(); app.executeAsynchronousAction(BrowserFragment.this, addTask, false); } }; dialog.Confirm(getActivity(), getActivity().getText(R.string.confirm_download).toString(), okUrl, getActivity().getText(R.string.button_cancel).toString(), getActivity().getText(R.string.button_ok).toString(), ok, ConfirmDialog.empty); } } public HashMap<String, String> getUrlsFromDB(){ HashMap<String, String> map = new HashMap<String, String>(); BookmarkDBHelper mDbHelper = new BookmarkDBHelper(getActivity()); SQLiteDatabase db = mDbHelper.getReadableDatabase(); // Define a projection that specifies which columns from the database // you will actually use after this query. String[] projection = { BookmarkDBHelper.BookmarkEntry.COLUMN_NAME_TITLE, BookmarkDBHelper.BookmarkEntry.COLUMN_NAME_URL}; // How you want the results sorted in the resulting Cursor String sortOrder = BookmarkDBHelper.BookmarkEntry.COLUMN_NAME_TITLE + " DESC"; Cursor c = db.query( BookmarkDBHelper.BookmarkEntry.TABLE_NAME, // The table to query projection, // The columns to return null, // The columns for the WHERE clause null, // The values for the WHERE clause null, // don't group the rows null, // don't filter by row groups sortOrder // The sort order ); for (int i = 0; i < c.getCount(); i++){ c.moveToPosition(i); String itemTitle = c.getString(c.getColumnIndexOrThrow(BookmarkDBHelper.BookmarkEntry.COLUMN_NAME_TITLE)); String itemUrl = c.getString(c.getColumnIndexOrThrow(BookmarkDBHelper.BookmarkEntry.COLUMN_NAME_URL)); map.put(itemUrl, itemTitle); } db.close(); return map; } public void deleteFromDB(String url){ BookmarkDBHelper mDbHelper = new BookmarkDBHelper(getActivity()); // Gets the data repository in write mode SQLiteDatabase db = mDbHelper.getWritableDatabase(); // Define 'where' part of query. String selection = BookmarkDBHelper.BookmarkEntry.COLUMN_NAME_URL + " LIKE ?"; // Specify arguments in placeholder order. String[] selectionArgs = { url }; // Issue SQL statement. db.delete(BookmarkDBHelper.BookmarkEntry.TABLE_NAME, selection, selectionArgs); db.close(); } public void saveToDB(String title, String url){ BookmarkDBHelper mDbHelper = new BookmarkDBHelper(getActivity()); // Gets the data repository in write mode SQLiteDatabase db = mDbHelper.getWritableDatabase(); // Create a new map of values, where column names are the keys ContentValues values = new ContentValues(); values.put(BookmarkDBHelper.BookmarkEntry.COLUMN_NAME_TITLE, title); values.put(BookmarkDBHelper.BookmarkEntry.COLUMN_NAME_URL, url); // Insert the new row, returning the primary key value of the new row db.insert(BookmarkDBHelper.BookmarkEntry.TABLE_NAME, null, values); db.close(); } @Override public void handleMessage(Message msgP) { // TODO Auto-generated method stub } public class MyWebChromeClient extends WebChromeClient{ private ProgressBar pb = null; private boolean shouldUpdate = true; public void setPB(ProgressBar mPB){ pb = mPB; } public void onProgressChanged(WebView view, int progress){ if(progress < 100 && pb.getVisibility() == ProgressBar.GONE){ pb.setVisibility(ProgressBar.VISIBLE); } pb.setProgress(progress); if(progress == 100) { pb.setVisibility(ProgressBar.GONE); try{ ((BrowserActivity)getActivity()).updateRefreshStatus(false); } catch(NullPointerException e){/*Let's not do anything with this error since it only happens when the fragment is being closed...*/} shouldUpdate = true; stop_btn.setVisibility(View.GONE); } else if (shouldUpdate){ try{ ((BrowserActivity)getActivity()).updateRefreshStatus(true); } catch(NullPointerException e){/*Let's not do anything with this error since it only happens when the fragment is being closed...*/} shouldUpdate = false; stop_btn.setVisibility(View.VISIBLE); } } @Override public void onReceivedIcon(WebView view, Bitmap icon){ url_favicon.setImageBitmap(icon); } } public class MyDownloadListener implements DownloadListener{ @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { try{ if (((Synodroid)getActivity().getApplication()).DEBUG)Log.d(Synodroid.DS_TAG, "Downloading URL: " + url); } catch (Exception e){} if (url.startsWith("http://magnet/")){ url = url.replace("http://magnet/", "magnet:"); } else if (url.startsWith("https://magnet/")){ url.replace("https://magnet/", "magnet:"); } CookieManager cookieManager = CookieManager.getInstance(); final String cookie = cookieManager.getCookie(url); ConfirmDialog dialog = new ConfirmDialog(); final String okUrl = url; final String cD = contentDisposition; Runnable ok = new Runnable(){ @Override public void run() { String content; if (cD == null){ content = ""; } else{ content = cD; } if ((okUrl.toLowerCase().endsWith(".torrent") || okUrl.toLowerCase().endsWith(".nzb") || content.toLowerCase().contains(".torrent") || content.toLowerCase().contains(".nzb")) && !okUrl.startsWith("magnet:")){ Activity a = getActivity(); Intent msgIntent = new Intent(a, DownloadIntentService.class); msgIntent.putExtra(DownloadIntentService.URL, okUrl); msgIntent.putExtra(DownloadIntentService.COOKIE, cookie); msgIntent.putExtra(DownloadIntentService.DEBUG, ((Synodroid)a.getApplication()).DEBUG); a.startService(msgIntent); } else { AddTaskAction addTask = new AddTaskAction(Uri.parse(okUrl), true, false); Synodroid app = (Synodroid) getActivity().getApplication(); app.executeAsynchronousAction(BrowserFragment.this, addTask, false); } } }; dialog.Confirm(getActivity(), getActivity().getText(R.string.confirm_download).toString(), url, getActivity().getText(R.string.button_cancel).toString(), getActivity().getText(R.string.button_ok).toString(), ok, ConfirmDialog.empty); url_text.setText(url_last); ((Synodroid)getActivity().getApplication()).setBrowserUrl(url_last); } } public class MyWebViewClient extends WebViewClient { public MyWebViewClient() { super(); // start anything you need to } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { boolean shouldOverride = false; if (url.startsWith("http://magnet/")){ url = url.replace("http://magnet/", "magnet:"); } else if (url.startsWith("https://magnet/")){ url.replace("https://magnet/", "magnet:"); } if (url.startsWith("magnet:")){ ConfirmDialog dialog = new ConfirmDialog(); final String okUrl = url; Runnable ok = new Runnable(){ @Override public void run() { AddTaskAction addTask = new AddTaskAction(Uri.parse(okUrl), true, false); Synodroid app = (Synodroid) getActivity().getApplication(); app.executeAsynchronousAction(BrowserFragment.this, addTask, false); } }; dialog.Confirm(getActivity(), getActivity().getText(R.string.confirm_download).toString(), url, getActivity().getText(R.string.button_cancel).toString(), getActivity().getText(R.string.button_ok).toString(), ok, ConfirmDialog.empty); view.stopLoading(); shouldOverride = true; } return shouldOverride; } public void onPageStarted(WebView view, String url, Bitmap favicon) { // Do something to the urls, views, etc. try{ if (((Synodroid)getActivity().getApplication()).DEBUG)Log.d(Synodroid.DS_TAG, "Loading URL: " + url); ((Synodroid)getActivity().getApplication()).setBrowserUrl(url); } catch (Exception e){} if (favicon != null){ url_favicon.setImageBitmap(favicon); } else{ url_favicon.setImageDrawable(getResources().getDrawable(R.drawable.ic_browser)); } url_last = url_text.getText().toString(); url_text.setText(url); HashMap<String, String> bookmarks = getUrlsFromDB(); if (bookmark_btn != null && url != null){ if (bookmarks.containsKey(url)){ bookmark_btn.setImageDrawable(getResources().getDrawable(R.drawable.ic_resethome)); } else{ bookmark_btn.setImageDrawable(getResources().getDrawable(R.drawable.ic_sethome)); } } } } }