Danny Fürniß, 25.11.2012, 1 Programmierung von Apps Android Persistence and Networking
May 11, 2015
Dann
y Für
niß,
25.
11.2
012,
1
Programmierungvon Apps
Android Persistenceand Networking
Dann
y Für
niß,
25.
11.2
012,
2
Die Studierenden kennen die Möglichkeiten für
Android Persistence und Networkingund verstehen, wie damit auf Daten
und Netzwerke zugegriffen werden kann.
Dann
y Für
niß,
25.
11.2
012,
3
Files
Dann
y Für
niß,
25.
11.2
012,
4
Internal Storage
Demo
/data/data/<app-package-name>
/databases
/shared_prefs/files
/lib…
/cache
Dann
y Für
niß,
25.
11.2
012,
5
openFileInput() openFileOutput()
MODE_PRIVATE – Kein Zugriff durch andere Apps
MODE_WORLD_READABLE – Lesender Zugriff durch andere Apps
MODE_WORLD_WRITABLE – Schreibender Zugriff durch andere Apps
MODE_WORLD_READABLE | MODE_WORLD_WRITABLE – Lese- und Schreib-Zugriff
Dann
y Für
niß,
25.
11.2
012,
6
External Storage
Quelle: http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir(java.lang.String)
Environment.getExternalStorageState();
Context.getExternalFilesDir(type);
Environment.DIRECTORY_MUSIC,Environment.DIRECTORY_PODCASTS,Environment.DIRECTORY_RINGTONES,Environment.DIRECTORY_ALARMS,Environment.DIRECTORY_NOTIFICATIONS,Environment.DIRECTORY_PICTURES, Environment.DIRECTORY_MOVIES.
nullandroid.permission.WRITE_EXTERNAL_STORAGE
/Android/data/<package-name>Demo
Dann
y Für
niß,
25.
11.2
012,
7
„In-APP“-Storage
/res/raw getResources().openRawResource()
/res/xml getResources().getXml()
/assets getAssets().open()
Dann
y Für
niß,
25.
11.2
012,
8
Shared Preferences
Dann
y Für
niß,
25.
11.2
012,
9
PreferenceActivity
@Overridepublic void onBuildHeaders(List<Header> target) {
super.onBuildHeaders(target);loadHeadersFromResource(R.xml.prefs_headers,
target);}
Demo
Dann
y Für
niß,
25.
11.2
012,
10
extends PreferenceFragmentaddPreferencesFromResource(R.xml.prefs_server);
<?xml version="1.0" encoding="utf‐8"?><PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"><PreferenceCategory
android:title="@string/prefsServerSettings"><EditTextPreference
android:title="@string/prefsServerUrl" android:key="prefsServerUrl"/>
<CheckBoxPreferenceandroid:title="@string/prefsServerWifiOnly" android:key="prefsServerWifiOnly"/>
</PreferenceCategory></PreferenceScreen>
prefs_server.xml
Dann
y Für
niß,
25.
11.2
012,
11
SharedPreferenceslesen und schreiben
prefs = PreferenceManager.getDefaultSharedPreferences(this);String prefsServerUrl =
prefs.getString("<key>", "<default‐value>");
SharedPreferences.Editor editor = prefs.edit();editor.putString("<key>", "<value>");editor.commit();
Dann
y Für
niß,
25.
11.2
012,
12
Database
Dann
y Für
niß,
25.
11.2
012,
13
SQLite• Keine Konfiguration notwendig
• Kein Datenbank-Server
• Single-File Datenbank (Filesystem-Security)
• Open Source
• In Android integriert
• Keine strikte statische Typisierung
• sqlite.org
Dann
y Für
niß,
25.
11.2
012,
14
SQLite DataTypes
Quelle: http://www.sqlite.org/datatype3.html
• TEXT
• INTEGER
• REAL
No checks!
• Date and Time (functions)
• TEXT as ISO8601 strings
("YYYY-MM-DD HH:MM:SS.SSS").
• INTEGER as Unix Time, the number of
seconds since 1970-01-01 00:00:00 UTC.
Dann
y Für
niß,
25.
11.2
012,
15
extend SQLiteOpenHelper
• Erzeugt Datenbank
• onCreate()
• Aktualisiert Datenbank
• onUpgrade()
• Ermöglicht Zugriff auf die Datenbank
• getReadableDatabase()
• getWritableDatabase()
Demo
Dann
y Für
niß,
25.
11.2
012,
16
onCreate()
public void onCreate(SQLiteDatabase db) {
db.execSQL(NewsItemContract.Table.CREATE_TABLE_NEWS);
db.execSQL("CREATE TABLE xyz (_id PRIMARY KEY AUTOIN…");}
Dann
y Für
niß,
25.
11.2
012,
17
onUpgrade()
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + NewsItemContract.Table.NEWS);
onCreate(db);}
Dann
y Für
niß,
25.
11.2
012,
18
REATE
EAD
PDATE
ELETE
Dann
y Für
niß,
25.
11.2
012,
19
insert()
ContentValues values = new ContentValues();values.put(NewsItemColumns.title, item.getTitle());values.put(NewsItemColumns.teaser, item.getTeaser());values.put(NewsItemColumns.published, item.getPublished().getTime());values.put(NewsItemColumns.pictureUrl, item.getPictureUri().toString());values.put(NewsItemColumns.imageFileName, item.getImageFileName());
…
db.insertOrThrow(NewsItemContract.Table.NEWS, null, values);
Dann
y Für
niß,
25.
11.2
012,
20
query()
SELECT edvNr, name
FROM lehrveranstaltung
WHERE name
= "Prof. Dr.‐Ing. Vogelsang"
ORDER BY edvNr
SQL
projection/columns
table
selection
selectionArgs
groupBy = null
having = null
orderBy
Interface
Dann
y Für
niß,
25.
11.2
012,
21
update()
db.update(table, values, whereClause,whereArgs
);
Dann
y Für
niß,
25.
11.2
012,
22
delete()
db.delete(table, whereClause,whereArgs
);
Dann
y Für
niß,
25.
11.2
012,
23
Cursor
Dann
y Für
niß,
25.
11.2
012,
24
Cursor nutzen
int edvNrIndex= cursor.getColumnIndex(„edvNr“)
String edvNr = cursor.getString(edvNrIndex)
0 1 2 3_id edvNr name …
Dann
y Für
niß,
25.
11.2
012,
25
Transactions
Bildquelle: http://developer.android.com/design/patterns/actionbar.html
int inserts = 0;try {db.beginTransaction();if (null != table) {
for (ContentValues contentValues : values) {db.insert(table, "", contentValues);inserts++;
}db.setTransactionSuccessful();
}
} catch (SQLException e) {Log.e(LOG_TAG, "Insert fehlgeschlagen", e);
} finally {db.endTransaction();
}
Dann
y Für
niß,
25.
11.2
012,
26
Networking
Dann
y Für
niß,
25.
11.2
012,
27
Permissions
android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
Dann
y Für
niß,
25.
11.2
012,
28
10.0.2.2IP‐Adresse für das Host‐System im Android Emulator
Dann
y Für
niß,
25.
11.2
012,
29
Apache Http ClientHttpClient client = new DefaultHttpClient();HttpGet request = new HttpGet(host +
"/api/persons?type=ProfessorInnen");
// Response lesenHttpResponse response = client.execute(request);BufferedReader reader = new BufferedReader(new
InputStreamReader(response.getEntity().getContent()));String content = "";StringBuilder responseTxt = new StringBuilder(); while ((content = reader.readLine()) != null) {
responseTxt.append(content);}
Demo
Dann
y Für
niß,
25.
11.2
012,
30
java.net.HttpUrlConnection
Quelle: http://android-developers.blogspot.de/2011/09/androids-http-clients.html
URL newsUrl = new URL(host + "/api/news.json"); HttpURLConnection conn = (HttpURLConnection)
newsUrl.openConnection();
// Response lesenInputStream in = conn.getInputStream();BufferedReader reader = new BufferedReader(
new InputStreamReader(in));String content = "";StringBuilder response = new StringBuilder();while ((content = reader.readLine()) != null) {
response.append(content);}
Demo
Dann
y Für
niß,
25.
11.2
012,
31
Dann
y Für
niß,
25.
11.2
012,
32
Representational State Transfer (REST)
http://www.slideshare.net/dnene/rest‐representational‐state‐transfer‐explained
HTTP-Verben
POST
GET
PUT
DELETE
Architekturstil
basierend auf WWW
URI, Ressourcen, Repräsentationenhttp://localhost:8180/api/newshttp://localhost:8180/api/news/3http://localhost:8180/api/personsetc.
json, xml, html, etc.
Dann
y Für
niß,
25.
11.2
012,
33
JSON
{ "newsItem" : [ { "id" : 3,"imageFileName" : "news3.jpg","pictureUri" : "http://localhost:8180/images/news3.jpg","published" : "2011‐12‐20T13:07:54.480+01:00","teaser" : "für Innovationen in der Hochschullehre","title" : "Prof. Dr. Andreas Heberle erhält für gute Lehre Förderpreis von 50 000 Euro"} ] }
JSONObject
JSONArray
JSONObject
Demo
Dann
y Für
niß,
25.
11.2
012,
34
XML APIs
Quelle: http://www.torsten-horn.de/techdocs/java-xml.htm
SAX (Simple API for XML)
DOM (Document Object Model)
StAX (Streaming API for XML)
Dann
y Für
niß,
25.
11.2
012,
35
XmlPullParser
Quelle: http://www.xmlpull.org; http://android-developers.blogspot.com/2011/12/watch-out-for-xmlpullparsernexttext.html
XmlPullParserFactory.newPullParser().
Dann
y Für
niß,
25.
11.2
012,
36
XML
<person><akademischerTitel>Prof. Dr.</akademischerTitel><displayName>Albrecht, Ditzinger</displayName><imageURI>http://localhost:8180/images/I_2e8f4d534f.jpg</imageURI><personURI>http://localhost:8180/api/persons/3</personURI>
</person>
START_TAG, name = person
START_TAG, name = akademischerTitel
Text
END_TAG, name = person
Demo
Dann
y Für
niß,
25.
11.2
012,
37
ContentProvider
Dann
y Für
niß,
25.
11.2
012,
38
ContentProvider
Dann
y Für
niß,
25.
11.2
012,
39
URIs
content://com.dfuerniss.pva.ss2012.database.contentprovider/lehrveranstaltungen
content://com.dfuerniss.pva.ss2012.database.contentprovider/lehrveranstaltungen/#
Multi Item
Single Item
Platzhalter für die Id der Lehrveranstaltung
Demo
Dann
y Für
niß,
25.
11.2
012,
40
ContentResolver
Cursor cursor = getContentResolver().query(
uri, projection, selection, selectionArgs, sortOrder
);
Dann
y Für
niß,
25.
11.2
012,
41
android:authorities
<providerandroid:name=".provider.LehrveranstaltungContentProvider" android:authorities=
"com.dfuerniss.pva.ss2012.database.contentprovider"></provider>
Dann
y Für
niß,
25.
11.2
012,
42
extendContentProvider
Demo
Dann
y Für
niß,
25.
11.2
012,
43
Loader
Dann
y Für
niß,
25.
11.2
012,
44
Loaders
Dann
y Für
niß,
25.
11.2
012,
45
initLoader
private static final int NEWS_LOADER = 0;
…
// setup news loaderLog.i(TAG, "initLoader: " + NEWS_LOADER);newsLoader = getLoaderManager().initLoader(NEWS_LOADER,
null, this);
Dann
y Für
niß,
25.
11.2
012,
46
implementsLoaderCallbacks<Cursor>
1@Overridepublic Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
Log.i(TAG, "creating loader for id: " + loaderId);AsyncTaskLoader<Cursor> loader = null;if (loaderId == NEWS_LOADER) {
Log.i(TAG, "creating news loader");loader = new AsyncTaskLoader<Cursor>(this) {
…};
}return loader;
}
Dann
y Für
niß,
25.
11.2
012,
47
implementsLoaderCallbacks<Cursor>
2@Overridepublic void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
Log.i(TAG, "loader finished: " + loader.getId());if (loader.getId() == NEWS_LOADER) {
newsAdapter.swapCursor(cursor);}
}
@Overridepublic void onLoaderReset(Loader<Cursor> loader) {
Log.i(TAG, "loader reset: " + loader.getId());if (loader.getId() == NEWS_LOADER) {
newsAdapter.swapCursor(null);}
}Demo
Dann
y Für
niß,
25.
11.2
012,
48
AsyncTaskLoader@Overridepublic Cursor loadInBackground() {
Log.i(TAG, "load in background");SQLiteDatabase db = ((Application) getApplication())
.getDbHelper().getReadableDatabase();return db.query(
NewsItemContract.Table.NEWS, // Projection muss _id enthalten!NewsItemContract.Query.PROJECTION_ALL, selection, selectionArgs, groupBy, having, orderBy);
}
@Overridepublic void onStartLoading() { …forceLoad()… }
Dann
y Für
niß,
25.
11.2
012,
49
CursorLoaderCursorLoader cl =
new CursorLoader(context, URI, projection, selection, selectionArgs, sortOrder
);
Dann
y Für
niß,
25.
11.2
012,
50
android:installLocation
internalOnly (default)
auto
preferExternal
Dann
y Für
niß,
25.
11.2
012,
51
Portions of this presentation are modifications based on work created and shared by Google and used according
to terms described in the Creative Commons 3.0
Attribution License.