web-dev-qa-db-fra.com

Comment lire une base de données SQLite en Android avec un chargeur de curseur?

Je configure mon application pour que les gens puissent créer des groupes de leurs amis. Lorsqu'un groupe est créé, il écrit 2 tables dans la base de données SQL. La première table a un nom de groupe et un identifiant de groupe. La deuxième table a 2 colonnes, un identifiant de groupe et un identifiant d'utilisateur. Cela fonctionne bien.

Cependant, maintenant je veux pouvoir lire à partir de la base de données. J'utilise un fragment listview avec un cursorloader mais j'ai du mal à obtenir les informations à afficher. Je veux répertorier tous les noms de groupe de la première table dans ma vue de liste.

Mon problème est que, lorsque j'ai utilisé pour la première fois le cursorloader pour répertorier mes contacts, j'utilisais un Uri du content provider Dans la méthode onCreateLoader. Plus précisément, j'avais CONTENT_URI De la classe ContactsContracts.Contacts.

Exemple de cursorloader avec 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);
}

Cependant, sans utiliser de fournisseur de contenu, je ne sais pas quoi mettre dans la méthode onCreateLoader car return new CursorLoader(...) nécessite un Uri dans le deuxième argument.

Une suggestion sur la façon dont je pourrais afficher mes données de base de données dans une vue de liste?

code de classe de fragment:

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

Ce sont les étapes pour créer un chargeur de curseur dans un fragment de liste

1) Créez une classe étendant SQLiteOpenHelper et redéfinissez onCreate et onUpgrade pour créer vos tables.

2) Créez une classe étendant ContentProvider et créez les URI pour accéder à votre base de données. Reportez-vous http://developer.Android.com/guide/topics/providers/content-providers.html . Ajoutez vos URI à URIMatcher que vous utilisez dans onCreate, onUpdate, requête, etc. (méthodes substituées) pour correspondre à l'URI. Reportez-vous http://developer.Android.com/reference/Android/content/UriMatcher.html

3) Dans la méthode d'insertion, appelez getContext().getContentResolver().notifyChange(uri, null). Dans la méthode de requête, appelez setNotificationUri(ContentResolver cr, Uri uri) avant de renvoyer le fournisseur de contenu pour que la modification d'insertion se répercute automatiquement sur votre chargeur. ( https://stackoverflow.com/a/7915117/936414 ).

4) Donnez cet URI dans onCreateLoader.

Remarque: Sans fournisseur de contenu, l'actualisation automatique des modifications apportées à la liste n'est pas possible à partir de la version actuelle Android. Si vous ne souhaitez pas que votre fournisseur de contenu soit visible, définissez l'attribut exporté dans le manifeste à false. Ou vous pouvez implémenter votre CursorLoader personnalisé comme dans https://stackoverflow.com/a/7422343/936414 pour récupérer les données de la base de données. Mais dans ce cas, l'actualisation automatique des données n'est pas possible

35
user936414

Le Guide Android suggère de créer un ContentProvider lorsque vous souhaitez partager vos données avec d'autres applications. Si vous n'en avez pas besoin, vous pouvez simplement remplacer la méthode loadInBackgroud() de la classe CursorLoader. Par exemple, écrivez comme ceci dans votre 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