CursorAdapter.java revision cba2e2c881e8e16ea5025b564c94320174d65f01
1cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/*
2cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project
3cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
4cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * you may not use this file except in compliance with the License.
6cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * You may obtain a copy of the License at
7cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
8cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
10cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * See the License for the specific language governing permissions and
14cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * limitations under the License.
15cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */
16cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
17cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpackage android.support.v4.widget;
18cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
19cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.content.Context;
20cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.database.ContentObserver;
21cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.database.Cursor;
22cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.database.DataSetObserver;
23cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Handler;
24cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.Config;
25cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.Log;
26cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.view.View;
27cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.view.ViewGroup;
28cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.widget.BaseAdapter;
29cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.widget.Filter;
30cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.widget.FilterQueryProvider;
31cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.widget.Filterable;
32cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
33cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/**
34cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Static library support version of the framework's {@link android.widget.CursorAdapter}.
35cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Used to write apps that run on platforms prior to Android 3.0.  When running
36cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * on Android 3.0 or above, this implementation is still used; it does not try
37cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * to switch to the framework's implementation.  See the framework SDK
38cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * documentation for a class overview.
39cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */
40cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpublic abstract class CursorAdapter extends BaseAdapter implements Filterable,
41cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        CursorFilter.CursorFilterClient {
42cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
43cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This field should be made private, so it is hidden from the SDK.
44cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@hide}
45cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
46cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected boolean mDataValid;
47cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
48cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This field should be made private, so it is hidden from the SDK.
49cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@hide}
50cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
51cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected boolean mAutoRequery;
52cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
53cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This field should be made private, so it is hidden from the SDK.
54cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@hide}
55cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
56cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected Cursor mCursor;
57cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
58cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This field should be made private, so it is hidden from the SDK.
59cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@hide}
60cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
61cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected Context mContext;
62cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
63cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This field should be made private, so it is hidden from the SDK.
64cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@hide}
65cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
66cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected int mRowIDColumn;
67cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
68cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This field should be made private, so it is hidden from the SDK.
69cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@hide}
70cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
71cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected ChangeObserver mChangeObserver;
72cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
73cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This field should be made private, so it is hidden from the SDK.
74cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@hide}
75cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
76cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected DataSetObserver mDataSetObserver;
77cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
78cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This field should be made private, so it is hidden from the SDK.
79cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@hide}
80cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
81cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected CursorFilter mCursorFilter;
82cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
83cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This field should be made private, so it is hidden from the SDK.
84cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@hide}
85cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
86cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected FilterQueryProvider mFilterQueryProvider;
87cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
88cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
89cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * If set the adapter will call requery() on the cursor whenever a content change
90cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * notification is delivered. Implies {@link #FLAG_REGISTER_CONTENT_OBSERVER}.
91cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
92cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @deprecated This option is discouraged, as it results in Cursor queries
93cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * being performed on the application's UI thread and thus can cause poor
94cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * responsiveness or even Application Not Responding errors.  As an alternative,
95cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
96cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
97cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    @Deprecated
98cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public static final int FLAG_AUTO_REQUERY = 0x01;
99cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
101cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * If set the adapter will register a content observer on the cursor and will call
102cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@link #onContentChanged()} when a notification comes in.  Be careful when
103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * using this flag: you will need to unset the current Cursor from the adapter
104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * to avoid leaks due to its registered observers.  This flag is not needed
105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * when using a CursorAdapter with a
106cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@link android.content.CursorLoader}.
107cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public static final int FLAG_REGISTER_CONTENT_OBSERVER = 0x02;
109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
110cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Constructor that always enables auto-requery.
112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
113cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @deprecated This option is discouraged, as it results in Cursor queries
114cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * being performed on the application's UI thread and thus can cause poor
115cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * responsiveness or even Application Not Responding errors.  As an alternative,
116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * use {@link android.app.LoaderManager} with a {@link android.content.CursorLoader}.
117cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
118cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param c The cursor from which to get the data.
119cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param context The context
120cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
121cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    @Deprecated
122cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public CursorAdapter(Context context, Cursor c) {
123cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        init(context, c, FLAG_AUTO_REQUERY);
124cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
125cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
126cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
127cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Constructor that allows control over auto-requery.  It is recommended
128cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * you not use this, but instead {@link #CursorAdapter(Context, Cursor, int)}.
129cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * When using this constructor, {@link #FLAG_REGISTER_CONTENT_OBSERVER}
130cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * will always be set.
131cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
132cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param c The cursor from which to get the data.
133cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param context The context
134cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param autoRequery If true the adapter will call requery() on the
135cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *                    cursor whenever it changes so the most recent
136cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *                    data is always displayed.  Using true here is discouraged.
137cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public CursorAdapter(Context context, Cursor c, boolean autoRequery) {
139cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        init(context, c, autoRequery ? FLAG_AUTO_REQUERY : FLAG_REGISTER_CONTENT_OBSERVER);
140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
141cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
142cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
143cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Recommended constructor.
144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param c The cursor from which to get the data.
146cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param context The context
147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param flags Flags used to determine the behavior of the adapter; may
148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * be any combination of {@link #FLAG_AUTO_REQUERY} and
149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@link #FLAG_REGISTER_CONTENT_OBSERVER}.
150cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
151cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public CursorAdapter(Context context, Cursor c, int flags) {
152cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        init(context, c, flags);
153cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
155cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @deprecated Don't use this, use the normal constructor.  This will
157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * be removed in the future.
158cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    @Deprecated
160cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected void init(Context context, Cursor c, boolean autoRequery) {
161cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        init(context, c, autoRequery ? FLAG_AUTO_REQUERY : FLAG_REGISTER_CONTENT_OBSERVER);
162cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
163cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    void init(Context context, Cursor c, int flags) {
165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if ((flags & FLAG_AUTO_REQUERY) == FLAG_AUTO_REQUERY) {
166cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            flags |= FLAG_REGISTER_CONTENT_OBSERVER;
167cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mAutoRequery = true;
168cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
169cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mAutoRequery = false;
170cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
171cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        boolean cursorPresent = c != null;
172cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mCursor = c;
173cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mDataValid = cursorPresent;
174cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mContext = context;
175cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
176cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if ((flags & FLAG_REGISTER_CONTENT_OBSERVER) == FLAG_REGISTER_CONTENT_OBSERVER) {
177cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mChangeObserver = new ChangeObserver();
178cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mDataSetObserver = new MyDataSetObserver();
179cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
180cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mChangeObserver = null;
181cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mDataSetObserver = null;
182cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
183cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
184cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (cursorPresent) {
185cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (mChangeObserver != null) c.registerContentObserver(mChangeObserver);
186cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (mDataSetObserver != null) c.registerDataSetObserver(mDataSetObserver);
187cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
188cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
190cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
191cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Returns the cursor.
192cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @return the cursor.
193cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
194cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public Cursor getCursor() {
195cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mCursor;
196cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
197cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
198cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
199cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see android.widget.ListAdapter#getCount()
200cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
201cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public int getCount() {
202cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mDataValid && mCursor != null) {
203cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return mCursor.getCount();
204cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
205cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return 0;
206cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
207cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
208cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
209cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
210cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see android.widget.ListAdapter#getItem(int)
211cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
212cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public Object getItem(int position) {
213cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mDataValid && mCursor != null) {
214cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mCursor.moveToPosition(position);
215cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return mCursor;
216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return null;
218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
219cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
220cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
221cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
222cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see android.widget.ListAdapter#getItemId(int)
223cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
224cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public long getItemId(int position) {
225cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mDataValid && mCursor != null) {
226cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (mCursor.moveToPosition(position)) {
227cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                return mCursor.getLong(mRowIDColumn);
228cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            } else {
229cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                return 0;
230cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
231cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
232cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return 0;
233cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
234cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
235cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
236cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    @Override
237cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public boolean hasStableIds() {
238cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return true;
239cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
240cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
241cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
242cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
243cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
244cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public View getView(int position, View convertView, ViewGroup parent) {
245cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (!mDataValid) {
246cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            throw new IllegalStateException("this should only be called when the cursor is valid");
247cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
248cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (!mCursor.moveToPosition(position)) {
249cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            throw new IllegalStateException("couldn't move cursor to position " + position);
250cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
251cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        View v;
252cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (convertView == null) {
253cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            v = newView(mContext, mCursor, parent);
254cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
255cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            v = convertView;
256cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
257cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bindView(v, mContext, mCursor);
258cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return v;
259cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
260cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
261cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    @Override
262cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public View getDropDownView(int position, View convertView, ViewGroup parent) {
263cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mDataValid) {
264cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mCursor.moveToPosition(position);
265cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            View v;
266cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (convertView == null) {
267cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                v = newDropDownView(mContext, mCursor, parent);
268cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            } else {
269cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                v = convertView;
270cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
271cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            bindView(v, mContext, mCursor);
272cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return v;
273cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
274cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return null;
275cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
276cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
277cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
278cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
279cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Makes a new view to hold the data pointed to by cursor.
280cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param context Interface to application's global information
281cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param cursor The cursor from which to get the data. The cursor is already
282cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * moved to the correct position.
283cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param parent The parent to which the new view is attached to
284cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @return the newly created view.
285cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
286cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public abstract View newView(Context context, Cursor cursor, ViewGroup parent);
287cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
288cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
289cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Makes a new drop down view to hold the data pointed to by cursor.
290cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param context Interface to application's global information
291cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param cursor The cursor from which to get the data. The cursor is already
292cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * moved to the correct position.
293cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param parent The parent to which the new view is attached to
294cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @return the newly created view.
295cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
296cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) {
297cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return newView(context, cursor, parent);
298cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
299cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
300cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
301cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Bind an existing view to the data pointed to by cursor
302cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param view Existing view, returned earlier by newView
303cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param context Interface to application's global information
304cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param cursor The cursor from which to get the data. The cursor is already
305cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * moved to the correct position.
306cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
307cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public abstract void bindView(View view, Context context, Cursor cursor);
308cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
309cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
310cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Change the underlying cursor to a new cursor. If there is an existing cursor it will be
311cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * closed.
312cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
313cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param cursor The new cursor to be used
314cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
315cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public void changeCursor(Cursor cursor) {
316cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Cursor old = swapCursor(cursor);
317cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (old != null) {
318cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            old.close();
319cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
320cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
321cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
322cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
323cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Swap in a new Cursor, returning the old Cursor.  Unlike
324cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
325cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * closed.
326cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
327cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param newCursor The new cursor to be used.
328cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @return Returns the previously set Cursor, or null if there wasa not one.
329cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * If the given new Cursor is the same instance is the previously set
330cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Cursor, null is also returned.
331cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
332cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public Cursor swapCursor(Cursor newCursor) {
333cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (newCursor == mCursor) {
334cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return null;
335cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
336cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Cursor oldCursor = mCursor;
337cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (oldCursor != null) {
338cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (mChangeObserver != null) oldCursor.unregisterContentObserver(mChangeObserver);
339cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (mDataSetObserver != null) oldCursor.unregisterDataSetObserver(mDataSetObserver);
340cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
341cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mCursor = newCursor;
342cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (newCursor != null) {
343cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (mChangeObserver != null) newCursor.registerContentObserver(mChangeObserver);
344cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (mDataSetObserver != null) newCursor.registerDataSetObserver(mDataSetObserver);
345cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");
346cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mDataValid = true;
347cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            // notify the observers about the new cursor
348cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            notifyDataSetChanged();
349cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
350cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mRowIDColumn = -1;
351cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mDataValid = false;
352cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            // notify the observers about the lack of a data set
353cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            notifyDataSetInvalidated();
354cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
355cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return oldCursor;
356cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
357cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
358cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
359cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * <p>Converts the cursor into a CharSequence. Subclasses should override this
360cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * method to convert their results. The default implementation returns an
361cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * empty String for null values or the default String representation of
362cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * the value.</p>
363cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
364cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param cursor the cursor to convert to a CharSequence
365cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @return a CharSequence representing the value
366cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
367cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public CharSequence convertToString(Cursor cursor) {
368cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return cursor == null ? "" : cursor.toString();
369cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
370cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
371cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
372cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Runs a query with the specified constraint. This query is requested
373cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * by the filter attached to this adapter.
374cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
375cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * The query is provided by a
376cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@link android.widget.FilterQueryProvider}.
377cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * If no provider is specified, the current cursor is not filtered and returned.
378cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
379cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * After this method returns the resulting cursor is passed to {@link #changeCursor(Cursor)}
380cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * and the previous cursor is closed.
381cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
382cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * This method is always executed on a background thread, not on the
383cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * application's main thread (or UI thread.)
384cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
385cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Contract: when constraint is null or empty, the original results,
386cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * prior to any filtering, must be returned.
387cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
388cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param constraint the constraint with which the query must be filtered
389cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
390cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @return a Cursor representing the results of the new query
391cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
392cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see #getFilter()
393cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see #getFilterQueryProvider()
394cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
395cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
396cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
397cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mFilterQueryProvider != null) {
398cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return mFilterQueryProvider.runQuery(constraint);
399cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
400cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
401cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mCursor;
402cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
403cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
404cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public Filter getFilter() {
405cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mCursorFilter == null) {
406cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mCursorFilter = new CursorFilter(this);
407cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
408cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mCursorFilter;
409cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
410cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
411cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
412cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Returns the query filter provider used for filtering. When the
413cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * provider is null, no filtering occurs.
414cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
415cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @return the current filter query provider or null if it does not exist
416cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
417cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see #setFilterQueryProvider(android.widget.FilterQueryProvider)
418cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see #runQueryOnBackgroundThread(CharSequence)
419cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
420cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FilterQueryProvider getFilterQueryProvider() {
421cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mFilterQueryProvider;
422cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
423cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
424cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
425cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Sets the query filter provider used to filter the current Cursor.
426cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * The provider's
427cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * {@link android.widget.FilterQueryProvider#runQuery(CharSequence)}
428cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * method is invoked when filtering is requested by a client of
429cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * this adapter.
430cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
431cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @param filterQueryProvider the filter query provider or null to remove it
432cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
433cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see #getFilterQueryProvider()
434cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see #runQueryOnBackgroundThread(CharSequence)
435cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
436cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public void setFilterQueryProvider(FilterQueryProvider filterQueryProvider) {
437cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mFilterQueryProvider = filterQueryProvider;
438cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
439cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
440cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    /**
441cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * Called when the {@link ContentObserver} on the cursor receives a change notification.
442cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * The default implementation provides the auto-requery logic, but may be overridden by
443cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * sub classes.
444cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     *
445cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     * @see ContentObserver#onChange(boolean)
446cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn     */
447cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    protected void onContentChanged() {
448cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
449cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (Config.LOGV) Log.v("Cursor", "Auto requerying " + mCursor + " due to update");
450cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mDataValid = mCursor.requery();
451cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
452cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
453cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
454cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    private class ChangeObserver extends ContentObserver {
455cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        public ChangeObserver() {
456cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            super(new Handler());
457cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
458cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
459cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        @Override
460cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        public boolean deliverSelfNotifications() {
461cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return true;
462cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
463cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
464cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        @Override
465cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        public void onChange(boolean selfChange) {
466cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            onContentChanged();
467cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
468cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
469cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
470cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    private class MyDataSetObserver extends DataSetObserver {
471cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        @Override
472cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        public void onChanged() {
473cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mDataValid = true;
474cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            notifyDataSetChanged();
475cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
476cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
477cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        @Override
478cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        public void onInvalidated() {
479cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mDataValid = false;
480cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            notifyDataSetInvalidated();
481cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
482cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
483cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
484cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn}
485