BrowserBookmarksPage.java revision d3e4d5b4ffdf374b836ec9d4d3e315040c8c3779
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17package com.android.browser; 18 19import android.app.Activity; 20import android.app.Fragment; 21import android.app.LoaderManager; 22import android.content.ClipData; 23import android.content.ClipboardManager; 24import android.content.ContentUris; 25import android.content.Context; 26import android.content.CursorLoader; 27import android.content.Intent; 28import android.content.Loader; 29import android.content.res.Configuration; 30import android.content.res.Resources; 31import android.database.Cursor; 32import android.graphics.Bitmap; 33import android.graphics.BitmapFactory; 34import android.net.Uri; 35import android.os.AsyncTask; 36import android.os.Bundle; 37import android.provider.BrowserContract; 38import android.provider.BrowserContract.Accounts; 39import android.provider.BrowserContract.ChromeSyncColumns; 40import android.view.ActionMode; 41import android.view.ContextMenu; 42import android.view.ContextMenu.ContextMenuInfo; 43import android.view.LayoutInflater; 44import android.view.Menu; 45import android.view.MenuInflater; 46import android.view.MenuItem; 47import android.view.View; 48import android.view.ViewGroup; 49import android.widget.ExpandableListView; 50import android.widget.ExpandableListView.OnChildClickListener; 51import android.widget.ImageView; 52import android.widget.LinearLayout; 53import android.widget.Toast; 54 55import com.android.browser.BookmarkDragHandler.BookmarkDragController; 56import com.android.browser.BookmarkDragHandler.BookmarkDragState; 57import com.android.browser.view.BookmarkExpandableView; 58import com.android.browser.view.BookmarkExpandableView.BookmarkContextMenuInfo; 59 60import java.util.HashMap; 61 62interface BookmarksPageCallbacks { 63 // Return true if handled 64 boolean onBookmarkSelected(Cursor c, boolean isFolder); 65 // Return true if handled 66 boolean onOpenInNewWindow(String... urls); 67} 68 69/** 70 * View showing the user's bookmarks in the browser. 71 */ 72public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener, 73 LoaderManager.LoaderCallbacks<Cursor>, BreadCrumbView.Controller, 74 OnChildClickListener { 75 76 public static class ExtraDragState { 77 public int childPosition; 78 public int groupPosition; 79 } 80 81 static final String LOGTAG = "browser"; 82 83 static final int LOADER_ACCOUNTS = 1; 84 static final int LOADER_BOOKMARKS = 100; 85 86 static final String EXTRA_DISABLE_WINDOW = "disable_new_window"; 87 88 static final String ACCOUNT_TYPE = "account_type"; 89 static final String ACCOUNT_NAME = "account_name"; 90 91 public static final int VIEW_THUMBNAILS = 1; 92 public static final int VIEW_LIST = 2; 93 94 BookmarksPageCallbacks mCallbacks; 95 View mRoot; 96 BookmarkExpandableView mGrid; 97 boolean mDisableNewWindow; 98 boolean mEnableContextMenu = true; 99 View mEmptyView; 100 View mHeader; 101 HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>(); 102 BookmarkDragHandler mDragHandler; 103 104 static BrowserBookmarksPage newInstance(BookmarksPageCallbacks cb, 105 Bundle args, ViewGroup headerContainer) { 106 BrowserBookmarksPage bbp = new BrowserBookmarksPage(); 107 bbp.mCallbacks = cb; 108 bbp.setArguments(args); 109 return bbp; 110 } 111 112 @Override 113 public Loader<Cursor> onCreateLoader(int id, Bundle args) { 114 if (id == LOADER_ACCOUNTS) { 115 return new AccountsLoader(getActivity()); 116 } else if (id >= LOADER_BOOKMARKS) { 117 String accountType = args.getString(ACCOUNT_TYPE); 118 String accountName = args.getString(ACCOUNT_NAME); 119 BookmarksLoader bl = new BookmarksLoader(getActivity(), 120 accountType, accountName); 121 return bl; 122 } else { 123 throw new UnsupportedOperationException("Unknown loader id " + id); 124 } 125 } 126 127 @Override 128 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 129 if (loader.getId() == LOADER_ACCOUNTS) { 130 LoaderManager lm = getLoaderManager(); 131 int id = LOADER_BOOKMARKS; 132 while (cursor.moveToNext()) { 133 String accountName = cursor.getString(0); 134 String accountType = cursor.getString(1); 135 Bundle args = new Bundle(); 136 args.putString(ACCOUNT_NAME, accountName); 137 args.putString(ACCOUNT_TYPE, accountType); 138 BrowserBookmarksAdapter adapter = new BrowserBookmarksAdapter( 139 getActivity(), VIEW_THUMBNAILS); 140 mBookmarkAdapters.put(id, adapter); 141 mGrid.addAccount(accountName, adapter); 142 lm.restartLoader(id, args, this); 143 id++; 144 } 145 // TODO: Figure out what a reload of these means 146 // Currently, a reload is triggered whenever bookmarks change 147 // This is less than ideal 148 // It also causes UI flickering as a new adapter is created 149 // instead of re-using an existing one when the account_name is the 150 // same. 151 // For now, this is a one-shot load 152 getLoaderManager().destroyLoader(LOADER_ACCOUNTS); 153 } else if (loader.getId() >= LOADER_BOOKMARKS) { 154 BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId()); 155 adapter.changeCursor(cursor); 156 } 157 } 158 159 @Override 160 public void onLoaderReset(Loader<Cursor> loader) { 161 } 162 163 @Override 164 public boolean onContextItemSelected(MenuItem item) { 165 BookmarkContextMenuInfo i = (BookmarkContextMenuInfo)item.getMenuInfo(); 166 // If we have no menu info, we can't tell which item was selected. 167 if (i == null) { 168 return false; 169 } 170 171 if (handleContextItem(item.getItemId(), i.groupPosition, i.childPosition)) { 172 return true; 173 } 174 return super.onContextItemSelected(item); 175 } 176 177 public boolean handleContextItem(int itemId, int groupPosition, 178 int childPosition) { 179 final Activity activity = getActivity(); 180 BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition); 181 182 switch (itemId) { 183 case R.id.open_context_menu_id: 184 loadUrl(adapter, childPosition); 185 break; 186 case R.id.edit_context_menu_id: 187 editBookmark(adapter, childPosition); 188 break; 189 case R.id.shortcut_context_menu_id: 190 Cursor c = adapter.getItem(childPosition); 191 activity.sendBroadcast(createShortcutIntent(getActivity(), c)); 192 break; 193 case R.id.delete_context_menu_id: 194 displayRemoveBookmarkDialog(adapter, childPosition); 195 break; 196 case R.id.new_window_context_menu_id: 197 openInNewWindow(adapter, childPosition); 198 break; 199 case R.id.share_link_context_menu_id: { 200 Cursor cursor = adapter.getItem(childPosition); 201 Controller.sharePage(activity, 202 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE), 203 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL), 204 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON), 205 getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL)); 206 break; 207 } 208 case R.id.copy_url_context_menu_id: 209 copy(getUrl(adapter, childPosition)); 210 break; 211 case R.id.homepage_context_menu_id: { 212 BrowserSettings.getInstance().setHomePage(getUrl(adapter, childPosition)); 213 Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show(); 214 break; 215 } 216 // Only for the Most visited page 217 case R.id.save_to_bookmarks_menu_id: { 218 Cursor cursor = adapter.getItem(childPosition); 219 String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 220 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 221 // If the site is bookmarked, the item becomes remove from 222 // bookmarks. 223 Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name); 224 break; 225 } 226 default: 227 return false; 228 } 229 return true; 230 } 231 232 static Bitmap getBitmap(Cursor cursor, int columnIndex) { 233 byte[] data = cursor.getBlob(columnIndex); 234 if (data == null) { 235 return null; 236 } 237 return BitmapFactory.decodeByteArray(data, 0, data.length); 238 } 239 240 private MenuItem.OnMenuItemClickListener mContextItemClickListener = 241 new MenuItem.OnMenuItemClickListener() { 242 @Override 243 public boolean onMenuItemClick(MenuItem item) { 244 return onContextItemSelected(item); 245 } 246 }; 247 248 @Override 249 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 250 BookmarkContextMenuInfo info = (BookmarkContextMenuInfo) menuInfo; 251 BrowserBookmarksAdapter adapter = getChildAdapter(info.groupPosition); 252 Cursor cursor = adapter.getItem(info.childPosition); 253 if (!canEdit(cursor)) { 254 return; 255 } 256 boolean isFolder 257 = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 258 259 final Activity activity = getActivity(); 260 MenuInflater inflater = activity.getMenuInflater(); 261 inflater.inflate(R.menu.bookmarkscontext, menu); 262 if (isFolder) { 263 menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true); 264 } else { 265 menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true); 266 if (mDisableNewWindow) { 267 menu.findItem(R.id.new_window_context_menu_id).setVisible(false); 268 } 269 } 270 BookmarkItem header = new BookmarkItem(activity); 271 populateBookmarkItem(cursor, header, isFolder); 272 menu.setHeaderView(header); 273 274 int count = menu.size(); 275 for (int i = 0; i < count; i++) { 276 menu.getItem(i).setOnMenuItemClickListener(mContextItemClickListener); 277 } 278 } 279 280 boolean canEdit(Cursor c) { 281 String unique = c.getString(BookmarksLoader.COLUMN_INDEX_SERVER_UNIQUE); 282 return !ChromeSyncColumns.FOLDER_NAME_OTHER_BOOKMARKS.equals(unique); 283 } 284 285 private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder) { 286 item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 287 if (isFolder) { 288 item.setUrl(null); 289 Bitmap bitmap = 290 BitmapFactory.decodeResource(getResources(), R.drawable.ic_folder_holo_dark); 291 item.setFavicon(bitmap); 292 new LookupBookmarkCount(getActivity(), item) 293 .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 294 } else { 295 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 296 item.setUrl(url); 297 Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 298 if (bitmap == null) { 299 bitmap = CombinedBookmarkHistoryView.getIconListenerSet().getFavicon(url); 300 } 301 item.setFavicon(bitmap); 302 } 303 } 304 305 /** 306 * Create a new BrowserBookmarksPage. 307 */ 308 @Override 309 public void onCreate(Bundle icicle) { 310 super.onCreate(icicle); 311 Bundle args = getArguments(); 312 mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false); 313 setHasOptionsMenu(true); 314 } 315 316 @Override 317 public View onCreateView(LayoutInflater inflater, ViewGroup container, 318 Bundle savedInstanceState) { 319 mRoot = inflater.inflate(R.layout.bookmarks, container, false); 320 mEmptyView = mRoot.findViewById(android.R.id.empty); 321 322 mGrid = (BookmarkExpandableView) mRoot.findViewById(R.id.grid); 323 mGrid.setOnChildClickListener(this); 324 mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail); 325 mGrid.setBreadcrumbController(this); 326 setEnableContextMenu(mEnableContextMenu); 327 mDragHandler = new BookmarkDragHandler(getActivity(), mDragController, 328 mGrid.getDragAdapter()); 329 330 // Start the loaders 331 LoaderManager lm = getLoaderManager(); 332 lm.restartLoader(LOADER_ACCOUNTS, null, this); 333 334 return mRoot; 335 } 336 337 @Override 338 public void onDestroyView() { 339 super.onDestroyView(); 340 mGrid.setBreadcrumbController(null); 341 LoaderManager lm = getLoaderManager(); 342 lm.destroyLoader(LOADER_ACCOUNTS); 343 for (int id : mBookmarkAdapters.keySet()) { 344 lm.destroyLoader(id); 345 } 346 mBookmarkAdapters.clear(); 347 } 348 349 private BrowserBookmarksAdapter getChildAdapter(int groupPosition) { 350 return mGrid.getChildAdapter(groupPosition); 351 } 352 353 private BreadCrumbView getBreadCrumbs(int groupPosition) { 354 return mGrid.getBreadCrumbs(groupPosition); 355 } 356 357 @Override 358 public boolean onChildClick(ExpandableListView parent, View v, 359 int groupPosition, int childPosition, long id) { 360 BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition); 361 Cursor cursor = adapter.getItem(childPosition); 362 boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 363 if (mCallbacks != null && 364 mCallbacks.onBookmarkSelected(cursor, isFolder)) { 365 return true; 366 } 367 368 // TODO: Folder stuff 369 if (isFolder) { 370 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 371 Uri uri = ContentUris.withAppendedId( 372 BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id); 373 BreadCrumbView crumbs = getBreadCrumbs(groupPosition); 374 if (crumbs != null) { 375 // update crumbs 376 crumbs.pushView(title, uri); 377 } 378 loadFolder(groupPosition, uri); 379 } 380 return true; 381 } 382 383 /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) { 384 String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL); 385 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 386 Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON); 387 Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON); 388 return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon); 389 } 390 391 private void loadUrl(BrowserBookmarksAdapter adapter, int position) { 392 if (mCallbacks != null && adapter != null) { 393 mCallbacks.onBookmarkSelected(adapter.getItem(position), false); 394 } 395 } 396 397 private void openInNewWindow(BrowserBookmarksAdapter adapter, int position) { 398 if (mCallbacks != null) { 399 Cursor c = adapter.getItem(position); 400 boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1; 401 if (isFolder) { 402 long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID); 403 new OpenAllInTabsTask(id).execute(); 404 } else { 405 mCallbacks.onOpenInNewWindow(BrowserBookmarksPage.getUrl(c)); 406 } 407 } 408 } 409 410 class OpenAllInTabsTask extends AsyncTask<Void, Void, Cursor> { 411 long mFolderId; 412 public OpenAllInTabsTask(long id) { 413 mFolderId = id; 414 } 415 416 @Override 417 protected Cursor doInBackground(Void... params) { 418 Context c = getActivity(); 419 if (c == null) return null; 420 return c.getContentResolver().query(BookmarkUtils.getBookmarksUri(c), 421 BookmarksLoader.PROJECTION, BrowserContract.Bookmarks.PARENT + "=?", 422 new String[] { Long.toString(mFolderId) }, null); 423 } 424 425 @Override 426 protected void onPostExecute(Cursor result) { 427 if (mCallbacks != null && result.getCount() > 0) { 428 String[] urls = new String[result.getCount()]; 429 int i = 0; 430 while (result.moveToNext()) { 431 urls[i++] = BrowserBookmarksPage.getUrl(result); 432 } 433 mCallbacks.onOpenInNewWindow(urls); 434 } 435 } 436 437 } 438 439 private void editBookmark(BrowserBookmarksAdapter adapter, int position) { 440 Intent intent = new Intent(getActivity(), AddBookmarkPage.class); 441 Cursor cursor = adapter.getItem(position); 442 Bundle item = new Bundle(); 443 item.putString(BrowserContract.Bookmarks.TITLE, 444 cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE)); 445 item.putString(BrowserContract.Bookmarks.URL, 446 cursor.getString(BookmarksLoader.COLUMN_INDEX_URL)); 447 byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON); 448 if (data != null) { 449 item.putParcelable(BrowserContract.Bookmarks.FAVICON, 450 BitmapFactory.decodeByteArray(data, 0, data.length)); 451 } 452 item.putLong(BrowserContract.Bookmarks._ID, 453 cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID)); 454 item.putLong(BrowserContract.Bookmarks.PARENT, 455 cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT)); 456 intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item); 457 intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER, 458 cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1); 459 startActivity(intent); 460 } 461 462 private void displayRemoveBookmarkDialog(BrowserBookmarksAdapter adapter, 463 int position) { 464 // Put up a dialog asking if the user really wants to 465 // delete the bookmark 466 Cursor cursor = adapter.getItem(position); 467 long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID); 468 String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE); 469 Context context = getActivity(); 470 BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null); 471 } 472 473 private String getUrl(BrowserBookmarksAdapter adapter, int position) { 474 return getUrl(adapter.getItem(position)); 475 } 476 477 /* package */ static String getUrl(Cursor c) { 478 return c.getString(BookmarksLoader.COLUMN_INDEX_URL); 479 } 480 481 private void copy(CharSequence text) { 482 ClipboardManager cm = (ClipboardManager) getActivity().getSystemService( 483 Context.CLIPBOARD_SERVICE); 484 cm.setPrimaryClip(ClipData.newRawUri(null, Uri.parse(text.toString()))); 485 } 486 487 @Override 488 public void onConfigurationChanged(Configuration newConfig) { 489 super.onConfigurationChanged(newConfig); 490 Resources res = getActivity().getResources(); 491 mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail); 492 int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop); 493 mRoot.setPadding(0, paddingTop, 0, 0); 494 getActivity().invalidateOptionsMenu(); 495 } 496 497 /** 498 * BreadCrumb controller callback 499 */ 500 @Override 501 public void onTop(BreadCrumbView view, int level, Object data) { 502 int groupPosition = (Integer) view.getTag(R.id.group_position); 503 Uri uri = (Uri) data; 504 if (uri == null) { 505 // top level 506 uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER; 507 } 508 loadFolder(groupPosition, uri); 509 } 510 511 /** 512 * @param uri 513 */ 514 private void loadFolder(int groupPosition, Uri uri) { 515 LoaderManager manager = getLoaderManager(); 516 // This assumes groups are ordered the same as loaders 517 BookmarksLoader loader = (BookmarksLoader) ((Loader<?>) 518 manager.getLoader(LOADER_BOOKMARKS + groupPosition)); 519 loader.setUri(uri); 520 loader.forceLoad(); 521 } 522 523 public boolean onBackPressed() { 524 return false; 525 } 526 527 public void setCallbackListener(BookmarksPageCallbacks callbackListener) { 528 mCallbacks = callbackListener; 529 } 530 531 public void setEnableContextMenu(boolean enable) { 532 mEnableContextMenu = enable; 533 if (mGrid != null) { 534 if (mEnableContextMenu) { 535 registerForContextMenu(mGrid); 536 } else { 537 unregisterForContextMenu(mGrid); 538 mGrid.setLongClickable(false); 539 } 540 } 541 } 542 543 private BookmarkDragController mDragController = new BookmarkDragController() { 544 545 @Override 546 public boolean startDrag(Cursor item) { 547 return canEdit(item); 548 } 549 550 @Override 551 public ViewGroup getActionModeView(ActionMode mode, 552 BookmarkDragState state) { 553 LayoutInflater inflater = LayoutInflater.from(getActivity()); 554 LinearLayout view = (LinearLayout) inflater.inflate( 555 R.layout.bookmarks_drag_actionmode, null); 556 view.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE); 557 ExtraDragState extraState = (ExtraDragState) state.extraState; 558 BrowserBookmarksAdapter adapter = getChildAdapter(extraState.groupPosition); 559 Cursor c = adapter.getItem(extraState.childPosition); 560 boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0; 561 if (isFolder) { 562 view.findViewById(R.id.open_context_menu_id).setVisibility(View.GONE); 563 ImageView iv = (ImageView) view.findViewById( 564 R.id.new_window_context_menu_id); 565 iv.setImageResource(R.drawable.ic_windows_holo_dark); 566 } 567 return view; 568 } 569 570 @Override 571 public void actionItemClicked(View v, BookmarkDragState state) { 572 if (v.getId() == R.id.info) { 573 mGrid.showContextMenuForState(state); 574 } else { 575 ExtraDragState extraState = (ExtraDragState) state.extraState; 576 handleContextItem(v.getId(), extraState.groupPosition, 577 extraState.childPosition); 578 } 579 } 580 }; 581 582 private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> { 583 Context mContext; 584 BookmarkItem mHeader; 585 586 public LookupBookmarkCount(Context context, BookmarkItem header) { 587 mContext = context; 588 mHeader = header; 589 } 590 591 @Override 592 protected Integer doInBackground(Long... params) { 593 if (params.length != 1) { 594 throw new IllegalArgumentException("Missing folder id!"); 595 } 596 Uri uri = BookmarkUtils.getBookmarksUri(mContext); 597 Cursor c = mContext.getContentResolver().query(uri, 598 null, BrowserContract.Bookmarks.PARENT + "=?", 599 new String[] {params[0].toString()}, null); 600 return c.getCount(); 601 } 602 603 @Override 604 protected void onPostExecute(Integer result) { 605 if (result > 0) { 606 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount, 607 result)); 608 } else if (result == 0) { 609 mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty)); 610 } 611 } 612 } 613 614 static class AccountsLoader extends CursorLoader { 615 616 static String[] ACCOUNTS_PROJECTION = new String[] { 617 Accounts.ACCOUNT_NAME, 618 Accounts.ACCOUNT_TYPE 619 }; 620 621 public AccountsLoader(Context context) { 622 super(context, Accounts.CONTENT_URI, ACCOUNTS_PROJECTION, null, null, 623 Accounts.ACCOUNT_NAME + " ASC"); 624 } 625 626 } 627} 628