diff options
-rw-r--r-- | AndroidManifest.xml | 15 | ||||
-rw-r--r-- | res/layout/bookmarkstackwidget.xml | 40 | ||||
-rw-r--r-- | res/layout/bookmarkstackwidget_item.xml | 47 | ||||
-rw-r--r-- | res/xml/bookmarkstackwidget.xml | 24 | ||||
-rw-r--r-- | src/com/android/browser/widget/BookmarkStackWidgetProvider.java | 45 | ||||
-rw-r--r-- | src/com/android/browser/widget/BookmarkStackWidgetService.java | 222 |
6 files changed, 393 insertions, 0 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 3a0cee5..f50c9f0 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -215,6 +215,21 @@ <service android:name=".widget.BookmarkWidgetService" /--> + <receiver + android:name=".widget.BookmarkStackWidgetProvider" + android:label="@string/bookmarks"> + <intent-filter> + <action + android:name="android.appwidget.action.APPWIDGET_UPDATE" /> + </intent-filter> + <meta-data + android:name="android.appwidget.provider" + android:resource="@xml/bookmarkstackwidget" /> + </receiver> + <service + android:name=".widget.BookmarkStackWidgetService" + android:exported="true" /> + <!-- Makes .BrowserActivity the search target for any activity in Browser --> <meta-data android:name="android.app.default_searchable" android:value=".BrowserActivity" /> diff --git a/res/layout/bookmarkstackwidget.xml b/res/layout/bookmarkstackwidget.xml new file mode 100644 index 0000000..c8c88c4 --- /dev/null +++ b/res/layout/bookmarkstackwidget.xml @@ -0,0 +1,40 @@ +<?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. +--> + +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <StackView + android:id="@+id/stackwidget_stack" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center" + android:paddingTop="16dip" + android:paddingBottom="8dip" + android:paddingLeft="8dip" + android:paddingRight="8dip" + android:background="#00000000" + android:cacheColorHint="#00000000" + android:autoStart="true" /> + <ImageView + android:id="@+id/logo" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_centerHorizontal="true" + android:src="@drawable/ic_launcher_shortcut_browser_bookmark" /> +</RelativeLayout> diff --git a/res/layout/bookmarkstackwidget_item.xml b/res/layout/bookmarkstackwidget_item.xml new file mode 100644 index 0000000..e7992f7 --- /dev/null +++ b/res/layout/bookmarkstackwidget_item.xml @@ -0,0 +1,47 @@ +<?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. +--> + +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/stack_item" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="16dip"> + <ImageView + android:id="@+id/thumb" + android:src="@drawable/browser_thumbnail" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:scaleType="fitXY" + android:layout_centerInParent="true" /> + <TextView + android:id="@+id/label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textStyle="bold" + android:textColor="@color/white" + android:maxLines="1" + android:paddingLeft="2dip" + android:paddingRight="2dip" + android:paddingTop="0dip" + android:paddingBottom="0dip" + android:scrollHorizontally="true" + android:ellipsize="marquee" + android:layout_alignBottom="@id/thumb" + android:layout_alignLeft="@id/thumb" + android:layout_alignRight="@id/thumb" /> +</RelativeLayout> diff --git a/res/xml/bookmarkstackwidget.xml b/res/xml/bookmarkstackwidget.xml new file mode 100644 index 0000000..1879923 --- /dev/null +++ b/res/xml/bookmarkstackwidget.xml @@ -0,0 +1,24 @@ +<?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. +--> + +<!-- 2x2 Widget displaying the user's bookmarks as thumbnails. --> +<appwidget-provider + xmlns:android="http://schemas.android.com/apk/res/android" + android:minWidth="146dip" + android:minHeight="146dip" + android:updatePeriodMillis="3600000" + android:initialLayout="@layout/bookmarkstackwidget"> +</appwidget-provider> diff --git a/src/com/android/browser/widget/BookmarkStackWidgetProvider.java b/src/com/android/browser/widget/BookmarkStackWidgetProvider.java new file mode 100644 index 0000000..0684c61 --- /dev/null +++ b/src/com/android/browser/widget/BookmarkStackWidgetProvider.java @@ -0,0 +1,45 @@ +/* + * 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.widget; + +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; + +/** + * Widget that shows a preview of the user's bookmarks. + */ +public class BookmarkStackWidgetProvider extends AppWidgetProvider { + + @Override + public void onUpdate(Context context, AppWidgetManager mngr, int[] ids) { + context.startService(new Intent(BookmarkStackWidgetService.UPDATE, null, + context, BookmarkStackWidgetService.class)); + } + + @Override + public void onEnabled(Context context) { + context.startService(new Intent(context, BookmarkStackWidgetService.class)); + } + + @Override + public void onDisabled(Context context) { + context.stopService(new Intent(context, BookmarkStackWidgetService.class)); + } + +} diff --git a/src/com/android/browser/widget/BookmarkStackWidgetService.java b/src/com/android/browser/widget/BookmarkStackWidgetService.java new file mode 100644 index 0000000..5334499 --- /dev/null +++ b/src/com/android/browser/widget/BookmarkStackWidgetService.java @@ -0,0 +1,222 @@ +/* + * 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.widget; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.content.ComponentName; +import android.content.Intent; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.Handler; +import android.os.Message; +import android.provider.BrowserContract; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +import com.android.browser.R; + +import java.util.ArrayList; +import java.util.List; + +public class BookmarkStackWidgetService extends RemoteViewsService { + + private static final String LOGTAG = "browserwidget"; + + /** Force the bookmarks to be re-renderer. */ + public static final String UPDATE = "com.android.browser.widget.UPDATE"; + + /** the adapter intent action */ + public static final String ADAPTER = "com.android.browser.widget.ADAPTER"; + + private static final String EXTRA_ID = "_id"; + private static final String EXTRA_URL = "_url"; + + private static final String[] PROJECTION = new String[] { + BrowserContract.Bookmarks._ID, + BrowserContract.Bookmarks.TITLE, + BrowserContract.Bookmarks.URL, + BrowserContract.Bookmarks.THUMBNAIL }; + + private static final String WHERE_CLAUSE = BrowserContract.Bookmarks.IS_FOLDER + + " == 0"; + + // No id specified. + private static final int NO_ID = -1; + + private static final int MSG_UPDATE = 0; + + List<RenderResult> mBookmarks; + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_UPDATE: + updateWidget(); + break; + default: + break; + } + } + }; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + final String action = intent.getAction(); + if (UPDATE.equals(action)) { + mHandler.sendEmptyMessage(MSG_UPDATE); + } + return START_STICKY; + } + + private void updateWidget() { + RemoteViews views = new RemoteViews(getPackageName(), + R.layout.bookmarkstackwidget); + Intent adapter = new Intent(BookmarkStackWidgetService.ADAPTER, null, + this, BookmarkStackWidgetService.class); + views.setRemoteAdapter(R.id.stackwidget_stack, adapter); + AppWidgetManager.getInstance(this).updateAppWidget( + new ComponentName(this, BookmarkStackWidgetProvider.class), + views); + } + + @Override + public RemoteViewsFactory onGetViewFactory(Intent intent) { + return mViewFactory; + } + + RemoteViewsService.RemoteViewsFactory mViewFactory = new RemoteViewsFactory () { + + @Override + public int getCount() { + return mBookmarks.size(); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public RemoteViews getLoadingView() { + return null; + } + + @Override + public RemoteViews getViewAt(int position) { + RenderResult res = mBookmarks.get(position); + RemoteViews views = new RemoteViews(getPackageName(), + R.layout.bookmarkstackwidget_item); + views.setOnClickPendingIntent(R.id.stack_item, + getOpenUrlPendingIntent(res.mUrl)); + + // Set the title of the bookmark. Use the url as a backup. + String displayTitle = res.mTitle; + if (TextUtils.isEmpty(displayTitle)) { + displayTitle = res.mUrl; + } + views.setTextViewText(R.id.label, displayTitle); + if (res.mBitmap != null) { + views.setImageViewBitmap(R.id.thumb, res.mBitmap); + views.setViewVisibility(R.id.label, View.GONE); + } + return views; + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public boolean hasStableIds() { + return false; + } + + @Override + public void onCreate() { + update(); + } + + @Override + public void onDestroy() { + } + + public void update() { + mBookmarks = new ArrayList<RenderResult>(); + // Look up all the bookmarks + Cursor c = null; + try { + c = getContentResolver().query(BrowserContract.Bookmarks.CONTENT_URI, + PROJECTION, WHERE_CLAUSE, null, null); + if (c != null) { + while (c.moveToNext()) { + int id = c.getInt(0); + String title = c.getString(1); + String url = c.getString(2); + RenderResult res = new RenderResult(id, title, url); + byte[] blob = c.getBlob(3); + if (blob != null) { + res.mBitmap = BitmapFactory.decodeByteArray(blob, 0, blob.length); + } + mBookmarks.add(res); + } + } + } catch (IllegalStateException e) { + Log.e(LOGTAG, "update bookmark widget", e); + } finally { + if (c != null) { + c.close(); + } + } + } + + @Override + public void onDataSetChanged() { + } + }; + + private PendingIntent getOpenUrlPendingIntent(String url) { + Intent vi = new Intent(Intent.ACTION_VIEW); + vi.setData(Uri.parse(url)); + return PendingIntent.getActivity(this, 0, vi, PendingIntent.FLAG_CANCEL_CURRENT); + } + + + // Class containing the rendering information for a specific bookmark. + private static class RenderResult { + final int mId; + final String mTitle; + final String mUrl; + Bitmap mBitmap; + + RenderResult(int id, String title, String url) { + mId = id; + mTitle = title; + mUrl = url; + } + + } + + +} |