Datenbank mit List View verbinden, aber wie ?

  • 35 Antworten
  • Letztes Antwortdatum
T

theboss22

Ambitioniertes Mitglied
0
Hey,
habe für meine App eine Datenbank erstellt und möchte die Daten aus der Datenbank nun in einer ListView (ähnlich wie diese hier: http://i.stack.imgur.com/OlaAl.png) ausgeben. Habe mir jetzt schon verschiedene Tutorials dazu angeguckt wie man eine List View erstellt und habe es auch schon geschafft diese so umzusetzen, das sie in meinem emulator funktionieren, jedoch habe ich noch keine Idee, wie ich die Verbindung zu meiner SQL-Datenbank realisieren kann. Vielen Dank für Hilfe im voraus! :)

Ps: wenn das von Relevanz ist kann ich auch gerne die Codes für die ListView posten :)

Meine Datenbank enthält folgende drei Activities:


DatabaseHandler:

Code:
package com.example.fotooh2;

import java.util.ArrayList;

import java.util.List;

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHandler extends SQLiteOpenHelper {

	// All Static variables

	// Database Version

	private static final int DATABASE_VERSION = 5;

	// Database Name

	private static final String DATABASE_NAME = "PositionManager";

	// Positions table name

	private static final String TABLE_POSITIONS = "positions";

	// Positions Table Columns names

	private static final String KEY_ID = "_id";

	private static final String KEY_NAME = "Name";

	private static final String KEY_KATEGORIE = "Kategorie";

	private static final String KEY_LAENGE = "Laenge";

	private static final String KEY_BREITE = "Breite";

	public DatabaseHandler(Context context) {

		super(context, DATABASE_NAME, null, DATABASE_VERSION);

	}

	// Creating Tables

	@Override
	public void onCreate(SQLiteDatabase db) {

		String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_POSITIONS + "("

		+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
				+ KEY_KATEGORIE + " TEXT," + KEY_LAENGE + " REAL," + KEY_BREITE
				+ " REAL" + ")";

		db.execSQL(CREATE_CONTACTS_TABLE);

	}

	// Upgrading database

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

		// Drop older table if existed

		db.execSQL("DROP TABLE IF EXISTS " + TABLE_POSITIONS);

		// Create tables again

		onCreate(db);

	}

	/**
	 * 
	 * All CRUD(Create, Read, Update, Delete) Operations
	 */

	// Adding new contact

	void addPosition(Position position) {

		SQLiteDatabase db = this.getWritableDatabase();

		ContentValues values = new ContentValues();

		values.put(KEY_NAME, position.getName()); // Name

		values.put(KEY_KATEGORIE, position.getKategorie()); // Kategorie

		values.put(KEY_LAENGE, position.getLaenge()); // Länge

		values.put(KEY_BREITE, position.getBreite()); // Breite

		// Inserting Row

		db.insert(TABLE_POSITIONS, null, values);

		db.close(); // Closing database connection

	}

	// Getting single position

	Position getPosition(int id) {

		SQLiteDatabase db = this.getReadableDatabase();

		Cursor cursor = db.query(TABLE_POSITIONS, new String[] { KEY_ID,

		KEY_NAME, KEY_KATEGORIE, KEY_LAENGE, KEY_BREITE }, KEY_ID + "=?",

		new String[] { String.valueOf(id) }, null, null, null, null);

		if (cursor != null)

			cursor.moveToFirst();

		Position position = new Position(Integer.parseInt(cursor.getString(0)),
				cursor.getString(1), cursor.getString(2), cursor.getFloat(3),
				cursor.getFloat(4));

		// return position

		return position;

	}

	// Getting All Positions

	public List<Position> getAllPositions() {

		List<Position> positionList = new ArrayList<Position>();

		// Select All Query

		String selectQuery = "SELECT  * FROM " + TABLE_POSITIONS;

		SQLiteDatabase db = this.getWritableDatabase();

		Cursor cursor = db.rawQuery(selectQuery, null);

		// looping through all rows and adding to list

		if (cursor.moveToFirst()) {

			do {

				Position position = new Position();

				position.setID(Integer.parseInt(cursor.getString(0)));

				position.setName(cursor.getString(1));

				position.setKategorie(cursor.getString(2));

				position.setLaenge(cursor.getFloat(3));

				position.setBreite(cursor.getFloat(4));

				// Adding position to list

				positionList.add(position);

			} while (cursor.moveToNext());

		}

		// return position list

		return positionList;

	}

	// Updating single position

	public int updatePosition(Position position) {

		SQLiteDatabase db = this.getWritableDatabase();

		ContentValues values = new ContentValues();

		values.put(KEY_NAME, position.getName());

		values.put(KEY_KATEGORIE, position.getKategorie());

		values.put(KEY_LAENGE, position.getLaenge());

		values.put(KEY_BREITE, position.getBreite());

		// updating row

		return db.update(TABLE_POSITIONS, values, KEY_ID + " = ?",

		new String[] { String.valueOf(position.getID()) });

	}

	// Deleting single position

	public void deletePosition(Position position) {

		SQLiteDatabase db = this.getWritableDatabase();

		db.delete(TABLE_POSITIONS, KEY_ID + " = ?",

		new String[] { String.valueOf(position.getID()) });

		db.close();

	}

	// Getting positions Count

	public int getPositionsCount() {

		String countQuery = "SELECT  * FROM " + TABLE_POSITIONS;

		SQLiteDatabase db = this.getReadableDatabase();

		Cursor cursor = db.rawQuery(countQuery, null);
		
		int resultCount = cursor.getCount();

		cursor.close();

		// return count

		return resultCount;

	}

	
	}


AndroidSQLLiteTutorialActivity:

Code:
package com.example.fotooh2;

import java.util.List;


import android.app.Activity;
import android.os.Bundle;
import android.util.Log;


public class AndroidSQLiteTutorialActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        DatabaseHandler db = new DatabaseHandler(this);
        
        /**
         * CRUD Operations
         * */
        // Inserting Positions
        Log.d("Insert: ", "Inserting ..");
        db.addPosition(new Position("Hobbersdorfer Felder", "Landschaft" , 53.94966, 10.70343));
        db.addPosition(new Position("Felder bei Pelzerhaken", "Landschaft", 54.10039, 10.83878));
        db.addPosition(new Position("Felder bei Neustadt", "Landschaft" , 54.10713, 10.84201));
        db.addPosition(new Position("Felder bei Gronenberg", "Landschaft" , 54.04454, 10.69646));
        db.addPosition(new Position("Felder bei Stolpe", "Landschaft" , 54.15785, 10.78290));
        db.addPosition(new Position("Felder bei Ruhleben", "Landschaft" , 54.11740, 10.88896));
        db.addPosition(new Position("Niendorfer Hafen: ", "Häfen" , 53.99321, 10.81323));
        db.addPosition(new Position("Neustädter Hafen: ", "Häfen" , 54.10509, 10.81117));
        
        
        // Reading all positions
        Log.d("Reading: ", "Reading all positions..");
        List<Position> positions = db.getAllPositions();       
 
        for (Position cn : positions) {
            String log = "Id: "+cn.getID()+" ,Name: " + cn.getName() +" ,Kategorie: " + cn.getKategorie() + " ,Länge: " + cn.getLaenge()+" ,Breite: " + cn.getBreite();
                // Writing Contacts to log
        Log.d("Name: ", log);
        
        }
    }
}



Position.java:

Code:
package com.example.fotooh2;

public class Position{
	
	//private variables
	int _id;
	String name;
	String kategorie;
	double laenge;
	double breite;
	
	
	// Empty constructor
	public Position(){
		
	}
	// constructor
	public Position(int id, String name, String kategorie, double laenge, double breite){
		this._id = id;
		this.name = name;
		this.kategorie = kategorie;
		this.laenge = laenge;
		this.breite = breite;
		
	}
	
	// constructor
	public Position(String name, String kategorie, double laenge, double breite){
		this.name = name;
		this.kategorie = kategorie;
		this.laenge = laenge;
		this.breite = breite;
		
	}
	// getting ID
	public int getID(){
		return this._id;
	}
	
	// setting id
	public void setID(int id){
		this._id = id;
	}
	
		
	// getting name
	public String getName(){
		return this.name;
	}
	
	// setting name
	public void setName(String name){
		this.name = name;
	}
	
	// getting category
		public String getKategorie(){
			return this.kategorie;
		}
		
		// setting category
		public void setKategorie(String kategorie){
			this.kategorie = kategorie;
			}
	
		
	// getting Laenge
	public double getLaenge(){
		return this.laenge;
	}
	// setting LAENGE
		public void setLaenge(double laenge){
			this.laenge = laenge;

		}
		
		// getting Breite
		public double getBreite(){
			return this.breite;
		}
		
		// setting BreiteE
		public void setBreite(double breite){
			this.breite = breite;

		}
		@Override
		public String toString() {
			return "Position [ laenge=" + laenge + ", breite=" + breite
					+ "]";
		}

}
 
Das Einfachste, und meist auch Intelligenteste, ist es ein Daten-Modell
zu implementieren. Für jede deiner Tabellen in der Datenbank legst du
ein POJO (Plain old Java-Object) in deinem Code an und mappst deine
Daten aus der Datenbank in diese Klassen. Dafür gibt es verschiedenste
Frameworks mit Annotations.

Diese POJO's kannst du dann in deinen ArrayAdaptern verwenden und
in der ListView anzeigen.
 
Lybrial schrieb:
Diese POJO's kannst du dann in deinen ArrayAdaptern verwenden und
in der ListView anzeigen.


Kann man dadurch auch Bilder in der Liste anzeigen ?
 
Ja, kann man. (POJO - ein Java-Objekt ohne Vererbung (extends und implements, sowie Annotations)).

Wenn du Bilder speichern willst, benutzt du am entweder ein Blob. Ober du speicherst die Bilder einfach als Datei, und schreibst den Pfad in die Datenbank.

Wenn du nicht gerade eine objekt-relationale Datenbank (Hibernate, JDO oder EJB) willst, kannst du die Daten auch einfach in einer simplen Tabelle speichern. Und die Werte mit ein Cursor auslesen. Dazu findest du hunderte von Beispiele im Netz.
Android SQLite database and content provider - Tutorial

Zu deiner Klasse Position noch eine Anmerkung. Normalerweise lernt man der Uni, dass man getter und Setter benutzt. Unter Android ist das keine gute Idee. Erklärung siehe Link:

Performance Tips | Android Developers
 
  • Danke
Reaktionen: theboss22
markus.tullius schrieb:
Ober du speicherst die Bilder einfach als Datei, und schreibst den Pfad in die Datenbank.

Ich kann mir die Korrektur nicht verkneifen ;-)

Man schreibt natürlich nicht den kompletten Pfad in die Datenbank sondern nur den Dateinamen. Das Verzeichnis wird dynamisch ermittelt. Und dann (wenn man es braucht) mit dem Dateinamen verknüpft.

Der absolute Pfad kann sich ja jederzeit ändern.

cu
 
Der Pfad meiner Datenbank im externen Speicher kann sich auch ändern. ;) Man sollte sich schon vorher überlegen, wohin man die Sachen schreibt.
 
das mit POJO klingt ja schön und gut, aber wie genau benutzte ich so etwas ? Ich habe gerade geguckt, aber finde jetzt nicht unbedingt ein gutes Tutorial dazu, irgendwie scheint alles unterschiedlich zu sein
 
POJO ist ein einfaches JavaObjekt. Und du brauchst es nicht. SQLite ist eine relationale Datenbank, die aus einer einzelnen Datei besteht. POJO sind eher etwas für Objektrelationale Datenbanken.

Der ganze Overhead sieht zwar schön aus, aber du brauchst ihn nicht. Und er bremst deine App aus. SQLite ist nicht die schnellste Datenbank, und je komplexer du alles baust, desto langsamer wird alles.

Meisten reicht es, jeden Eintrag eine Listen einfach in eine Spalte in der Tabelle zu schreiben.
 
markus.tullius schrieb:
POJO ist ein einfaches JavaObjekt. Und du brauchst es nicht. .

also soll ich weiterhin sql Lite benutzen ?
Aber wie kann ich dann z.B. den Namen von Orten aus der Datenbank in der Listview ausgeben ?
 
Im Großen und Ganzen hast du ja oben schon alles implementiert (In der DatabaseHandler Klasse)
Du kannst ja dort entsprechend die Abfragen bzw. Funktionen so umgestalten, so wie du es halt brauchst.
Aktuell lässt du ja auch alles in eine List befüllen (List<Position> positions = db.getAllPositions();)
Dir fehlt dann jetzt nur noch die grafische Anzeige
Das obige Tutorial kenne ich btw. und habe es für mich auch komplett umgearbeitet.

Wie du an Daten aus den Datenbank kommst? Na einfach mit entsprechenden Datenbankabfragen, so wie oben ja auch schon (z.B. oben SELECT * FROM " + TABLE_POSITIONS)
Wie du abfragst und was du mit den erhaltenen Daten machst, musst ja du dann entscheiden (z.b. mit ner do while Schleife).

Ich lasse mir meine Daten in einem String Array hinzufügen, welches ich dann z.b. in einer GridView anzeigen lassen (ArrayAdapter einbauen).
 
  • Danke
Reaktionen: theboss22
KatyB schrieb:
Ich lasse mir meine Daten in einem String Array hinzufügen, welches ich dann z.b. in einer GridView anzeigen lassen (ArrayAdapter einbauen).

Wow ist jeder string im Array bei dir unterschiedlich groß? Ich sehe da irgendwie große Performanceeinbußen Strings zu benutzen...oder ein out of memory exception
 
Naja, bei mir sind es nur eine Hand voll Daten. Theoretisch Daten zu allen installierten Apps auf dem Gerät. Was soll das performancetechnisch schon nicht passen. War meine erste Implementierung, da ich selbst mit Datenbanken noch nicht viel gearbeitet habe (eher gegen 0). Btw.: Array or List in Java. Which is faster? - Stack Overflow

Ansonsten, was schlägst du (oder andere) vor. Ist ja nicht so, dass ich mich nicht belehren lasse. XD
 
Warum sollte das ein Problem sein, für was gibt es den sonst Referenzen? Außerdem schlägt @KatyB vorher eine Liste vor. Denke mal er meinte eine ArrayList.

Und Listen sind extra dafür ausgelegt. In der Grundkonzeption kann man da jedes Objekt rein stecken.
Und man kann sie dynamisch erweitern.

List | Android Developers
ArrayList | Android Developers
 
Ja ich meinte ArrayList. Nutze eine List<Strings> und implementiere eine ArrayList.
Wobei ich da mein Projekt nochmal sauber überarbeiten muss. Mein Ziel war erstmal, dass es lauffähig war. ;/
 
@KatyB: Hast du also schon eine Datenbank mit einem dazugehörigem ArrayAdapter erstellt ? Ich finde zwar im Internet einige Tutorials aber scheitere halt daran diese auf meine Datenbank "zurechtzuschneiden" :/
 
Ok auf die Schnelle mein Beispiel:

In der MainActivity:

Code:
private static GridView myGrid;
public static ArrayList<String> ArrayofApps = new ArrayList<String>();
onCreate:

Code:
myGrid = (GridView) findViewById(R.id.gridView);
DatabaseManager db = new DatabaseManager(this); #das ist dann bei dir die DatabaseHandler Klasse
db.getAllApps();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, ArrayofApps);
myGrid.setAdapter(adapter);
und hier die getAllApps() in meiner DatabaseManager Klasse:

Code:
public List<Apps> getAllApps() {
        List<Apps> appsList = new ArrayList<Apps>();
        // Select All Query
        String selectQuery = "SELECT * FROM " + TABLE_APPS;

        SQLiteDatabase data = this.getWritableDatabase();
        Cursor cursor = data.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                 Apps apps = new Apps();
                String name = "Paketname: " +  cursor.getString(1) +"\n"+ "Startzeit: " + cursor.getString(12) + "\n" + "Endzeit: " + cursor.getString(13);
                [COLOR=Red]MainActivity.ArrayofApps.add(name);   #Das hier ist das wichtigste: Du fügst die einzelnen Strings dem Array (das in der MainActivity definiert wurde) hinzu.[/COLOR]
                // Adding apps to list
                appsList.add(apps);
            } while (cursor.moveToNext());
        }

        // return apps list
        return appsList;
    }
Habe mal mein Beispiel ziemlich gekürzt. Und ja, so perfekt ist es wahrscheinlich noch nicht, aber bei mir läufts. Bin ja auch erst noch Newbie. :lol:;)
 
  • Danke
Reaktionen: theboss22
@katy b. danke für das beispiel ich habe selber ncoh nciht so viel erfahrung mit datenbanken(nur theoretischer natur)
würde sich diese beispiel auch für eine serverdatenbankabfrage eignen ich stelle mir da grausame möglichkeiten vom user vor wenn er den selectQuery string in etwas anderes umschreibt das alles löscht oder auf andere sensible daten zugreift :O
 
1. Keine Ahnung - bin doch erst Anfänger. Da können die Experten hier mehr sagen. Aber natürlich kann man sich auch remote mit Datenbanken verbinden (mit Anmeldung usw.). Nur wäre mMn ziemlich unsicher. Daher denke ich, dass es sinnvoller ist, nen Webservice zu nutzen der dann entsprechend auf die Datenbank zugreift.
2. Öffne ich die Datenbank bei mir readonly. Aber du gehst jetzt davon aus, dass ein User meine App dekompiliert um an den Query zu kommen.
3. Kann man bzgl. Sicherheit noch einiges machen - nur war das für mich mehr ein Übungsprojekt, damit ich überhaupt verstehe, wie das so mit Datenbanken unter Android funktioniert.
 
KatyB schrieb:
Ok auf die Schnelle mein Beispiel:

soooo habe das mal versucht auf meine Activities zu übertragen:

mein Code in "DatabaseHandler":
Code:
	}

	public List<Position> getAllPositionstoList() {
        List<Position> PositionsList = new ArrayList<Position>();
        // Select All Query
        String selectQuery = "SELECT * FROM " + TABLE_POSITIONS;

        SQLiteDatabase data = this.getWritableDatabase();
        Cursor cursor = data.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                 Position position = new Position();
                String name = "Name:" +  cursor.getString(1);
                listview_activity.ArrayofPositions.add(name);   
                PositionsList.add(position);
            } while (cursor.moveToNext());
        }

        // return Positions-Liste
        return PositionsList;
    }
	}


---> funktioniert :)


mein Code in listview_activity.java (sozusagen deine MainActivity):

Code:
package com.example.fotooh2;


import java.sql.Array;
import java.util.ArrayList;

import com.example.fotooh2.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;


public class listview_activity {

	
	public static ListView myList;
	public static ArrayList<String> ArrayofPositions = new ArrayList<String>();
	
	public void onCreate(Bundle savedInstanceState) {
				setContentView(R.layout.suche_liste);
	}
	
	ListView Liste = (ListView) findViewById(R.id.Liste);
	
	DatabaseHandler db = new DatabaseHandler; 
	db.getAllPositionstoList();
	ArrayAdapter <String> adapter = new Array Adapter<String>(this, android.R.layout.suche_liste, ArrayofPositions);
	myList.setAdapter(adapter);
	
	
	
	
}

-----> funktioniert leider noch nicht aufgrund folgender Fehler:
https://www.dropbox.com/s/8gj5s3gmf8hlewx/Bildschirmfoto 2015-02-10 um 21.33.18.png?dl=0

hast du eine Idee ? Ich versuche ja wirklich das zu verstehen und habe auch schon recherchiert aber verstehe noch nicht so ganz was nicht stimmt
 
Zurück
Oben Unten