Design-Frage: Vordefinierte Elemente in App bringen

  • Antworten:9
Gelöschter Account
  • Forum-Beiträge: 2.492

29.08.2015, 18:54:30 via Website

Hallo,

ich habe mehrere, bestimmt 100, vordefinierte Elemente und die Anzahl soll mit der Zeit auch wachsen.
Ein Element besteht aus einer Bezeichnung (String), einer Beschreibung (String), einer Kategorie (int), einem boolean und evtl noch weiteren Feldern.
Zum Beispiel:
Fußball | Fußball ist eine Ballsportart... | Sport | false

Diese Elemente sollen nachträglich in der App auch noch veränderbar sein.
Wie kann ich diese Elemente jetzt schon bei der App Installation zur Verfügung haben (online Kommunikation ausgeschlossen).

Ich habe folgende Ideen:
- Ein Array/eine Liste von Elementen (Klasse "Element" erstellen mit den oben genannten Attributen)
- 4 (oder mehr) Arrays/Listen für jedes Attribut ein Array/Liste
- eine vorher erstellte und ausgefüllte Datenbank (bereits versucht jedoch fehlgeschlagen)
- Datenbank bei Erstausführung erstellen

Was ist der beste Weg? Habt ihr besser Ideen? Wie kann ich das Vorhaben am besten umsetzen?

Antworten
Gelöschter Account
  • Forum-Beiträge: 438

29.08.2015, 22:20:20 via Website

Da über Handy getippt nur eine kurze Antwort: Bei Installation erstellte bzw. angepasste Datenbank. Meiner Erinnerung mach müsste eine Ableitung von Sqlitehelper oder so ähnlich das Richtige sein - aber vielleicht kann jemand mit IDE Zugriff etwas besser antworten...

Aktuelles Entwicklungsprojekt: (thinking) Sudoku Dojo Free (lightbulb)
Ich freue mich über Tester/innen.

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

29.08.2015, 23:08:47 via App

Also ich würde da auf jeden Fall eine DB nehmen. Da geht auch schon eine Vorausgefüllte, welche dann halt entsprechend kopiert werden muss.über den DatabaseHalper oä.)
Dann kann der User der App auch nachträglich Daten ändern.
Wenn du dir dann noch vorbehalten willst selber einträge per App update hinzuzufügen wird es komplizierter denn dann brauchst du zusätzlich zum kopieren der DB auch noch einen Sync der die neuen Daten übernimmt, damit die Daten die der User evntl. geändert hat nicht gelöscht werden.

Das mit dem kopieren und eine vorhandene DB nutzen hab ich schonmal genacht, nur gerade den Code nicht zur Hand. Kann ihn aber heraussuchen falls es dich Interessiert.

LG

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Gelöschter Account
  • Forum-Beiträge: 2.492

29.08.2015, 23:55:01 via App

Okay dann werde ich wohl eine DB nehmen.
Ja Pascal das wäre nicht schlecht ich habe es nämlich schon versucht aber nicht hinbekommen.
Habe eine Datenbank erstellt mit der Endung .db hab sie dann in den neu erstellten assets Ordner kopiert und dann mit Hilfe etlicher verschiedener Anleitungen versucht in den App databases Ordner zu kopieren wobei jedes mal der Fehler kam, dass die Datenbank nicht gefunden werden konnte.

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

31.08.2015, 22:24:06 via Website

So hier mal meine Sqlite Klasse die aus den Assets die DB nimmt und in den internene speicher kopiert.
Der Update Teil und der Abgleich mit der bestehenden Tabelle fehlt hier, da ich die DB aus der App über eine Webschnittstelle zusätzlich aktualisieren kann. Das ganze ist also nur für den ersten Start erstellt, damit die DB dda nicht komplett leer ist.
(Zudem habe ich die DB mit dem Tool SqLiteDAtaBaseBrowser erstellt)

public class DataBaseHelper extends SQLiteOpenHelper {
    private Context mycontext;

    private String DB_PATH;
    private static String DB_NAME = "deineDB.db";//the extension may be .sqlite or .db
    public SQLiteDatabase myDataBase;

  private static DataBaseHelper  _instance;
    /**
     * Prüft auf schon existierende Instanz (Singleton variante, bei mehrerend DBs bitte weglassen)
     * @param ctx
     * @return
     */
    public static DataBaseHelper getInstance(Context ctx)
    {
        if(_instance != null) return _instance;

        return new DataBaseHelper(ctx);
    }

    /**
     * Erstellt eine neue Instanz und wenn DB nicht existiert, wird eine aus den Assets kopiert
     * @param context 
     */
    public DataBaseHelper(Context context)  {
           super(context,DB_NAME,null,1);//Wobei die 1 hier für den Versionscode steht, welchen man bei einem Update erhähen kann (musst du halt dann anpassen)


           this.mycontext=context;
        DB_PATH = "/data/data/"+ mycontext.getPackageName()+"/databases/";
     _instance = this;

        boolean dbexist = checkdatabase();
        if (dbexist) {
            //System.out.println("Database exists");
            opendatabase(); 
        } else {
            System.out.println("Database doesn't exist");
            try {
                createdatabase();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            opendatabase();
        }

    }
    /**
     * Datenbank erstellen
     * @throws IOException
     */
    public void createdatabase() throws IOException {
        boolean dbexist = checkdatabase();
        if(dbexist) {
            //System.out.println(" Database exists.");
        } else {
            this.getReadableDatabase();
            try {
                copydatabase();
            } catch(IOException e) {
                throw new Error("Error copying database" + e.toString());
            }
        }
    }   

    /**
     * Auf existierende Datenbank prüfen
     * @return
     */
    private boolean checkdatabase() {
        //SQLiteDatabase checkdb = null;
        boolean checkdb = false;
        try {
            String myPath = DB_PATH + DB_NAME;
            File dbfile = new File(myPath);
            //checkdb = SQLiteDatabase.openDatabase(myPath,null,SQLiteDatabase.OPEN_READWRITE);
            checkdb = dbfile.exists();

        } catch(SQLiteException e) {
            System.out.println("Database doesn't exist");
        }
        return checkdb;
    }

    /**
     * Datenbank aus den assets in den Internen Speicher Kopieren
     * @throws IOException
     */
    private void copydatabase() throws IOException {
        //Open your local db as the input stream
        InputStream myinput = mycontext.getAssets().open(DB_NAME);

        // Path to the just created empty db
        String outfilename = DB_PATH + DB_NAME;

        //Open the empty db as the output stream
        OutputStream myoutput = new FileOutputStream(outfilename);

        // transfer byte to inputfile to 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();
    }

    /** 
     * Öffnet die Datenbank
     * @throws SQLException
     */
     public void opendatabase() throws SQLException {
        //Open the database
        String mypath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READWRITE);
    }

    public synchronized void close() {
        if(myDataBase != null) {
            myDataBase.close();
        }
        super.close();
    }

    /**
     * Erstellt DB SQL abfrage fürs erstellen (nicht nötig wenn du eine existierende DB mit Daten kopierst)
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub 
        String query = "CREATE TABLE `test` ("+
        "`_id`  INTEGER,"+
        "`field1`   text,"+
        "`int1` int,"+
        "`title`    text,"+
        "`name` text,"+
        "`desc` text,"+
        "PRIMARY KEY(_id)"+
    ");";

         db.execSQL(query);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    //Udate Dinge hier rein. Wei man das dan allerding mit Versionscode o.ä. benutzt müsstest du nochmal nachlesen

    }

}

— geändert am 31.08.2015, 22:24:31

LG Pascal //It's not a bug, it's a feature. :) ;)

Gelöschter Account

Antworten
Gelöschter Account
  • Forum-Beiträge: 2.492

30.09.2015, 13:28:45 via Website

Hi, danke für den Code, bin leider jetzt erst dazu gekommen, es auszuprobieren und es scheint gut zu funktionieren. Zumindest kann ich den ersten Datensatz auslesen. Ich kann zwar SQL - Befehle, aber mit diesem .query() komm ich noch nicht so ganz klar, aber das krieg ich bestimmt auch noch hin.

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

30.09.2015, 15:09:55 via App

Ja daran musste ich mich auch erst gewöhnen. Du kannst aucht nativ SQL Statements ausführen mit Query ist es stilistisch aber besser ;)

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Sync
  • Forum-Beiträge: 9

12.10.2016, 18:38:57 via Website

Pascal P.

So hier mal meine Sqlite Klasse die aus den Assets die DB nimmt und in den internene speicher kopiert.
Der Update Teil und der Abgleich mit der bestehenden Tabelle fehlt hier, da ich die DB aus der App über eine Webschnittstelle zusätzlich aktualisieren kann. Das ganze ist also nur für den ersten Start erstellt, damit die DB dda nicht komplett leer ist.
(Zudem habe ich die DB mit dem Tool SqLiteDAtaBaseBrowser erstellt)

......

Hey vielen Dank dafür. Hast du auch den Teil womit man die DB über eine Webschnittstelle aktualisieren kann? Das würde mir sehr helfen:)

Antworten