web-dev-qa-db-ja.com

Androidでカーソルローダーを使用してSQLite DBを読み取る方法は?

人々が友人のグループを作成できるように、アプリをセットアップしています。グループが作成されると、2つのテーブルがSQLデータベースに書き込まれます。最初のテーブルには、グループ名とグループIDがあります。 2番目のテーブルには、グループIDとユーザーIDの2つの列があります。これは正常に機能しています。

ただし、データベースから読み取ることができるようになりたいと思います。 cursorloaderでリストビューフラグメントを使用していますが、情報を表示するのに問題があります。リストビューの最初のテーブルのすべてのグループ名をリストしたい。

私の問題は、最初にcursorloaderを使用して連絡先をリストしたときに、Uriメソッドの_content provider_からonCreateLoaderを使用していたことです。具体的には、_CONTENT_URI_クラスの_ContactsContracts.Contacts_がありました。

cursorloaderを含むcontentproviderの例:

_@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    Uri contentUri = ContactsContract.Contacts.CONTENT_URI;
    return new CursorLoader(getActivity(),contentUri,PROJECTION,SELECTION,ARGS,ORDER);
}
_

ただし、コンテンツプロバイダーを使用しないと、return new CursorLoader(...)には2番目の引数にonCreateLoaderが必要なので、Uriメソッドに何を入れるかわかりません。

リストビューでデータベースデータを表示する方法についての提案はありますか?

フラグメントクラスコード:

_public class GroupListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {

CursorAdapter mAdapter;
private OnItemSelectedListener listener;
private static final String[] PROJECTION ={GroupContract.GroupDetails.COLUMN_NAME_GROUP_NAME};
private static final String SELECTION = null;
final String[] FROM = {GroupContract.GroupDetails.COLUMN_NAME_GROUP_NAME};
final int[] TO = {Android.R.id.text1};
private static final String[] ARGS = null;
private static final String ORDER = null;
private Cursor c;


@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    mAdapter = new SimpleCursorAdapter(getActivity(), Android.R.layout.simple_list_item_1,null,FROM,TO,0 );
    ReadDBAsync readDB = new ReadDBAsync();
    readDB.execute();
}

@Override
public void onActivityCreated(Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);
    setListAdapter(mAdapter);
    getLoaderManager().initLoader(0,null,this);
}

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    Uri contenturi = Uri.parse("content://preamble.oneapp");
    Uri tableuri = Uri.withAppendedPath(contenturi,GroupContract.GroupDetails.TABLE_NAME);
    return new CursorLoader(getActivity(),tableuri,PROJECTION,SELECTION,ARGS,ORDER);
}

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

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


private class ReadDBAsync extends AsyncTask<Void,Void,String> {

    @Override
    protected String doInBackground(Void... voids) {

        ContractDBHelpers mDBHelper = new ContractDBHelpers(getActivity());
        SQLiteDatabase db = mDBHelper.getReadableDatabase();
        String returnvalue = "database read";
        c = db.query(GroupContract.GroupDetails.TABLE_NAME,PROJECTION,null,null,null,null,null);
        return returnvalue;
    }

    @Override
    protected void onPostExecute(String result){
        Toast.makeText(getActivity(), result, Toast.LENGTH_LONG).show();
    }
}

}
_
32
Terence Chow

これらは、リストフラグメントにカーソルローダーを作成する手順です。

1)SQLiteOpenHelperを拡張するクラスを作成し、onCreateおよびonUpgradeをオーバーライドしてテーブルを作成します。

2)ContentProviderを拡張するクラスを作成し、データベースにアクセスするためのURIを作成します。 http://developer.Android.com/guide/topics/providers/content-providers.html を参照してください。 URIMatcheronCreate、クエリなど(オーバーライドされたメソッド)で使用するonUpdateにURIを追加して、URIに一致させます。参照 http://developer.Android.com/reference/Android/content/UriMatcher.html

3)insertメソッドでgetContext().getContentResolver().notifyChange(uri, null)を呼び出します。クエリメソッドでsetNotificationUri(ContentResolver cr, Uri uri)を呼び出してから、挿入の変更がコンテンツプロバイダーに戻り、ローダーに自動的に反映されるようにします。 ( https://stackoverflow.com/a/7915117/936414 )。

4)onCreateLoaderでそのURIを指定します。

注:コンテンツプロバイダーがない場合、現在のAndroidバージョン。現在のバージョンでは、リストへの変更の自動更新は実行できません。コンテンツプロバイダーを表示したくない場合は、マニフェストでエクスポートされた属性を設定または、 https://stackoverflow.com/a/7422343/936414 のようにカスタムCursorLoaderを実装して、データベースからデータを取得できますが、この場合、データの自動更新はできません。

35
user936414

Androidガイドでは、他のアプリケーションとデータを共有する場合は、ContentProviderを作成することをお勧めします。これが必要ない場合は、CursorLoaderクラスのメソッドloadInBackgroud()をオーバーライドできます。たとえば、onCreateLoaderに次のように記述します。

return new CursorLoader( YourContext, null, YourProjection, YourSelection, YourSelectionArgs, YourOrder )
           {
               @Override
               public Cursor loadInBackground()
               {
                   // You better know how to get your database.
                   SQLiteDatabase DB = getReadableDatabase();
                   // You can use any query that returns a cursor.
                   return DB.query( YourTableName, getProjection(), getSelection(), getSelectionArgs(), null, null, getSortOrder(), null );
               }
           };
64
wholeman