依靠自定义ContentProvider

时间:2013-05-06 22:01:52

标签: android sqlite android-contentprovider

我有一个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)

1 个答案:

答案 0 :(得分:2)

来自CursorAdapter

  

Cursor必须包含名为“_id”的列,否则此类将无效。