CursorAdapter.java revision c91893511dc1b9e634648406c9ae61b15476e65d
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.DataSetObserver;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Adapter that exposes data from a {@link android.database.Cursor Cursor} to a
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.widget.ListView ListView} widget. The Cursor must include
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a column named "_id" or this class will not work.
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class CursorAdapter extends BaseAdapter implements Filterable,
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CursorFilter.CursorFilterClient {
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean mDataValid;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected boolean mAutoRequery;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected Cursor mCursor;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected Context mContext;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected int mRowIDColumn;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected ChangeObserver mChangeObserver;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
70c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    protected DataSetObserver mDataSetObserver;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected CursorFilter mCursorFilter;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This field should be made private, so it is hidden from the SDK.
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@hide}
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected FilterQueryProvider mFilterQueryProvider;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
83451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * If set the adapter will call requery() on the cursor whenever a content change
84c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * notification is delivered. Implies {@link #FLAG_REGISTER_CONTENT_OBSERVER}.
85c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
86c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @deprecated This option is discouraged, as it results in Cursor queries
87c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * being performed on the application's UI thread and thus can cause poor
88c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * responsiveness or even Application Not Responding errors.  As an alternative,
89c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
90451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     */
91c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    @Deprecated
92451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    public static final int FLAG_AUTO_REQUERY = 0x01;
93451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
94451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    /**
95451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * If set the adapter will register a content observer on the cursor and will call
96c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * {@link #onContentChanged()} when a notification comes in.  Be careful when
97c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * using this flag: you will need to unset the current Cursor from the adapter
98c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * to avoid leaks due to its registered observers.  This flag is not needed
99c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * when using a CursorAdapter with a
100c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * {@link android.content.CursorLoader}.
101451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     */
102451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    public static final int FLAG_REGISTER_CONTENT_OBSERVER = 0x02;
103451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
104451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    /**
105c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Constructor that always enables auto-requery.
106c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
107c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @deprecated This option is discouraged, as it results in Cursor queries
108c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * being performed on the application's UI thread and thus can cause poor
109c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * responsiveness or even Application Not Responding errors.  As an alternative,
110c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param c The cursor from which to get the data.
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
115c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    @Deprecated
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CursorAdapter(Context context, Cursor c) {
117451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        init(context, c, FLAG_AUTO_REQUERY);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
121c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Constructor that allows control over auto-requery.  It is recommended
122c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * you not use this, but instead {@link #CursorAdapter(Context, Cursor, int)}.
123c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * When using this constructor, {@link #FLAG_REGISTER_CONTENT_OBSERVER}
124c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * will always be set.
125c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param c The cursor from which to get the data.
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context The context
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param autoRequery If true the adapter will call requery() on the
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                    cursor whenever it changes so the most recent
130c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *                    data is always displayed.  Using true here is discouraged.
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CursorAdapter(Context context, Cursor c, boolean autoRequery) {
13369e87f9b43b82b9a0f8a0fbc1c41251bbea212f9Jeff Hamilton        init(context, c, autoRequery ? FLAG_AUTO_REQUERY : FLAG_REGISTER_CONTENT_OBSERVER);
134451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    }
135451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
136451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    /**
137c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Recommended constructor.
138c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
139451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * @param c The cursor from which to get the data.
140451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     * @param context The context
141c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @param flags Flags used to determine the behavior of the adapter; may
142c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * be any combination of {@link #FLAG_AUTO_REQUERY} and
143c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * {@link #FLAG_REGISTER_CONTENT_OBSERVER}.
144451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton     */
145451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    public CursorAdapter(Context context, Cursor c, int flags) {
146451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        init(context, c, flags);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
149c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    /**
150c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @deprecated Don't use this, use the normal constructor.  This will
151c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * be removed in the future.
152c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     */
153c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    @Deprecated
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void init(Context context, Cursor c, boolean autoRequery) {
15569e87f9b43b82b9a0f8a0fbc1c41251bbea212f9Jeff Hamilton        init(context, c, autoRequery ? FLAG_AUTO_REQUERY : FLAG_REGISTER_CONTENT_OBSERVER);
156451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton    }
157451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
158c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    void init(Context context, Cursor c, int flags) {
159451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        if ((flags & FLAG_AUTO_REQUERY) == FLAG_AUTO_REQUERY) {
160451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            flags |= FLAG_REGISTER_CONTENT_OBSERVER;
161451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mAutoRequery = true;
162451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        } else {
163451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mAutoRequery = false;
164451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean cursorPresent = c != null;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCursor = c;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDataValid = cursorPresent;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
170451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        if ((flags & FLAG_REGISTER_CONTENT_OBSERVER) == FLAG_REGISTER_CONTENT_OBSERVER) {
171451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mChangeObserver = new ChangeObserver();
172c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            mDataSetObserver = new MyDataSetObserver();
173451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        } else {
174451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            mChangeObserver = null;
175c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            mDataSetObserver = null;
176451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton        }
177451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cursorPresent) {
179451513baa7b3fdd04b253b25e441a20a609de2edJeff Hamilton            if (mChangeObserver != null) c.registerContentObserver(mChangeObserver);
180c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mDataSetObserver != null) c.registerDataSetObserver(mDataSetObserver);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the cursor.
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the cursor.
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Cursor getCursor() {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursor;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getCount()
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1952c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public int getCount() {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCursor.getCount();
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getItem(int)
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2062c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public Object getItem(int position) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.moveToPosition(position);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mCursor;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getItemId(int)
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2182c6b3b0c26b8efc40035fb70eec8562016c116a2Jeff Hamilton    public long getItemId(int position) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid && mCursor != null) {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCursor.moveToPosition(position)) {
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mCursor.getLong(mRowIDColumn);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return 0;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean hasStableIds() {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getView(int position, View convertView, ViewGroup parent) {
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mDataValid) {
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("this should only be called when the cursor is valid");
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mCursor.moveToPosition(position)) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("couldn't move cursor to position " + position);
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View v;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (convertView == null) {
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v = newView(mContext, mCursor, parent);
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v = convertView;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bindView(v, mContext, mCursor);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return v;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getDropDownView(int position, View convertView, ViewGroup parent) {
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDataValid) {
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursor.moveToPosition(position);
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View v;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (convertView == null) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = newDropDownView(mContext, mCursor, parent);
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                v = convertView;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bindView(v, mContext, mCursor);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return v;
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Makes a new view to hold the data pointed to by cursor.
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent The parent to which the new view is attached to
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the newly created view.
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract View newView(Context context, Cursor cursor, ViewGroup parent);
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Makes a new drop down view to hold the data pointed to by cursor.
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent The parent to which the new view is attached to
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the newly created view.
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) {
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return newView(context, cursor, parent);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Bind an existing view to the data pointed to by cursor
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param view Existing view, returned earlier by newView
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Interface to application's global information
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor The cursor from which to get the data. The cursor is already
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * moved to the correct position.
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void bindView(View view, Context context, Cursor cursor);
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Change the underlying cursor to a new cursor. If there is an existing cursor it will be
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * closed.
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
307c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @param cursor The new cursor to be used
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void changeCursor(Cursor cursor) {
310c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        Cursor old = swapCursor(cursor);
311c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        if (old != null) {
312c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            old.close();
313c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        }
314c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    }
315c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn
316c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    /**
317c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Swap in a new Cursor, returning the old Cursor.  Unlike
318c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
319c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * closed.
320c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     *
321c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @param newCursor The new cursor to be used.
322c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * @return Returns the previously set Cursor, or null if there wasa not one.
323c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * If the given new Cursor is the same instance is the previously set
324c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     * Cursor, null is also returned.
325c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn     */
326c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn    public Cursor swapCursor(Cursor newCursor) {
327c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        if (newCursor == mCursor) {
328c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            return null;
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
330c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        Cursor oldCursor = mCursor;
331c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        if (oldCursor != null) {
332c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mChangeObserver != null) oldCursor.unregisterContentObserver(mChangeObserver);
333c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mDataSetObserver != null) oldCursor.unregisterDataSetObserver(mDataSetObserver);
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
335c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        mCursor = newCursor;
336c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        if (newCursor != null) {
337c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mChangeObserver != null) newCursor.registerContentObserver(mChangeObserver);
338c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            if (mDataSetObserver != null) newCursor.registerDataSetObserver(mDataSetObserver);
339c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn            mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = true;
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // notify the observers about the new cursor
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetChanged();
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRowIDColumn = -1;
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = false;
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // notify the observers about the lack of a data set
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetInvalidated();
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
349c91893511dc1b9e634648406c9ae61b15476e65dDianne Hackborn        return oldCursor;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Converts the cursor into a CharSequence. Subclasses should override this
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method to convert their results. The default implementation returns an
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * empty String for null values or the default String representation of
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the value.</p>
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cursor the cursor to convert to a CharSequence
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a CharSequence representing the value
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence convertToString(Cursor cursor) {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return cursor == null ? "" : cursor.toString();
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs a query with the specified constraint. This query is requested
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the filter attached to this adapter.
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The query is provided by a
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.widget.FilterQueryProvider}.
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If no provider is specified, the current cursor is not filtered and returned.
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * After this method returns the resulting cursor is passed to {@link #changeCursor(Cursor)}
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and the previous cursor is closed.
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method is always executed on a background thread, not on the
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application's main thread (or UI thread.)
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Contract: when constraint is null or empty, the original results,
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * prior to any filtering, must be returned.
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param constraint the constraint with which the query must be filtered
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a Cursor representing the results of the new query
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilter()
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilterQueryProvider()
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mFilterQueryProvider != null) {
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mFilterQueryProvider.runQuery(constraint);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursor;
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Filter getFilter() {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCursorFilter == null) {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCursorFilter = new CursorFilter(this);
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mCursorFilter;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the query filter provider used for filtering. When the
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provider is null, no filtering occurs.
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the current filter query provider or null if it does not exist
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #runQueryOnBackgroundThread(CharSequence)
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public FilterQueryProvider getFilterQueryProvider() {
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFilterQueryProvider;
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the query filter provider used to filter the current Cursor.
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The provider's
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.widget.FilterQueryProvider#runQuery(CharSequence)}
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method is invoked when filtering is requested by a client of
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this adapter.
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param filterQueryProvider the filter query provider or null to remove it
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getFilterQueryProvider()
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #runQueryOnBackgroundThread(CharSequence)
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFilterQueryProvider(FilterQueryProvider filterQueryProvider) {
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFilterQueryProvider = filterQueryProvider;
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the {@link ContentObserver} on the cursor receives a change notification.
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The default implementation provides the auto-requery logic, but may be overridden by
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sub classes.
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see ContentObserver#onChange(boolean)
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onContentChanged() {
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Config.LOGV) Log.v("Cursor", "Auto requerying " + mCursor + " due to update");
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = mCursor.requery();
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class ChangeObserver extends ContentObserver {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ChangeObserver() {
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(new Handler());
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean deliverSelfNotifications() {
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onChange(boolean selfChange) {
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onContentChanged();
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class MyDataSetObserver extends DataSetObserver {
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onChanged() {
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = true;
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetChanged();
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onInvalidated() {
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataValid = false;
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            notifyDataSetInvalidated();
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
479