-1

CursorLoader を SQLiteDatabase で使用する方法を説明するいくつかのチュートリアルに従いました。ListView を実行すると、結果が返されません。Eclipse プラグインを使用して、データベースに 1 つのエントリがあることを確認しました。

これは、sqliteopenhelper を実装した私の contentprovider です。

public class DiaryDataProvider extends ContentProvider {

public static final String DATABASE_NAME = "data.db";
public static final int DATABASE_VERSION = 1;

// implementation of SQLiteOpenHelper
private static class DiaryDbHelper extends SQLiteOpenHelper {
    // creating and deleting the database and table
    private static final String TEXT_TYPE = " TEXT";
    private static final String REAL_TYPE = " REAL";
    private static final String INTEGER_TYPE = " INTEGER";
    private static final String COMMA_SEP = ",";

    private static final String SQL_CREATE_ENTRIES = "CREATE TABLE "
            + DiarySchema.TABLE_NAME + " (" + DiarySchema._ID
            + " INTEGER PRIMARY KEY," + DiarySchema.COLUMN_NAME_DIARY_ID
            + TEXT_TYPE + COMMA_SEP + DiarySchema.COLUMN_NAME_DATE
            + TEXT_TYPE + COMMA_SEP + DiarySchema.COLUMN_NAME_TIME
            + TEXT_TYPE + COMMA_SEP + DiarySchema.COLUMN_NAME_SEVERITY
            + TEXT_TYPE + COMMA_SEP + DiarySchema.COLUMN_NAME_LOCATION_LAT
            + REAL_TYPE + COMMA_SEP + DiarySchema.COLUMN_NAME_LOCATION_LONG
            + REAL_TYPE + COMMA_SEP
            + DiarySchema.COLUMN_NAME_LOCATION_DETAIL + TEXT_TYPE
            + COMMA_SEP + DiarySchema.COLUMN_NAME_HAS_FOOD + INTEGER_TYPE
            + COMMA_SEP + DiarySchema.COLUMN_NAME_DETAILS + TEXT_TYPE
            + " )";

    public DiaryDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + DiarySchema.TABLE_NAME);
        onCreate(db);
    }
}

private DiaryDbHelper dbHelper;

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    SQLiteDatabase db = dbHelper.getReadableDatabase();
    final int match = DiarySchema.URI_MATCHER.match(uri);
    switch (match) {
    // retrieve diary list
    case DiarySchema.PATH_TOKEN: {
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(DiarySchema.TABLE_NAME);
        return db.delete(DiarySchema.TABLE_NAME, selection, selectionArgs);
    }
    default:
        return 0;
    }

}

@Override
public String getType(Uri uri) {
    final int match = DiarySchema.URI_MATCHER.match(uri);
    switch (match) {
    case DiarySchema.PATH_TOKEN:
        return DiarySchema.CONTENT_TYPE_DIR;
    case DiarySchema.PATH_FOR_ID_TOKEN:
        return DiarySchema.CONTENT_ITEM_TYPE;
    default:
        throw new UnsupportedOperationException("URI " + uri
                + " is not supported.");
    }
}

@Override
public Uri insert(Uri uri, ContentValues values) {
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    int token = DiarySchema.URI_MATCHER.match(uri);
    switch (token) {
    case DiarySchema.PATH_TOKEN: {
        long id = db.insert(DiarySchema.TABLE_NAME, null, values);
        getContext().getContentResolver().notifyChange(uri, null);
        return DiarySchema.CONTENT_URI.buildUpon()
                .appendPath(String.valueOf(id)).build();
    }
    default: {
        throw new UnsupportedOperationException("URI: " + uri
                + " not supported.");
    }
    }
}

@Override
public boolean onCreate() {
    dbHelper = new DiaryDbHelper(getContext());
    return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {
    SQLiteDatabase db = dbHelper.getReadableDatabase();
    final int match = DiarySchema.URI_MATCHER.match(uri);
    switch (match) {
    // retrieve diary list
    case DiarySchema.PATH_TOKEN: {
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(DiarySchema.TABLE_NAME);
        return builder.query(db, projection, selection, null, null, sortOrder, null);
    }
    default:
        return null;
    }
}

@Override
public int update(Uri uri, ContentValues values, String selection,
        String[] selectionArgs) {
    SQLiteDatabase db = dbHelper.getReadableDatabase();
    final int match = DiarySchema.URI_MATCHER.match(uri);
    switch (match) {
    // retrieve diary list
    case DiarySchema.PATH_TOKEN: {
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(DiarySchema.TABLE_NAME);
        return db.update(DiarySchema.TABLE_NAME, values, selection,
                selectionArgs);
    }
    default:
        return 0;
    }

}
}

これはそれに付随するスキーマです

public abstract class DiarySchema implements BaseColumns {
public static final String TABLE_NAME = "diary";
public static final String COLUMN_NAME_DIARY_ID = "diaryid";
public static final String COLUMN_NAME_DATE = "date";
public static final String COLUMN_NAME_TIME = "time";
public static final String COLUMN_NAME_SEVERITY = "severity";
public static final String COLUMN_NAME_LOCATION_LAT = "locationlat";
public static final String COLUMN_NAME_LOCATION_LONG = "locationlong";
public static final String COLUMN_NAME_LOCATION_DETAIL = "locationdetail";
public static final String COLUMN_NAME_DETAILS = "details";
public static final String COLUMN_NAME_HAS_FOOD = "hasfood";

public static final String PATH = "diaries";
public static final int PATH_TOKEN = 100;
public static final String PATH_FOR_ID = "diaries/#";
public static final int PATH_FOR_ID_TOKEN = 200;

public static final String CONTENT_TYPE_DIR = ContentResolver.CURSOR_DIR_BASE_TYPE + "/diaries";
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/diaries";

public static final String AUTHORITY = "com.foo.bar.contentproviders";
private static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY);
public static final UriMatcher URI_MATCHER = buildUriMatcher();
public static final Uri CONTENT_URI = BASE_URI.buildUpon().appendPath(PATH)
        .build();

private static UriMatcher buildUriMatcher() {
    final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    final String authority = AUTHORITY;

    matcher.addURI(authority, PATH, PATH_TOKEN);
    matcher.addURI(authority, PATH_FOR_ID, PATH_FOR_ID_TOKEN);

    return matcher;
}

// Prevent anyone from instantiating this class
private DiarySchema() {
};
}

私の ContentProvider は androidmanifest.xml ファイルで次のように宣言されています...

<provider
        android:name="com.foo.bar.contentproviders.DiaryDataProvider"
        android:authorities="com.foo.bar.contentproviders"
        android:exported="false" />

私のListFragmentは次のようになります...

public class FragDiaryEntries extends SherlockListFragment implements
    LoaderManager.LoaderCallbacks<Cursor> {
private static final int URL_LOADER = 0;
private View view;
private Map<Integer, DiaryHolder> diaryHolders = new HashMap<Integer, DiaryHolder>();
CustomAdapter adapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    view = inflater.inflate(R.layout.frag_diary_entries, container);

    // start the cursor loader getting data to populate diary view
    getLoaderManager().initLoader(URL_LOADER, null, this);

    // Set up adapter
    adapter = new CustomAdapter(getActivity().getApplicationContext(), null);
    setListAdapter(adapter);

    return view;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // TODO different indicator of no data yet
    ((TextView) getListView().getEmptyView()).setText("It's Empty");

    super.onActivityCreated(savedInstanceState);
}



/* Loader callback implemented methods */

@Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
    Loader<Cursor> cursorLoader = null;

    // Get all of the diary entries
    switch (loaderId) {
    case URL_LOADER:
        String[] projection = { DiarySchema._ID,
                DiarySchema.COLUMN_NAME_DATE, DiarySchema.COLUMN_NAME_TIME,
                DiarySchema.COLUMN_NAME_SEVERITY,
                DiarySchema.COLUMN_NAME_LOCATION_LAT,
                DiarySchema.COLUMN_NAME_LOCATION_LONG,
                DiarySchema.COLUMN_NAME_LOCATION_DETAIL,
                DiarySchema.COLUMN_NAME_DETAILS,
                DiarySchema.COLUMN_NAME_HAS_FOOD };

        cursorLoader = new CursorLoader(getActivity(),
                DiarySchema.CONTENT_URI, projection, null, null, null);

    }
    return cursorLoader;
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    adapter.swapCursor(cursor);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    adapter.swapCursor(null);
}

// Custom CursorAdapter
private class CustomAdapter extends CursorAdapter {

    private Cursor cursor;

    public CustomAdapter(Context context, Cursor c) {
        super(context, c, 0);
        this.cursor = c;
    }

    @Override
    public int getCount() {
        return cursor == null ? 0 : cursor.getCount();
    }

    @Override
    public Cursor getCursor() {
        return super.getCursor();
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        int position = cursor.getPosition();

        // Map values from cursor to fields
        TextView created = (TextView) view.findViewById(R.id.diary_created);
        TextView severity = (TextView) view
                .findViewById(R.id.diary_severity);
        TextView location = (TextView) view
                .findViewById(R.id.diary_location);
        CheckBox checkbox = (CheckBox) view
                .findViewById(R.id.diary_item_checked);

        // Create a holder object to store some row details
        if (!diaryHolders.containsKey(position)) {
            // Put the cursor in the correct position
            cursor.moveToPosition(position);

            String date = cursor.getString(cursor
                    .getColumnIndexOrThrow(DiarySchema.COLUMN_NAME_DATE));
            String time = cursor.getString(cursor
                    .getColumnIndexOrThrow(DiarySchema.COLUMN_NAME_TIME));
            created.setText(date + " at " + time);

            String sev = cursor
                    .getString(cursor
                            .getColumnIndexOrThrow(DiarySchema.COLUMN_NAME_SEVERITY));
            severity.setText(sev);

            String loc = cursor
                    .getString(cursor
                            .getColumnIndexOrThrow(DiarySchema.COLUMN_NAME_LOCATION_DETAIL));
            location.setText(loc);

            // Other values to put into holder
            long latitude = cursor
                    .getLong(cursor
                            .getColumnIndexOrThrow(DiarySchema.COLUMN_NAME_LOCATION_LAT));
            long longitude = cursor
                    .getLong(cursor
                            .getColumnIndexOrThrow(DiarySchema.COLUMN_NAME_LOCATION_LONG));
            int hasFood = cursor
                    .getInt(cursor
                            .getColumnIndexOrThrow(DiarySchema.COLUMN_NAME_HAS_FOOD));

            diaryHolders.put(position,
                    new DiaryHolder(position, checkbox.isChecked(),
                            new Diary(date, time, sev, loc, latitude,
                                    longitude, hasFood)));
        } else {

            // Populate from map
            DiaryHolder holder = diaryHolders.get(position);
            Diary diary = holder.getDiaryData();

            created.setText(diary.getDate().concat(diary.getTime()));
            severity.setText(diary.getSeverity());
            location.setText(diary.getLocationDetail());
            checkbox.setChecked(holder.isSelected());
        }

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup container) {

        // Inflate a new view
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.diary_list_item, container);
        bindView(view, context, cursor);
        return view;
    }

}

// Holder class for row values
private class DiaryHolder {
    private long rowId;
    private boolean selected;
    private Diary diaryData;

    public DiaryHolder(long rowId, boolean selected, Diary diaryData) {
        this.rowId = rowId;
        this.selected = selected;
        this.diaryData = diaryData;
    }

    public Diary getDiaryData() {
        return diaryData;
    }

    public void setDiaryData(Diary diaryData) {
        this.diaryData = diaryData;
    }

    public long getRowId() {
        return rowId;
    }

    public void setRowId(long rowId) {
        this.rowId = rowId;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

}

}

レコードを挿入できたので、ContentProvider の挿入部分が機能することはわかっています。私がやりたいことは、すべてのデータを引き出してリストビューに表示することです。どんな助けでも大歓迎です。

4

2 に答える 2

0

さて、私は答えを見つけました。CustomAdapter の getCursor() メソッドをオーバーライドしたところ、super.getCursor(); が返されました。明らかに(当然)アダプターオブジェクトをインスタンス化したときにスーパーのカーソルがnullに設定されたため、常にnullが返されました:)

ご提案いただきありがとうございます。

于 2013-06-26T17:07:25.067 に答える