SQLite
 sql >> Base de données >  >> RDS >> SQLite

Comment remplir ListView avec db dans le dossier d'actifs ?

D'abord quelques points à noter.

  • 1 - vous avez dit que le fichier est FoodDB.db mais ensuite dit que la base de données s'appelle foodDatabase.db . Le nom de la base de données est le nom du fichier. En tant que tel, l'exemple suivant utilise FoodDB.db comme le fichier qui se trouve dans les actifs (vous pouvez renommer le fichier lors de la copie à partir des actifs, mais je ne l'ai pas fait dans cette réponse.)

  • 2 - Vous n'avez pas besoin d'un assistant de base de données et l'exemple n'en utilise pas.

Il y a deux parties :-

  • 1) Accéder à la base de données pour extraire les données pour le ListView. Dans l'exemple suivant, ceci est copié des actifs vers l'emplacement de la base de données standard (/data/data/the_package/databases/the_database_name ).

    • L'hypothèse a été faite qu'une fois copiée à partir des ressources, la base de données sera ensuite utilisée (c'est-à-dire qu'elle est copiée une fois pendant toute la durée de vie de l'application).
  • 2) Affichage des données extraites (obtenues en tant que Cursor) dans une ListView.

Pour faire 2, vous aurez besoin que la mise en page inclue une ListView, en tant que telle, la mise en page suivante a été utilisée. activity_main.xml :-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="fooddb.so49328656populatelistview.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        />
    <ListView
        android:id="@+id/foodlist"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>
  • Remarque tools:context="fooddb.so49328656populatelistview.MainActivity" devra refléter VOTRE package

L'assistant de base de données - Non utilisé comme averti

L'activité appelante MainActivity.java (voir notes) :-

public class MainActivity extends AppCompatActivity {

    static final String DBNAME = "FoodDB.db";
    static final String DBASSETPATH = "databases/" + DBNAME;
    static final String FOODTABLE = "dataset";
    static final String FOODCOLUMN = "Food";
    static final String IDCOLUMN = "ID";

    ListView mFoodList;
    SQLiteDatabase mDB;
    SimpleCursorAdapter mSCA;
    Cursor mCsr;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mFoodList = (ListView) this.findViewById(R.id.foodlist);
        mDB = openFoodDB();
        if (mDB != null) {
            mCsr = mDB.query(FOODTABLE,
                    new String[]{IDCOLUMN + " AS _id",
                            FOODCOLUMN
                    },
                    null,null,null,null,null);
            mSCA = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_1,mCsr,
                    new String[]{FOODCOLUMN},
                    new int[]{android.R.id.text1},0);
            mFoodList.setAdapter(mSCA);
        } else {
            Toast.makeText(this,"Unable to open Database.",Toast.LENGTH_LONG);
        }
    }

    private SQLiteDatabase openFoodDB() {
        String dbpath = this.getDatabasePath(DBNAME).getPath();
        if (this.getDatabasePath(DBNAME).exists()) {
            Log.d("OPENFOODDB","Opening already existing Database");
            return SQLiteDatabase.openDatabase(dbpath,null,SQLiteDatabase.OPEN_READWRITE);
        }
        InputStream is;
        byte[] buffer;
        FileOutputStream db;
        try {
             is =  this.getAssets().open(DBASSETPATH);
             buffer = new byte[is.available()];
             is.read(buffer);
             is.close();
        } catch (Exception e) {
            e.printStackTrace();
            Log.d("OPENFOODDB","Unable to locate or buffer input from assets " + DBASSETPATH);
            return null;
        }
        // Just in case the databases directory doesn't exist create it.
        File dbmkdir = (this.getDatabasePath(DBNAME)).getParentFile();
        dbmkdir.mkdirs();
        try {
            db = new FileOutputStream(this.getDatabasePath(DBNAME).getPath());
        } catch (Exception e) {
            e.printStackTrace();
            Log.d("OPENFOODDB","Unable to create outputstream for DB at path " + dbpath);
            try {
                is.close();
            } catch (Exception e2) {
            }
            return null;
        }
        try {
            db.write(buffer);
            db.flush();
            db.close();
            is.close();
        } catch (Exception e) {
            Log.d("OPENFOODDB","Failed to copy asset to DB");
            e.printStackTrace();
            return null;
        }
        return SQLiteDatabase.openDatabase(dbpath,null,SQLiteDatabase.OPEN_READWRITE);
    }
}

Remarques

  • le openFoodDB La méthode renvoie la base de données SQLiteDatabase après l'avoir copiée à partir du fichier d'actifs si la base de données n'existe pas. La méthode retournera null s'il y avait des problèmes.

    • si la base de données existe, le journal contiendra un message du type D/OPENFOODDB: Opening already existing Database
    • il n'y aura pas de messages de journal si la base de données a été copiée à partir du fichier d'actifs et ouverte avec succès. Les messages ne seront consignés qu'en cas de problème.
    • si, par exemple, le fichier d'actifs est manquant, vous obtiendrez un message dans le journal comme D/OPENFOODDB: Unable to locate or buffer input from assets databases/FoodDB.db ceci serait précédé d'une trace de pile

par exemple. :-

03-16 22:17:04.008 1529-1529/? W/System.err: java.io.FileNotFoundException: databases/FoodDB.db
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.content.res.AssetManager.openAsset(Native Method)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:315)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:289)
03-16 22:17:04.008 1529-1529/? W/System.err:     at fooddb.so49328656populatelistview.MainActivity.openFoodDB(MainActivity.java:63)
03-16 22:17:04.008 1529-1529/? W/System.err:     at fooddb.so49328656populatelistview.MainActivity.onCreate(MainActivity.java:37)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.app.Activity.performCreate(Activity.java:5008)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.app.ActivityThread.access$600(ActivityThread.java:130)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.os.Looper.loop(Looper.java:137)
03-16 22:17:04.008 1529-1529/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:4745)
03-16 22:17:04.008 1529-1529/? W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
03-16 22:17:04.008 1529-1529/? W/System.err:     at java.lang.reflect.Method.invoke(Method.java:511)
03-16 22:17:04.008 1529-1529/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-16 22:17:04.008 1529-1529/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-16 22:17:04.008 1529-1529/? W/System.err:     at dalvik.system.NativeStart.main(Native Method)
  • Un CursorAdapter nécessite une colonne spécifiquement nommée _id d'où l'utilisation de IDCOLUMN + " AS _id" .

Le résultat :-