2 * Copyright (C) 2006 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.browser;
19 import android.app.Activity;
20 import android.content.ContentResolver;
21 import android.content.Intent;
22 import android.content.res.Resources;
23 import android.database.Cursor;
24 import android.graphics.Bitmap;
25 import android.net.ParseException;
26 import android.net.WebAddress;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.os.Message;
30 import android.provider.Browser;
31 import android.view.View;
32 import android.view.Window;
33 import android.widget.EditText;
34 import android.widget.TextView;
35 import android.widget.Toast;
38 import java.net.URISyntaxException;
39 import java.util.Date;
41 public class AddBookmarkPage extends Activity {
43 private final String LOGTAG = "Bookmarks";
45 private EditText mTitle;
46 private EditText mAddress;
47 private TextView mButton;
48 private View mCancelButton;
49 private boolean mEditingExisting;
51 private String mTouchIconUrl;
52 private Bitmap mThumbnail;
53 private String mOriginalUrl;
56 private static final int SAVE_BOOKMARK = 100;
58 private Handler mHandler;
60 private View.OnClickListener mSaveBookmark = new View.OnClickListener() {
61 public void onClick(View v) {
68 private View.OnClickListener mCancel = new View.OnClickListener() {
69 public void onClick(View v) {
74 protected void onCreate(Bundle icicle) {
75 super.onCreate(icicle);
76 requestWindowFeature(Window.FEATURE_LEFT_ICON);
77 setContentView(R.layout.browser_add_bookmark);
78 setTitle(R.string.save_to_bookmarks);
79 getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_list_bookmark);
83 mMap = getIntent().getExtras();
85 Bundle b = mMap.getBundle("bookmark");
88 mEditingExisting = true;
89 setTitle(R.string.edit_bookmark);
91 title = mMap.getString("title");
92 url = mOriginalUrl = mMap.getString("url");
93 mTouchIconUrl = mMap.getString("touch_icon_url");
94 mThumbnail = (Bitmap) mMap.getParcelable("thumbnail");
97 mTitle = (EditText) findViewById(R.id.title);
98 mTitle.setText(title);
99 mAddress = (EditText) findViewById(R.id.address);
100 mAddress.setText(url);
102 View.OnClickListener accept = mSaveBookmark;
103 mButton = (TextView) findViewById(R.id.OK);
104 mButton.setOnClickListener(accept);
106 mCancelButton = findViewById(R.id.cancel);
107 mCancelButton.setOnClickListener(mCancel);
109 if (!getWindow().getDecorView().isInTouchMode()) {
110 mButton.requestFocus();
115 * Runnable to save a bookmark, so it can be performed in its own thread.
117 private class SaveBookmarkRunnable implements Runnable {
118 private Message mMessage;
119 public SaveBookmarkRunnable(Message msg) {
123 // Unbundle bookmark data.
124 Bundle bundle = mMessage.getData();
125 String title = bundle.getString("title");
126 String url = bundle.getString("url");
127 boolean invalidateThumbnail = bundle.getBoolean(
128 "invalidateThumbnail");
129 Bitmap thumbnail = invalidateThumbnail ? null
130 : (Bitmap) bundle.getParcelable("thumbnail");
131 String touchIconUrl = bundle.getString("touchIconUrl");
133 // Save to the bookmarks DB.
135 final ContentResolver cr = getContentResolver();
136 Bookmarks.addBookmark(null, cr, url, title, thumbnail, true);
137 if (touchIconUrl != null) {
139 = BrowserBookmarksAdapter.queryBookmarksForUrl(cr,
141 new DownloadTouchIcon(cr, c, url).execute(mTouchIconUrl);
144 } catch (IllegalStateException e) {
147 mMessage.sendToTarget();
151 private void createHandler() {
152 if (mHandler == null) {
153 mHandler = new Handler() {
155 public void handleMessage(Message msg) {
159 Toast.makeText(AddBookmarkPage.this, R.string.bookmark_saved,
160 Toast.LENGTH_LONG).show();
162 Toast.makeText(AddBookmarkPage.this, R.string.bookmark_not_saved,
163 Toast.LENGTH_LONG).show();
173 * Parse the data entered in the dialog and post a message to update the bookmarks database.
178 String title = mTitle.getText().toString().trim();
179 String unfilteredUrl =
180 BrowserActivity.fixUrl(mAddress.getText().toString());
181 boolean emptyTitle = title.length() == 0;
182 boolean emptyUrl = unfilteredUrl.trim().length() == 0;
183 Resources r = getResources();
184 if (emptyTitle || emptyUrl) {
186 mTitle.setError(r.getText(R.string.bookmark_needs_title));
189 mAddress.setError(r.getText(R.string.bookmark_needs_url));
193 String url = unfilteredUrl.trim();
195 // We allow bookmarks with a javascript: scheme, but these will in most cases
196 // fail URI parsing, so don't try it if that's the kind of bookmark we have.
198 if (!url.toLowerCase().startsWith("javascript:")) {
199 URI uriObj = new URI(url);
200 String scheme = uriObj.getScheme();
201 if (!Bookmarks.urlHasAcceptableScheme(url)) {
202 // If the scheme was non-null, let the user know that we
203 // can't save their bookmark. If it was null, we'll assume
204 // they meant http when we parse it in the WebAddress class.
205 if (scheme != null) {
206 mAddress.setError(r.getText(R.string.bookmark_cannot_save_url));
211 address = new WebAddress(unfilteredUrl);
212 } catch (ParseException e) {
213 throw new URISyntaxException("", "");
215 if (address.mHost.length() == 0) {
216 throw new URISyntaxException("", "");
218 url = address.toString();
221 } catch (URISyntaxException e) {
222 mAddress.setError(r.getText(R.string.bookmark_url_not_valid));
226 if (mEditingExisting) {
227 mMap.putString("title", title);
228 mMap.putString("url", url);
229 mMap.putBoolean("invalidateThumbnail", !url.equals(mOriginalUrl));
230 setResult(RESULT_OK, (new Intent()).setAction(
231 getIntent().toString()).putExtras(mMap));
233 // Post a message to write to the DB.
234 Bundle bundle = new Bundle();
235 bundle.putString("title", title);
236 bundle.putString("url", url);
237 bundle.putParcelable("thumbnail", mThumbnail);
238 bundle.putBoolean("invalidateThumbnail", !url.equals(mOriginalUrl));
239 bundle.putString("touchIconUrl", mTouchIconUrl);
240 Message msg = Message.obtain(mHandler, SAVE_BOOKMARK);
242 // Start a new thread so as to not slow down the UI
243 Thread t = new Thread(new SaveBookmarkRunnable(msg));
245 setResult(RESULT_OK);