diff options
author | Ben Murdoch <benm@google.com> | 2010-07-06 16:30:38 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-07-09 13:54:14 +0100 |
commit | eecb4e6cb64af03aad3f9facdbf6fd7190091b41 (patch) | |
tree | 4ca0e78bd031a7d64cc5fc3161dad4d15d01722f | |
parent | 6af492aeddda96c749142885e3b49455aa336309 (diff) | |
download | packages_apps_Browser-eecb4e6cb64af03aad3f9facdbf6fd7190091b41.zip packages_apps_Browser-eecb4e6cb64af03aad3f9facdbf6fd7190091b41.tar.gz packages_apps_Browser-eecb4e6cb64af03aad3f9facdbf6fd7190091b41.tar.bz2 |
Improve the visibility and discoverability of the "add shortcut
to home" functionality in the Browser.
When the user selects the bookmark button adjacent to the URL bar
they will be prompted to either add a new bookmark for the current
page or add a shortcut to the current page to their homescreen,
rather than being taken to the bookmark management activity. The
bookmarks button on the options menu will still take the user
directly to the bookmark management activity.
Bug: b/2794945
Change-Id: I07190250379f1d6e2fe6b8ea280317949cd58b15
-rw-r--r-- | AndroidManifest.xml | 4 | ||||
-rw-r--r-- | res/layout/browser_add_bookmark_const_url.xml | 87 | ||||
-rw-r--r-- | res/layout/title_bar.xml | 2 | ||||
-rw-r--r-- | res/values/strings.xml | 7 | ||||
-rw-r--r-- | src/com/android/browser/AddBookmarkPage.java | 57 | ||||
-rw-r--r-- | src/com/android/browser/BrowserActivity.java | 79 | ||||
-rw-r--r-- | src/com/android/browser/SaveToHomescreenDialog.java | 127 | ||||
-rw-r--r-- | src/com/android/browser/TitleBar.java | 2 | ||||
-rw-r--r-- | src/com/android/browser/TitleBarXLarge.java | 4 |
9 files changed, 351 insertions, 18 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7e98019..b46a41f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -184,6 +184,10 @@ </intent-filter> </activity> + <activity android:name="SaveToHomescreenDialog" android:label="Save to homescreen" android:theme="@android:style/Theme.Dialog" + android:configChanges="orientation|keyboardHidden" android:windowSoftInputMode="stateHidden"> + </activity> + <!--receiver android:name=".widget.BookmarkWidgetProvider" android:label="@string/bookmarks"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> diff --git a/res/layout/browser_add_bookmark_const_url.xml b/res/layout/browser_add_bookmark_const_url.xml new file mode 100644 index 0000000..c6603f4 --- /dev/null +++ b/res/layout/browser_add_bookmark_const_url.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + > + + <ImageView android:id="@+id/titleDivider" + android:layout_width="match_parent" + android:layout_height="1dip" + android:scaleType="fitXY" + android:gravity="fill_horizontal" + android:src="@drawable/dialog_divider_horizontal_light" + android:layout_marginLeft="10dip" + android:layout_marginRight="10dip"/> + + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:orientation="vertical" + android:paddingTop="5dip" + android:paddingBottom="13dip" + android:paddingLeft="20dip" + android:paddingRight="20dip" > + + <TextView + android:id="@+id/titleText" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:text="@string/name" + android:gravity="left" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <EditText + android:id="@+id/title" + android:layout_height="wrap_content" + android:layout_width="250dip" + android:gravity="fill_horizontal" + android:inputType="textCapSentences" + android:selectAllOnFocus="true" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="#c6c3c6" + android:minHeight="54dip" + android:orientation="horizontal" + android:paddingTop="4dip" + android:paddingLeft="2dip" + android:paddingRight="2dip" > + <Button android:id="@+id/OK" + android:text="@string/save" + android:layout_width="0dip" + android:layout_gravity="left" + android:layout_weight="1" + android:maxLines="2" + android:layout_height="wrap_content" /> + <Button android:id="@+id/cancel" + android:text="@string/do_not_save" + android:layout_width="0dip" + android:layout_gravity="right" + android:layout_weight="1" + android:maxLines="2" + android:layout_height="wrap_content" /> + </LinearLayout> + +</LinearLayout> + diff --git a/res/layout/title_bar.xml b/res/layout/title_bar.xml index 9f0cb51..d6a77e0 100644 --- a/res/layout/title_bar.xml +++ b/res/layout/title_bar.xml @@ -90,7 +90,7 @@ android:layout_marginRight="-5dip" android:scaleType="center" android:background="@drawable/btn_bookmark" - android:src="@drawable/ic_btn_bookmarks" + android:src="@drawable/ic_list_bookmark" /> </LinearLayout> </LinearLayout> diff --git a/res/values/strings.xml b/res/values/strings.xml index a30a399..c2068d7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -137,12 +137,13 @@ <string name="name">Name</string> <!-- Initial value in Location field in Bookmark dialog box --> <string name="http">http://</string> - <!-- Menu item that opens a dialog to save a bookmark, initialized with the current page --> - <string name="save_to_bookmarks">Add bookmark</string> + <!-- Menu item that opens a dialog to save a bookmark for the current page, also displayed as + the title of the dialog used for adding a bookmark --> + <string name="save_to_bookmarks">Add to Bookmarks</string> <!-- Menu item on the bookmarks page, to edit an existing bookmark --> <string name="edit_bookmark">Edit bookmark</string> <!-- Context menu item to create a shortcut to the bookmark on the desktop --> - <string name="create_shortcut_bookmark">Add shortcut to Home</string> + <string name="create_shortcut_bookmark">Add to Home</string> <!-- Context menu item to open the currently highlighted bookmark --> <string name="open_bookmark">Open</string> <!-- Menu item to remove the currently highlighted bookmark--> diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java index 1104d5e..104a495 100644 --- a/src/com/android/browser/AddBookmarkPage.java +++ b/src/com/android/browser/AddBookmarkPage.java @@ -51,6 +51,7 @@ public class AddBookmarkPage extends Activity { private String mTouchIconUrl; private Bitmap mThumbnail; private String mOriginalUrl; + private boolean mIsUrlEditable = true; // Message IDs private static final int SAVE_BOOKMARK = 100; @@ -74,13 +75,24 @@ public class AddBookmarkPage extends Activity { protected void onCreate(Bundle icicle) { super.onCreate(icicle); requestWindowFeature(Window.FEATURE_LEFT_ICON); - setContentView(R.layout.browser_add_bookmark); + + mMap = getIntent().getExtras(); + if (mMap != null) { + mIsUrlEditable = mMap.getBoolean("url_editable", true); + } + + if (mIsUrlEditable) { + setContentView(R.layout.browser_add_bookmark); + } else { + setContentView(R.layout.browser_add_bookmark_const_url); + } + setTitle(R.string.save_to_bookmarks); getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_list_bookmark); String title = null; String url = null; - mMap = getIntent().getExtras(); + if (mMap != null) { Bundle b = mMap.getBundle("bookmark"); if (b != null) { @@ -96,8 +108,11 @@ public class AddBookmarkPage extends Activity { mTitle = (EditText) findViewById(R.id.title); mTitle.setText(title); - mAddress = (EditText) findViewById(R.id.address); - mAddress.setText(url); + + if (mIsUrlEditable) { + mAddress = (EditText) findViewById(R.id.address); + mAddress.setText(url); + } View.OnClickListener accept = mSaveBookmark; mButton = (TextView) findViewById(R.id.OK); @@ -173,8 +188,14 @@ public class AddBookmarkPage extends Activity { createHandler(); String title = mTitle.getText().toString().trim(); - String unfilteredUrl = - BrowserActivity.fixUrl(mAddress.getText().toString()); + String unfilteredUrl; + if (mIsUrlEditable) { + unfilteredUrl = + BrowserActivity.fixUrl(mAddress.getText().toString()); + } else { + unfilteredUrl = mOriginalUrl; + } + boolean emptyTitle = title.length() == 0; boolean emptyUrl = unfilteredUrl.trim().length() == 0; Resources r = getResources(); @@ -183,9 +204,15 @@ public class AddBookmarkPage extends Activity { mTitle.setError(r.getText(R.string.bookmark_needs_title)); } if (emptyUrl) { - mAddress.setError(r.getText(R.string.bookmark_needs_url)); + if (mIsUrlEditable) { + mAddress.setError(r.getText(R.string.bookmark_needs_url)); + } else { + Toast.makeText(AddBookmarkPage.this, R.string.bookmark_needs_url, + Toast.LENGTH_LONG).show(); + } + return false; } - return false; + } String url = unfilteredUrl.trim(); try { @@ -200,7 +227,12 @@ public class AddBookmarkPage extends Activity { // can't save their bookmark. If it was null, we'll assume // they meant http when we parse it in the WebAddress class. if (scheme != null) { - mAddress.setError(r.getText(R.string.bookmark_cannot_save_url)); + if (mIsUrlEditable) { + mAddress.setError(r.getText(R.string.bookmark_cannot_save_url)); + } else { + Toast.makeText(AddBookmarkPage.this, R.string.bookmark_cannot_save_url, + Toast.LENGTH_LONG).show(); + } return false; } WebAddress address; @@ -216,7 +248,12 @@ public class AddBookmarkPage extends Activity { } } } catch (URISyntaxException e) { - mAddress.setError(r.getText(R.string.bookmark_url_not_valid)); + if (mIsUrlEditable) { + mAddress.setError(r.getText(R.string.bookmark_url_not_valid)); + } else { + Toast.makeText(AddBookmarkPage.this, R.string.bookmark_url_not_valid, + Toast.LENGTH_LONG).show(); + } return false; } diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index c7abad1..aeb8c46 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -1487,6 +1487,7 @@ public class BrowserActivity extends Activity i.putExtra("touch_icon_url", w.getTouchIconUrl()); i.putExtra("thumbnail", createScreenshot(w, getDesiredThumbnailWidth(this), getDesiredThumbnailHeight(this))); + i.putExtra("url_editable", false); startActivity(i); } @@ -2287,6 +2288,8 @@ public class BrowserActivity extends Activity static final int UPDATE_BOOKMARK_THUMBNAIL = 108; + private static final int TOUCH_ICON_DOWNLOADED = 109; + // Private handler for handling javascript and saving passwords private Handler mHandler = new Handler() { @@ -2357,6 +2360,14 @@ public class BrowserActivity extends Activity updateScreenshot(view); } break; + + case TOUCH_ICON_DOWNLOADED: + Bundle b = msg.getData(); + showSaveToHomescreenDialog(b.getString("url"), + b.getString("title"), + (Bitmap) b.getParcelable("touchIcon"), + (Bitmap) b.getParcelable("favicon")); + break; } } }; @@ -3728,6 +3739,47 @@ public class BrowserActivity extends Activity } + /* package*/ void promptAddOrInstallBookmark() { + final Tab current = mTabControl.getCurrentTab(); + Resources resources = getResources(); + CharSequence[] choices = { + resources.getString(R.string.save_to_bookmarks), + resources.getString(R.string.create_shortcut_bookmark) + }; + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.add_new_bookmark); + builder.setItems(choices, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { + if (item == 0) { + bookmarkCurrentPage(); + } else if (item == 1) { + current.populatePickerData(); + String touchIconUrl = mTabControl.getCurrentWebView().getTouchIconUrl(); + if (touchIconUrl != null) { + // Download the touch icon for this site then save it to the + // homescreen. + Bundle b = new Bundle(); + b.putString("url", current.getUrl()); + b.putString("title", current.getTitle()); + b.putParcelable("favicon", current.getFavicon()); + Message msg = mHandler.obtainMessage(TOUCH_ICON_DOWNLOADED); + msg.setData(b); + new DownloadTouchIcon(msg, + mTabControl.getCurrentWebView().getSettings() + .getUserAgentString()).execute(touchIconUrl); + } else { + // add to homescreen, can do it immediately as there is no touch + // icon. + showSaveToHomescreenDialog(current.getUrl(), current.getTitle(), + null, current.getFavicon()); + } + } + } + }); + builder.create().show(); + } + /** * Open the Go page. * @param startWithHistory If true, open starting on the history tab. @@ -3771,6 +3823,33 @@ public class BrowserActivity extends Activity startActivityForResult(intent, COMBO_PAGE); } + private void showSaveToHomescreenDialog(String url, String title, Bitmap touchIcon, + Bitmap favicon) { + Intent intent = new Intent(this, SaveToHomescreenDialog.class); + + // Just in case the user tries to save before a page finishes loading + // so the current history item, and therefore the page, is null. + if (null == url) { + url = mLastEnteredUrl; + // This can happen. + if (null == url) { + url = mSettings.getHomePage(); + } + } + + // In case the web page has not yet received its associated title. + if (title == null) { + title = url; + } + + intent.putExtra("title", title); + intent.putExtra("url", url); + intent.putExtra("favicon", favicon); + intent.putExtra("touchIcon", touchIcon); + startActivity(intent); + } + + // Called when loading from context menu or LOAD_URL message private void loadUrlFromContext(WebView view, String url) { // In case the user enters nothing. diff --git a/src/com/android/browser/SaveToHomescreenDialog.java b/src/com/android/browser/SaveToHomescreenDialog.java new file mode 100644 index 0000000..15f0aea --- /dev/null +++ b/src/com/android/browser/SaveToHomescreenDialog.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * 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.android.browser; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Intent; +import android.content.res.Resources; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.net.ParseException; +import android.net.Uri; +import android.net.WebAddress; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.provider.Browser; +import android.util.Log; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Date; + +public class SaveToHomescreenDialog extends Activity { + + private EditText mTitle; + private String mUrl; + private Bitmap mFavicon; + private Bitmap mTouchIcon; + + private View.OnClickListener mOk = new View.OnClickListener() { + public void onClick(View v) { + if (save()) { + finish(); + } + } + }; + + private View.OnClickListener mCancel = new View.OnClickListener() { + public void onClick(View v) { + finish(); + } + }; + + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + requestWindowFeature(Window.FEATURE_LEFT_ICON); + setContentView(R.layout.browser_add_bookmark_const_url); + setTitle(R.string.create_shortcut_bookmark); + getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, + R.drawable.ic_list_bookmark); + + String title = null; + String url = null; + Bundle map = getIntent().getExtras(); + if (map != null) { + title = map.getString("title"); + } + + mUrl = map.getString("url"); + mFavicon = (Bitmap)map.getParcelable("favicon"); + mTouchIcon = (Bitmap)map.getParcelable("touchIcon"); + + Bitmap icon = BookmarkUtils.createIcon(this, mTouchIcon, mFavicon, + BookmarkUtils.BookmarkIconType.ICON_HOME_SHORTCUT); + getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, new BitmapDrawable(icon)); + + mTitle = (EditText) findViewById(R.id.title); + mTitle.setText(title); + + Button okButton = (Button) findViewById(R.id.OK); + okButton.setOnClickListener(mOk); + + Button cancelButton = (Button) findViewById(R.id.cancel); + cancelButton.setOnClickListener(mCancel); + + if (!getWindow().getDecorView().isInTouchMode()) { + okButton.requestFocus(); + } + } + + /** + * Parse the data entered in the dialog and send an intent to create an + * icon on the homescreen. + */ + private boolean save() { + String title = mTitle.getText().toString().trim(); + String unfilteredUrl = BrowserActivity.fixUrl(mUrl); + if (title.length() == 0) { + mTitle.setError(getResources().getText(R.string.bookmark_needs_title)); + return false; + } + + String url = unfilteredUrl.trim(); + + sendBroadcast(BookmarkUtils.createAddToHomeIntent(this, url, title, + mTouchIcon, mFavicon)); + setResult(RESULT_OK); + return true; + } +} diff --git a/src/com/android/browser/TitleBar.java b/src/com/android/browser/TitleBar.java index 4e76334..f45025d 100644 --- a/src/com/android/browser/TitleBar.java +++ b/src/com/android/browser/TitleBar.java @@ -205,7 +205,7 @@ public class TitleBar extends TitleBarBase { } else if (mInLoad) { mBrowserActivity.stopLoading(); } else { - mBrowserActivity.bookmarksOrHistoryPicker(false); + mBrowserActivity.promptAddOrInstallBookmark(); } button.setPressed(false); } else if (mTitleBg.isPressed()) { diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java index 76f57d0..0d799a8 100644 --- a/src/com/android/browser/TitleBarXLarge.java +++ b/src/com/android/browser/TitleBarXLarge.java @@ -94,9 +94,7 @@ public class TitleBarXLarge extends TitleBarBase { } else if (mForwardButton == v) { mBrowserActivity.getTopWindow().goForward(); } else if (mStar == v) { - // FIXME: Show a menu with option to bookmark or - // save to home page - mBrowserActivity.bookmarkCurrentPage(); + mBrowserActivity.promptAddOrInstallBookmark(); } else if (mMenu == v) { mBrowserActivity.openOptionsMenu(); } else if (mStopButton == v) { |