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