2010-08-13 4 views
1

Une de mes applications télécharge une base de données à partir d'un serveur. Lorsque j'installe l'application sur mon téléphone, il télécharge le fichier correctement et charge l'information, aucune exception n'est levée ou quoi que ce soit.Base de données semble disparaître après le téléchargement de mon application. Des idées?

Toutefois, lorsque je télécharge l'apk sur l'Android Market Place et que je la télécharge sur le téléphone, l'application télécharge la base de données et se bloque, indiquant que le gestionnaire sqlite n'a pas pu ouvrir la base de données.

est ici la progression du code:

Dans le SQLiteOpenHelper:

this.FULL_DB_PATH = new String(this.getWritableDatabase().getPath()); 
this.getWritableDatabase(); 

// Code for retrieving the database off of the server: 

private void copyDataBase(){ 
     InputStream myInput=null; 
     OutputStream myOutput=null; 
     try{ 
      // opening connections 
      URL url = new URL("server_url_here"); 
      URLConnection ucon=url.openConnection(); 
      myInput = ucon.getInputStream();  
      myOutput = new FileOutputStream(this.FULL_DB_PATH); 

      // write to the db here 
      byte[] buffer = new byte[1024*1024]; 
      int length; 
      while ((length = myInput.read(buffer))>0){ 
       myOutput.write(buffer, 0, length); 
      } 

      myOutput.flush(); 
      myOutput.close(); 
      myInput.close(); 
     } 
     catch(Exception e) 
     { 

       try{ 
        myOutput.flush(); 
        myOutput.close(); 
        myInput.close(); 
       } 
       catch(Exception es){} 
     } 
    } 

Je ne sais pas pourquoi mon collègue sauve la db avec une extension mp3, mais ... cela fonctionne quand nous re installer l'apk ad-hoc.

Pour:

myOutput = new FileOutputStream(this.FULL_DB_PATH); 

J'ai aussi essayé:

myOutput = this.getApplicationContext().openFileOutput(this.FULL_DB_PATH, Context.MODE_WORLD_READABLE); 

Mais cela ne fonctionne pas non plus.

Toute aide est grandement appréciée !! Je me suis arraché les cheveux pendant quelques heures et je veux juste que ça finisse haha.

Répondre

1

Ce que vous faites est de copier le fichier dans le dossier/data dans le système de fichiers android. Sur un téléphone normal avec des autorisations normales, ceci n'est pas autorisé pour des raisons de sécurité. Vous pouvez le faire sur l'émulateur et les téléphones enracinés parce que vous avez reçu l'autorisation d'écrire dans/data (normalement seulement lu).

Pour contourner cela, vous devrez ajouter manuellement les informations à la base de données en utilisant db.insert(String, String, ContentValues) et db.update(String, ContentValues, String, String[])

Il serait agréable de pouvoir faire ce que vous essayez, mais pour des raisons de sécurité, il est une très bonne chose que vous ne peut pas.

+0

Mais qu'en est-il de l'emballage de l'application avec une base de données pré-construite? J'ai une énorme quantité de données et l'insertion manuelle de toutes les données rendrait l'application inutilisable du point de vue de l'utilisateur. –

+0

Vous avez vraiment 2 options. Si vous pouvez le fournir au format XML, vous pouvez l'ajouter au dossier res/xml de votre projet et y accéder à partir de là. Je peux fournir le code dans une autre réponse si c'est l'option que vous recherchez. L'autre ouverture consiste à télécharger un fichier à partir du serveur lors de la première exécution, puis à parcourir le fichier en ajoutant chaque ligne. Cela pourrait être en XML ou JSON, ou autre chose comme ça. Généralement l'avoir comme XML est la manière recommandée de le faire, mais cela fonctionnera. – matto1990

+0

ajoutant le db pré-construit directement dans le dossier res de l'éclipse ne le fera pas? Je suis confus ... surtout parce que dans la version d'origine que j'avais, j'avais le db inclus dans le dossier res pour le projet mais l'apk lui-même n'a jamais fini de télécharger. –

1

L'émulateur vous donne un accès spécial que les vrais téléphones n'ont pas. En d'autres termes, je suppose que vous copiez directement le fichier dans le répertoire des bases de données sur le téléphone? Si c'est le cas, vous ne pouvez pas le faire sur un téléphone non rooté. J'espère que quelqu'un va carillon et me prouver le contraire parce que c'est un problème pour moi aussi. Je voudrais télécharger facilement un fichier DB et l'installer. Ce que je finis par faire est de créer une nouvelle base de données et de charger le schéma et les données via des requêtes.

EDIT: Je voudrais partager un tour avec vous. C'est vraiment simple. Au lieu d'utiliser seulement db.insert/db.update/par eux-mêmes, les étendre dans les transactions. En fait, j'utiliserais toute la construction DB comme une transaction, ou au moins juste des tables individuelles. J'ai constaté une augmentation de 10 à 50 fois de la vitesse des transactions lorsqu'elles ont été ciblées et ensuite toutes engagées en même temps.

+0

Avez-vous essayé d'empaqueter la base de données avec l'ensemble de l'application et de la télécharger? Quand j'ai essayé cela, mon application était d'environ 40 Mo quelque chose, mais il ne serait pas télécharger dans le magasin ... –

+0

Woah c'est une grosse DB. Je considérerais garder votre DB sur le côté de serveur. Disposez également d'une base de données sur le téléphone local, mais autorisez le téléphone à télécharger uniquement les "éléments dont il a besoin" "selon les besoins". Ainsi, la base de données locale est un cache de seulement les parties de la base de données de 40 Mo qui sont pertinentes pour l'abonné donné. 40Mo est assez grand, bien que je sois sûr que tout cela est importand –

0

Les deux autres réponses sont incorrectes, je crois. J'ai un système de sauvegarde dans mon application où les sauvegardes sont copiées sur la carte SD, puis copiés dans le dossier/data/lorsque la sauvegarde est restaurée.Bien que je ne sais pas pourquoi votre travail de coutume de code, voici mon code pour copier la base de données de la carte SD:

final InputStream in = new FileInputStream(from); 
final OutputStream out = new FileOutputStream(to); 
final byte[] buf = new byte[1024]; 
int len; 
while ((len = in.read(buf)) > 0){ 
    out.write(buf, 0, len); 
} 
in.close(); 
out.close(); 

Juste pour plus investigare l'erreur, essayez de télécharger sur la carte SD au lieu et utilisez mon code pour le copier dans le dossier de données. L'objet "to" dans mon code se présente comme suit:

public static final String DATABASE_PATH = "/data/data/"+SomeClass.class.getPackage().getName()+"/databases/"+ DATABASE_NAME; 
final File to = new File(Constant.DATABASE_PATH); 
Questions connexes