1 /* 2 * Copyright (C) 2010 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 package com.android.contacts.list; 17 18 import android.content.Context; 19 import android.content.CursorLoader; 20 import android.database.Cursor; 21 import android.database.CursorWrapper; 22 import android.net.Uri; 23 24 /** 25 * A specialized loader for the Join Contacts UI. It executes two queries: 26 * join suggestions and (optionally) the full contact list. 27 * 28 * This loader also loads the "suggestion" cursor, which can be accessed with: 29 * {@code ((JoinContactLoaderResult) result).suggestionCursor } 30 */ 31 public class JoinContactLoader extends CursorLoader { 32 33 private String[] mProjection; 34 private Uri mSuggestionUri; 35 36 /** 37 * Actual returned class. It's guaranteed that this loader always returns an instance of this 38 * class. This class is needed to tie the lifecycle of the second cursor to that of the 39 * primary one. 40 * 41 * Note we can't change the result type of this loader itself, because CursorLoader 42 * extends AsyncTaskLoader<Cursor>, not AsyncTaskLoader<? extends Cursor> 43 */ 44 public static class JoinContactLoaderResult extends CursorWrapper { 45 public final Cursor suggestionCursor; 46 JoinContactLoaderResult(Cursor baseCursor, Cursor suggestionCursor)47 public JoinContactLoaderResult(Cursor baseCursor, Cursor suggestionCursor) { 48 super(baseCursor); 49 this.suggestionCursor = suggestionCursor; 50 } 51 52 @Override close()53 public void close() { 54 try { 55 if (suggestionCursor != null) { 56 suggestionCursor.close(); 57 } 58 } finally { 59 if (super.getWrappedCursor() != null) { 60 super.close(); 61 } 62 } 63 } 64 } 65 JoinContactLoader(Context context)66 public JoinContactLoader(Context context) { 67 super(context, null, null, null, null, null); 68 } 69 setSuggestionUri(Uri uri)70 public void setSuggestionUri(Uri uri) { 71 this.mSuggestionUri = uri; 72 } 73 74 @Override setProjection(String[] projection)75 public void setProjection(String[] projection) { 76 super.setProjection(projection); 77 this.mProjection = projection; 78 } 79 80 @Override loadInBackground()81 public Cursor loadInBackground() { 82 // First execute the suggestions query, then call super.loadInBackground 83 // to load the entire list 84 final Cursor suggestionsCursor = getContext().getContentResolver() 85 .query(mSuggestionUri, mProjection, null, null, null); 86 if (suggestionsCursor == null) { 87 return null; 88 } 89 Cursor cursorToClose = suggestionsCursor; 90 try { 91 final Cursor baseCursor = super.loadInBackground(); 92 if (baseCursor != null) { 93 final JoinContactLoaderResult result = 94 new JoinContactLoaderResult(baseCursor, suggestionsCursor); 95 cursorToClose = null; 96 return result; 97 } 98 } finally { 99 if (cursorToClose != null) { 100 cursorToClose.close(); 101 } 102 } 103 return null; 104 } 105 } 106