1e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov/* 2e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project 3e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * 4e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 5e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * you may not use this file except in compliance with the License. 6e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * You may obtain a copy of the License at 7e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * 8e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 9e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * 10e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 11e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 12e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * See the License for the specific language governing permissions and 14e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * limitations under the License. 15e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov */ 16e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovpackage com.android.contacts.list; 17e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 18e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.content.Context; 193c46291ef057eaf7b7f8ca5971e59bebe734a660Jeff Hamiltonimport android.content.CursorLoader; 20e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.database.Cursor; 2114ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onukiimport android.database.CursorWrapper; 22e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovimport android.net.Uri; 23e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 24e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov/** 25e124722daa8a4b31308d53e3f0457c3b66a20ae5Dmitri Plotnikov * A specialized loader for the Join Contacts UI. It executes two queries: 26e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov * join suggestions and (optionally) the full contact list. 2714ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki * 2814ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki * This loader also loads the "suggestion" cursor, which can be accessed with: 2914ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki * {@code ((JoinContactLoaderResult) result).suggestionCursor } 30e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov */ 31e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikovpublic class JoinContactLoader extends CursorLoader { 32e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 33e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov private String[] mProjection; 34e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov private Uri mSuggestionUri; 3514ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki 3614ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki /** 3714ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki * Actual returned class. It's guaranteed that this loader always returns an instance of this 3814ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki * class. This class is needed to tie the lifecycle of the second cursor to that of the 3914ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki * primary one. 4014ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki * 4114ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki * Note we can't change the result type of this loader itself, because CursorLoader 4214ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki * extends AsyncTaskLoader<Cursor>, not AsyncTaskLoader<? extends Cursor> 4314ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki */ 4414ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki public static class JoinContactLoaderResult extends CursorWrapper { 4514ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki public final Cursor suggestionCursor; 4614ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki 4714ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki public JoinContactLoaderResult(Cursor baseCursor, Cursor suggestionCursor) { 4814ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki super(baseCursor); 4914ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki this.suggestionCursor = suggestionCursor; 5014ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki } 5114ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki 5214ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki @Override 5314ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki public void close() { 5414ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki try { 5574b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner if (suggestionCursor != null) { 5674b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner suggestionCursor.close(); 5774b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner } 5814ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki } finally { 5974b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner if (super.getWrappedCursor() != null) { 6074b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner super.close(); 6174b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner } 6214ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki } 6314ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki } 6414ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki } 65e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 66e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov public JoinContactLoader(Context context) { 67e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov super(context, null, null, null, null, null); 68e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 69e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 70e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov public void setSuggestionUri(Uri uri) { 71e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov this.mSuggestionUri = uri; 72e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 73e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 74e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov @Override 75e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov public void setProjection(String[] projection) { 76e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov super.setProjection(projection); 77e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov this.mProjection = projection; 78e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 79e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov 80e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov @Override 813c46291ef057eaf7b7f8ca5971e59bebe734a660Jeff Hamilton public Cursor loadInBackground() { 82e124722daa8a4b31308d53e3f0457c3b66a20ae5Dmitri Plotnikov // First execute the suggestions query, then call super.loadInBackground 83e124722daa8a4b31308d53e3f0457c3b66a20ae5Dmitri Plotnikov // to load the entire list 8414ca86206ce0a54c316e1062c5ed9ee4dee44674Makoto Onuki final Cursor suggestionsCursor = getContext().getContentResolver() 85ecd392b81d65a5dd5511b2f96bbedfb5b8157ae7Daisuke Miyakawa .query(mSuggestionUri, mProjection, null, null, null); 8674b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner if (suggestionsCursor == null) { 8774b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner return null; 8874b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner } 8974b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner Cursor cursorToClose = suggestionsCursor; 9074b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner try { 9174b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner final Cursor baseCursor = super.loadInBackground(); 9274b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner if (baseCursor != null) { 9374b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner final JoinContactLoaderResult result = 9474b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner new JoinContactLoaderResult(baseCursor, suggestionsCursor); 9574b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner cursorToClose = null; 9674b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner return result; 9774b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner } 9874b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner } finally { 9974b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner if (cursorToClose != null) { 10074b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner cursorToClose.close(); 10174b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner } 10274b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner } 10374b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner return null; 104e4d32d92b10c1c1ce89c7a3ee4111a030e6afcf9Dmitri Plotnikov } 10574b5d6ce8300ae5009938b8f846688b5950215fbJay Shrauner} 106