First step(app) with android

Sto facendo porting di un’applicazione iPhone su Android, sto avendo modo di avvicinarmi ad entrambe le architetture valutandone pregi e difetti…pur mantenendo sempre il mio stile di programmazione…almeno fino a quando qualcuno di voi mi salverà :)

L’applicazione da portare su Android è la solita db based, quindi creato il database (sqlite) viene fatto il deploy all’interno dell’app. L’approccio è sempre lo stesso, ovvero la creazione di una classe singleton attraverso lo quale accedere al database, quindi connettere, disconnettere ed eseguire le query.
L’ambiente di riferimento su Android è Java, essendo il mio linguaggio di riferimento gioca tutto a mio favore. Il tool di sviluppo è Eclipse (forse chiamarlo tool è troppo riduttivo, facciamo IDE) e attraverso il plugin per android si parte praticamente subito allo sviluppo.

Creati i nostri package partiamo con la creazione della classe singleton: 

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package it.devme.dbmanager;
 
 
import it.devline.model.Farm;
import it.devline.model.Month;
import it.devline.model.Season;
import it.devline.model.Vegetable;
 
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
 
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
 
public class SQLiteDBManager extends SQLiteOpenHelper {
 
	private SQLiteDatabase dbconn;
	private static String DATABASE_NAME = "fennel.db";
	private static String DATABASE_PATH = "/data/data/it.devme/databases/";
	private final Context myContext;
	private static SQLiteDBManager instance;
 
	/**
	 * Costruttore
	 * @param context, il contesto dell'applicazione
	 */
	private SQLiteDBManager(Context context) {
	    super(context, DATABASE_NAME, null, 2);
		this.myContext = context;
	}
 
	public static SQLiteDBManager getInstance(Context context) {
		if (instance==null) {
			instance = new SQLiteDBManager(context);
		}
		return instance;
	}
 
	/**
	 * Tenta di aprire il database in sola lettura. Se il database non è presente,
	 * viene copiato dalla directory assets alla directory databases dell'applicazione.
	 * @return true se l'apertura del db va a buon fine; false altrimenti.
	 * @throws SQLException, eccezione in caso di errore.
	 */
	public boolean open() throws SQLException {
		boolean dbExist = checkDataBase();
 
		if(dbExist) {
    		//do nothing - database already exist
    	} else {
    		dbconn = this.getWritableDatabase();
        	try {
    			copyDataBase();
    		} catch (IOException e) {
        		Log.i("DBMANAGER", e.getMessage());
        		return false;
        	}
    	}
		return true;
	}
 
	/**
	 * Chiude il database.
	 */
	public synchronized void close() {
		 if(dbconn != null)
			 dbconn.close();
		 super.close();
	}
 
	@Override
	public void onCreate(SQLiteDatabase db) {
	}
 
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	}
 
	/**
	 * Effettua la copia del database dalla directory assets alla directory
	 * databases di default dell'applicazione.
	 * @throws IOException, eccezione in caso di problemi con il file
	 */
	public void copyDataBase() throws IOException {
 
	    InputStream assetsDB = myContext.getAssets().open(DATABASE_NAME);
	    OutputStream dbOut = new java.io.FileOutputStream(DATABASE_PATH + DATABASE_NAME);
 
	    byte[] buffer = new byte[1024];
	    int length;
	    while ((length = assetsDB.read(buffer))>0){
	      dbOut.write(buffer, 0, length);
	    }
 
	    dbOut.flush();
	    dbOut.close();
	    assetsDB.close();
	}	
 
	/**
	 * Restituisce true se il database è presente ed è possibile aprirlo;
	 * false altrimenti.
	 * @return true in caso di successo; false altrimenti.
	 */
	private boolean checkDataBase(){
		SQLiteDatabase checkDB = null;
 
		try {
			checkDB = SQLiteDatabase.openDatabase(DATABASE_PATH + DATABASE_NAME, null, SQLiteDatabase.OPEN_READONLY);
    	} catch(SQLiteException e) {}
 
    	if (checkDB != null) {
    		checkDB.close();
    	}
    	return checkDB != null ? true : false;
    }
 
    public List<String> getNames () {
	List<String> result = new ArrayList<String>();
	String sql = "SELECT name " +
		     "FROM Devme " +
		     "ORDER BY RANDOM()";
 
	Cursor cursor = dbconn.rawQuery(sql, null);
	while (cursor.moveToNext()) {
		result.add(cursor.getString(cursor.getColumnIndex("name")));
        }
	return result;    
    }
}

Si tratta di una classe Java (singleton) che realizza l’interazione con il database. Per utilizzarla è sufficiente ottenenerne l’istanza e quindi invocare il metodo che realizza la query voluta. Ovviamente prima bisogna connettersi, come segue: 

1
2
3
4
5
 .....
 .....
 SQLiteDBManager dbconn = SQLiteDBManager.getInstance(this);
 dbconn.open();
 List<string> vegs = dbconn.getNames();  dbconn.close();  <br /> ....      <br /> .... <br /></string>

Semplice, vero ?!
Questo è solo un assaggio per capire di quali potenzialità gode la piattaforma Android. Nei prossimi articoli, cercherò di occuparmi di esempi un pò più complessi per tirare in ballo altri argomenti.
Stay tuned ! 

WordPress Themes