IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

SQLite et apk


Sujet :

Android

  1. #1
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    154
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 154
    Par défaut SQLite et apk
    Bonjour à tous,

    J'ai une application avec une base de données sqlite que je souhaite mettre en ligne.
    Dans ma classe pour créer ma base de données, j'ai créer la base, 3 tables et toutes les méthodes.
    Or mon applications comporte 10 tables et j'ai crée les 7 autres tables via un autre moyen (sqlitemanager via firefox).

    Je me pose quelques questions :
    - faut-il que toutes les tables soient déclarées dans la classe de mon app ?
    - si j'ai importé la base de données complète (créée via sqlite manager) via ddms dans data/data/monapp.fr/databases, lorsque j'exporte mon app, prendra-t-elle en compte la base que j'ai importé ou uniquement celle qui est notée dans mon activité ?

    Autre question, j'ai créé une seconde base de données par erreur. Comment faire pour l'effacer ?

    Merci.

  2. #2
    Membre éprouvé Avatar de linked
    Profil pro
    Développeur Android
    Inscrit en
    Mai 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Android

    Informations forums :
    Inscription : Mai 2008
    Messages : 88
    Par défaut
    Bonjour,

    Un peu difficile de suivre ton raisonnement mais pour répondre à tes questions:

    1.Tu déclare les tables que tu veut dans ton application/classe du moment que tu travaille avec. Si tu n'en as pas besoin, tu n'a pas besoin de les déclarer mais je vois pas bien l'utilité qu'elles ont alors.

    2.Non, lorsque tu exporte ton application pour la publier, la base dans /data/data/.... ne sera pas exporté. Soit tu la met dans assets et tu la copie à la main au lancement, soit tu passe tout sur ton serveur et tu récupère tout au lancement (chose que je fait).

    Pour effacer, soit par eclipse, soit par java avec file.delete().

  3. #3
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    154
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 154
    Par défaut
    Citation Envoyé par linked Voir le message
    Un peu difficile de suivre ton raisonnement mais pour répondre à tes questions:

    1.Tu déclare les tables que tu veut dans ton application/classe du moment que tu travaille avec. Si tu n'en as pas besoin, tu n'a pas besoin de les déclarer mais je vois pas bien l'utilité qu'elles ont alors.
    En fait je déclare dans mon activity DataBase les 10 tables en faisant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    private static final String TABLE_UNE = "table_une";
    private static final String COL_ID = "_id";
    private static final int NUM_COL_ID = 0;
    etc etc jusqu'à TABLE_DIX
    Par contre elles ne sont pas toutes déclarées dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    private static final String CREATE_BDD  = "CREATE TABLE " + TABLE_UNE + " (" + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
    + COL_ID_ID + " INTEGER, " + COL_TEXTE + " LONG TEXT NOT NULL, "
    + COL_TITRE + " TEXT NOT NULL);"
    Citation Envoyé par linked Voir le message

    2.Non, lorsque tu exporte ton application pour la publier, la base dans /data/data/.... ne sera pas exporté. Soit tu la met dans assets et tu la copie à la main au lancement, soit tu passe tout sur ton serveur et tu récupère tout au lancement (chose que je fait).
    Pour effacer, soit par eclipse, soit par java avec file.delete().
    Ah ! merci de l'info.
    Pour récupérer via serveur, je dois faire en sorte que l'app se connecte au serveur à chaque fois qu'elle se lance ?

    Je vais regarder comment faire pour la solution assets.

    Si je comprends bien je dois ajouter quelque chose de ce style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    private boolean checkDataBase(){
       SQLiteDatabase checkDB = null;
        try{
               String myPath = DB_PATH + DB_NAME;
               checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
        }catch(SQLiteException e){
                //database does't exist yet.
        }
        if(checkDB != null){
                checkDB.close();
        }
        return checkDB != null ? true : false;
    }
    Du coup, une chose m'ennuie.
    J'ai crée une activity pour mettre à jour la base de données.
    Cette activité dispose d'un bouton, et lorsqu'on clique dessus, on télécharge mon database.db et il s'insère dans mon data/data.
    Ça n'est pas du tout la bonne solution en fait.

    Merci beaucoup

  4. #4
    Membre éprouvé Avatar de linked
    Profil pro
    Développeur Android
    Inscrit en
    Mai 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Android

    Informations forums :
    Inscription : Mai 2008
    Messages : 88
    Par défaut
    Si tu copie ton database.db, tu n'a pas besoin de créer les tables avec des lignes de code puisque ça va écraser ta base existante.

    C'est seulement si tu veut mettre à jour ta base avec des tables qui n'existent pas ou pour être sure qu'elles existent que tu lance "CREATE TABLE". Perso j'utilise "CREATE TABLE IF NOT EXISTS" au lancement de l'application et ensuite je les met à jour avec mon serveur.

    A toi de voir quel est le meilleur moment pour se connecter au serveur. J'ai un code spécial pour compter le nombres de lignes dans la base et ensuite l'application décide si il y a mise à jour ou pas.

    Ca peut aussi bien être un fichier .txt avec la version de la base que ton application va regarder.

    Le code checkDataBase() peut être un début, pour la copie depuis assets j'ai mis un code dans ce post:

    http://www.developpez.net/forums/d12...tante-eclipse/

  5. #5
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    154
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 154
    Par défaut
    merci beaucoup linked, t'es trop fort

    je vais regarder cela de suite.
    je suis également tombé sur ce lien (que je partage au cas où) http://blog.matt-technology.com/inde...e-sous-android

  6. #6
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    154
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 154
    Par défaut
    Si je comprends la manip, je dois créer une nouvelle base vide, mettre la base remplie dans assets et dans ma classe qui gère la base de données créer la base vide et faire une copie par bytes de notre fichier vers la base vierge pour l'écraser.

    J'ai tenté d'ajouter:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    	public void createDataBase() throws IOException {
    		this.getReadableDatabase();
    		try {
    			copyDataBase();
    		}catch (IOException e) {
                throw new Error("Erreur de copie de la base !");
            }
    	}
     
     
        public void copyDataBase() throws IOException{
     
        	// crée le repertoire
    	File f=new File(DB_PATH);
    	f.mkdirs(); 
        	//Open your local db as the input stream
        	InputStream myInput = myContext.getAssets().open(NOM_BDD);
        	// Path to the just created empty db
        	String outFileName = DB_PATH + NOM_BDD;
        	//Open the empty db as the output stream
        	OutputStream myOutput = new FileOutputStream(outFileName);
        	//transfer bytes from the inputfile to the outputfile
        	byte[] buffer = new byte[1024];
        	int length;
        	while ((length = myInput.read(buffer))>0){
        		myOutput.write(buffer, 0, length);
        	}
        	//Close the streams
        	myOutput.flush();
        	myOutput.close();
        	myInput.close();
        }
    et de supprimer ce qu'il y avait dans le onCreate et onUpgrade mais j'ai une erreur dans l'émulateur (et dans le device).
    Le LogCat me donne une erreur sqliteexception car l'app ne trouve pas ma table.

  7. #7
    Membre éprouvé Avatar de linked
    Profil pro
    Développeur Android
    Inscrit en
    Mai 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Android

    Informations forums :
    Inscription : Mai 2008
    Messages : 88
    Par défaut
    Ben, si tu copie la base depuis assets, tu n'a pas besoin d'en créer une vide avant.
    L'exception qui te dit que la table n'est pas trouvé, elle viens d'un autre bout de code non ?

    Tu voulais mettre à jour la base depuis internet si j'ai compris, ça doit être à ce moment qu'il ne trouve pas la table car elle n'est pas dans la base que tu copie depuis assets.

    Soit tu met toutes les tables(même vides) dans la base qui est dans assets, soit tu met une base avec une partie des tables dans assets et tu crée les tables quand tu les récupères depuis ton serveur pour les ajouter à ta base que tu viens de copier dans /data/data...

    Si j'ai mal compris, essaye de m'expliquer étapes par étapes ce que tu fais et à quel moment tu a l'erreur.

    Genre:
    1.copie depuis assets
    2.récupération depuis serveur
    3.erreur

    Sinon regarde le logcat un peu mieux, il te donne sûrement la ligne ou se trouve l'erreur.
    Des fois c'est tout con, un truc qu'on a oublié.

  8. #8
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    154
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 154
    Par défaut
    merci encore linked pour tes conseils et ton aide.

    Je n'ai malheureusement pas encore réussi
    Bon en fait je viens de regarder en détails, calmement et méthodiquement mon soucis et voici la source de mon problème :

    1. j'ai crée la base de données et quelques tables avec ma classe database.
    2. j'ai découvert SQLiteManger et pour aller plus vite, j'ai crée la totalité des tables et les contenus avec. Cela me donne un fichier bdd.db.

    Lorsque je copie ce fichier (bdd.db) dans data/data/machintruc/databases via le ddms et que je teste mon application via l'émulateur, aucun soucis, mes activités s'affichent bien et le contenu qui va avec aussi.

    Par contre si j'efface le fichier bdd.db de data/data/.... et que je le mets dans mon dossier assets et que j'ajoute le code createDataBase() suivant, (encore merci linked)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    private static final int VERSION_BDD = 1;
    private static final String NOM_BDD = "bdd.db";
     
    private static String DB_PATH = "/data/data/monpackageadequate/databases/";
     
        private final Context myContext;
        private SQLiteDatabase myDataBase;
     
    public MaDataBase(Context context) {
    	super(context, NOM_BDD, null, VERSION_BDD);
    	this.myContext = context;
    }
     
    public MaDataBase(Context context, String name, CursorFactory factory, int version) {
    	super(context, name, factory, version);
    	this.myContext = context;
    }
     
        public void createDataBase() throws IOException{
        File f=new File(DB_PATH);
        f.mkdirs(); 
        InputStream assetsDB = myContext.getAssets().open(NOM_BDD);
        String outFileName = DB_PATH + NOM_BDD;
        OutputStream myOutput = new FileOutputStream(outFileName);
     
            byte[] buffer = new byte[1024];
            int length;
            while ((length = assetsDB.read(buffer))>0){
            	myOutput.write(buffer, 0, length);
            }
            myOutput.flush();
            myOutput.close();
            assetsDB.close();
        }
    l'application ne fonctionne plus. J'obtiens une belle erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Caused by: android.database.sqlite.SQLiteException: no such table: table_une: , while compiling: SELECT _id, Titre, TEXTE FROM table_une
    Je vérifie dans le DDMS et je m'aperçois que le fichier bdd.db a bien été copié dans data/data/....
    Par contre je remarque que son poids est plus léger !
    Je le récupère via le ddms et l'enregistre sur mon disque dur et je m'aperçois que la base est vide, il ne reste qu'une seule table (android_metadata). En fait une base est crée mais vide

    Pour en être convaincu, j'ai effacé le fichier bdd.db qui est dans data/data/.... via le DDMS et j'ai effacé celui qui est dans assets et j'ai exactement la même erreur. Je retrouve un fichier bdd.bd dans data/data/.... via DDMS mais vide !

    La seule ligne modifiée dans le code de linked est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        InputStream assetsDB = this.getAssets().open(NOM_BDD);
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        InputStream assetsDB = myContext.getAssets().open(NOM_BDD);
    Sinon j'avais une erreur sur this.

  9. #9
    Membre éprouvé Avatar de linked
    Profil pro
    Développeur Android
    Inscrit en
    Mai 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Android

    Informations forums :
    Inscription : Mai 2008
    Messages : 88
    Par défaut
    Peut être un problème de context. Déjà il est déclaré comme final, je pense pas que ce soit une bonne chose.

    Ensuite, supprime le "throws IOException" et envoie directement le context comma ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public void createDataBase(Context context) {
    Eclipse te proposera de mettre un try/catch à la place du throw et tu pourra mettre un log.d dans le catch. Comme ça il te donnera l'ereur.

    Pour appeler la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    createDataBase(tonactivity.this);

  10. #10
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    154
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 154
    Par défaut
    YeeeEEEeaaaHHH samarche
    meeeerci beaucoup linked

    je vais bien étudier le code pour le comprendre parfaitement.

  11. #11
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    154
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 154
    Par défaut
    comme toujours, une fois que j'ai réussi une étape, je me pose des questions sur l'étape suivante ...

    pour le moment ma base de données est donc stockée dans le dossier assets.

    par contre cette base de données est vouée à être mise à jour avec des données supplémentaires. J'ai crée une activité Update qui permet de télécharger via internet le fichier bdd.db.

    Est-ce une bonne solution ?
    Si oui faut-il enregistrer le fichier dans assets ou dans data/data... ?

  12. #12
    Membre éprouvé Avatar de linked
    Profil pro
    Développeur Android
    Inscrit en
    Mai 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Android

    Informations forums :
    Inscription : Mai 2008
    Messages : 88
    Par défaut
    Si la base ne contient que des données que tu met TOI, pas de problème. Mais pourquoi ne pas directement passer par la méthode Update si elle est utilisé par la suite ?

    En récupérant la base depuis internet, c'est mieux de la mettre directement dans /data... sinon il faudrait la recopier. Ca prend du temps et ça bouffe la batterie pour rien.

    A toi de voir si il faut re télécharger toute la base ou juste une table suivant tes besoins.

  13. #13
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    154
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 154
    Par défaut
    merci encore linked pour toutes tes explications. Je comprends mieux comment fonctionne le couple android/sqlite mais il reste quelques zones de mystère dans ma tête.

    J'ai pour le moment une bdd (bdd.db) dans assets qui est copiée dans data/data/... lors de l'ouverture de l'application. Mais si je souhaite mettre à jour la bdd (toute la bdd) comment faire ?

    J'ai trouvé une solution en créant une petite activité avec un bouton "mettre à jour les données" et lors d'un clic sur ce bouton le fichier bdd.db est téléchargé via internet et copié dans data/data/....
    Je viens de tester et cela fonctionne. Toute la base est mise à jour.

    Mais je ne comprends pas bien le cycle de vie de la base de données:
    Le fichier bdd.db qui est dans data/data/.... est "temporaire" ?
    Avec mon activité qui télécharge un nouveau fichier bdd.db dans data/data/..., cette nouvelle base de données reste persistante dans le tel de l'utilisateur ou alors on revient à l'ancienne si il éteint et rallume son tél ?
    En gros, quelles sont les best practices pour mettre à jour une base de données ?

    Je n'ai pas regardé ni utilisé la méthode UpDate (c'est pour une mise à jour automatique?) mais je vais regarder comment l'utiliser, merci.

    @linked: j'ai cliqué sur le lien de ta signature et regardé les apps, ce sont tes applications ? si oui, félicitations

  14. #14
    Membre confirmé
    Inscrit en
    Novembre 2010
    Messages
    154
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 154
    Par défaut
    Je viens de faire un test en éteignant et rallumant le tel et la nouvelle base de données est toujours présente.

  15. #15
    Membre éprouvé Avatar de linked
    Profil pro
    Développeur Android
    Inscrit en
    Mai 2008
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Android

    Informations forums :
    Inscription : Mai 2008
    Messages : 88
    Par défaut
    Oui ce qui est dans /data reste jusqu'à ce que l'utilisateur désinstalle ton application(ou peut être clear le cache mais j'ai un doute).

    Pour "Update" je pensais que c'était une de tes méthodes pour récupérer la base depuis internet

    Apparemment tu a déjà un bouton "mettre à jour les données", utilise le code de ce bouton pour mettre la base à jour soit:
    -en le proposant aux utilisateurs
    -mettre le bouton dans un menu
    -de façon automatique quand ....seul toi le sait

    Et oui, ce sont mes application, merci
    Malheureusement mon compte google à été bannie et toutes mes application retirées du market....

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. qui connait sqlite ?
    Par Emmanuel Lecoester dans le forum SQLite
    Réponses: 23
    Dernier message: 19/02/2010, 13h44
  2. SQLITE
    Par Betatesteur dans le forum SQLite
    Réponses: 2
    Dernier message: 24/06/2005, 12h41
  3. [SQLite]éliminer un motif dans des champ TEXT
    Par Invité(e) dans le forum Langage SQL
    Réponses: 2
    Dernier message: 26/05/2005, 17h44
  4. base de données en sqlite
    Par Cyrillou dans le forum SQLite
    Réponses: 1
    Dernier message: 12/05/2005, 15h37
  5. debuter en SQLite
    Par venomelektro dans le forum SQLite
    Réponses: 4
    Dernier message: 08/12/2004, 19h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo