我有一个 ContentProvider 工作正常(查询、删除、更新、插入),用于简单查询,具有以下结构:
public static class Promotion implements BaseColumns {
private Promotion() {
}
public static final String TABLE_NAME = "promotions";
public static final String PATH_PROMOTIONS = "/promotions";
public static final String PATH_PROMOTION_ID = "/promotion/#";
public static final Uri CONTENT_URI = Uri.parse(SCHEME + AUTHORITY + PATH_PROMOTIONS);
public static final Uri CONTENT_URI_ID = Uri.parse(SCHEME + AUTHORITY + PATH_PROMOTION_ID);
public static final String COLUMN_NAME_ADVERTISER = "advertiser";
public static final String COLUMN_NAME_SUBJECT = "subject";
public static final String COLUMN_NAME_URL = "promo_url";
public static final String COLUMN_NAME_CATEGORY = "category";
public static final String COLUMN_NAME_READED = "is_readed";
public static final String COLUMN_NAME_STARRED = "is_starred";
public static final String COLUMN_NAME_UNTIL = "until";
public static final String COLUMN_NAME_CREATE_DATE = "created";
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.package.promotion";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.package.promotion";
}
现在我正在为 ListFragment 构建一个 SimpleCursorAdapter,但我需要以下 SQL
SELECT
COLUMN_NAME_ADVERTISER,
COUNT(COLUMN_NAME_ADVERTISER) AS _COUNT
FROM
TABLE_NAME
WHERE
(COLUMN_NAME_READED = ?)
GROUP BY
COLUMN_NAME_ADVERTISER;
这是片段类的简单实现
public class InboxListFragment extends ListFragment {
private SimpleCursorAdapter mAdapter;
@Override
public View onCreateView(
LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
fillData();
}
private void fillData() {
final String[] from = { MyPackage.Promotion.COLUMN_NAME_ADVERTISER,
MyPackage.Promotion._COUNT };
final int[] to = new int[] { android.R.id.text1 };
mAdapter = new SimpleCursorAdapter(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_1, null, from, to, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, new myLoader());
}
public class myLoader implements LoaderCallbacks<Cursor> {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
final String count = String.format("COUNT(%s) as %s",
MyPackage.Promotion.COLUMN_NAME_ADVERTISER, MyPackage.Promotion._COUNT);
final String[] projection = { MyPackage.Promotion.COLUMN_NAME_ADVERTISER,
count };
final String selection = MyPackage.Promotion.COLUMN_NAME_READED + " = ?";
final String[] selectionArgs = { "0" };
final CursorLoader loader = new CursorLoader(getActivity(),
MyPackage.Promotion.CONTENT_URI, projection, selection, selectionArgs,
null);
return loader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mAdapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
}
我得到以下信息:
05-06 21:49:03.914: E/AndroidRuntime(4307): FATAL EXCEPTION: main
05-06 21:49:03.914: E/AndroidRuntime(4307): java.lang.IllegalArgumentException: column '_id' does not exist
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:99)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.widget.CursorAdapter.swapCursor(CursorAdapter.java:344)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.widget.SimpleCursorAdapter.swapCursor(SimpleCursorAdapter.java:326)
05-06 21:49:03.914: E/AndroidRuntime(4307): at com.mypackage.regular.InboxListFragment$myLoader.onLoadFinished(InboxListFragment.java:74)
05-06 21:49:03.914: E/AndroidRuntime(4307): at com.mypackage.regular.InboxListFragment$myLoader.onLoadFinished(InboxListFragment.java:1)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:427)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:395)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.content.Loader.deliverResult(Loader.java:103)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:81)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:35)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:221)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:61)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:461)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.content.ModernAsyncTask.access$500(ModernAsyncTask.java:47)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:474)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.os.Handler.dispatchMessage(Handler.java:99)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.os.Looper.loop(Looper.java:130)
05-06 21:49:03.914: E/AndroidRuntime(4307): at android.app.ActivityThread.main(ActivityThread.java:3683)
05-06 21:49:03.914: E/AndroidRuntime(4307): at java.lang.reflect.Method.invokeNative(Native Method)
05-06 21:49:03.914: E/AndroidRuntime(4307): at java.lang.reflect.Method.invoke(Method.java:507)
05-06 21:49:03.914: E/AndroidRuntime(4307): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-06 21:49:03.914: E/AndroidRuntime(4307): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-06 21:49:03.914: E/AndroidRuntime(4307): at dalvik.system.NativeStart.main(Native Method)