SlideShare uma empresa Scribd logo
1 de 32
Baixar para ler offline
Data	
  Persistence	
  in	
  Android	
  
Jussi	
  Pohjolainen	
  
Tampere	
  University	
  of	
  Applied	
  Sciences	
  
Contents	
  
•  Overview	
  
•  About	
  State	
  InformaAon	
  
•  Preferences	
  
•  Using	
  files	
  
•  Using	
  databases	
  
•  Accessing	
  Content	
  Providers	
  
Overview	
  of	
  Data	
  Storing	
  
•  App	
  data	
  is	
  private	
  to	
  the	
  applicaAon	
  
•  Several	
  mechanism	
  
–  State	
  Storage:	
  Ram	
  memory!	
  
•  Mechanism	
  for	
  saving	
  acAvity’s	
  state	
  temporarily	
  
–  Preferences	
  
•  Lightweight	
  mechanism	
  to	
  store	
  and	
  retrieve	
  key-­‐value	
  pairs	
  
–  Files	
  
•  Open	
  and	
  save	
  files	
  on	
  the	
  device	
  or	
  removable	
  storage	
  
–  SQLite	
  databases	
  
•  Databases	
  
•  Content	
  provider	
  is	
  used	
  to	
  give	
  the	
  data	
  to	
  other	
  apps	
  
AcAvity	
  State:	
  Using	
  RAM	
  
•  AcAvity’s	
  state	
  informaAon	
  can	
  be	
  lost,	
  if	
  it’s	
  
closed	
  
– When	
  acAvity	
  is	
  no	
  longer	
  on	
  the	
  screen	
  and	
  it’s	
  
closed	
  because	
  of	
  freeing	
  memory	
  
– When	
  screen	
  rota1on	
  is	
  changed,	
  the	
  acAvity	
  is	
  
destroyed	
  and	
  opened	
  again	
  
	
  
How	
  to	
  Store	
  State	
  InformaAon	
  
•  Store	
  state:	
  
– onSaveInstanceState(Bundle)
•  Read	
  state	
  
– onRestoreInstanceState(Bundle)
•  This	
  will	
  store	
  data	
  only	
  temporarily:	
  for	
  app	
  
life1me!	
  
•  Data	
  will	
  be	
  held	
  in	
  memory	
  un1l	
  the	
  app	
  is	
  
closed!	
  
Store	
  
@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
String text = tv.getText().toString();
savedInstanceState.putString("someKey", text);
super.onSaveInstanceState(savedInstanceState);
}
Load	
  
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null)
{
String strValue = savedInstanceState.getString("someKey");
if (strValue != null)
{
textfield.setText(strValue);
}
}
}
Shared	
  Preferences:	
  Permanent	
  Storage	
  
•  Very	
  simple	
  way	
  of	
  share	
  small	
  amount	
  of	
  
data	
  between	
  acAviAes	
  
•  Also	
  for	
  saving	
  the	
  state	
  of	
  the	
  app	
  
•  Preferences	
  have	
  names,	
  so	
  apps	
  other	
  
components	
  can	
  found	
  them	
  
•  Preferences	
  can	
  be	
  private	
  or	
  public	
  (world	
  
readable,	
  writeable)	
  
How?	
  
•  SharedPreferences	
  provides	
  general	
  framework	
  
for	
  saving	
  and	
  retrieving	
  
•  To	
  get	
  SharedPreferences,	
  use	
  
–  getSharedPreferences(String name) –	
  Use	
  if	
  you	
  
need	
  mulAple	
  preference	
  files	
  (idenAfied	
  by	
  name)	
  
–  getPreferences() –	
  Use	
  if	
  only	
  one	
  preferences	
  file	
  
is	
  needed	
  
•  To	
  write	
  values,	
  call	
  edit() to	
  get	
  
SharedPreferences.Editor	
  to	
  be	
  used	
  when	
  
adding	
  values	
  to	
  file.	
  
Preferences	
  Example	
  
public class Calc extends Activity {
    public static final String PREFS_NAME = "MyPrefsFile";
    @Override
    protected void onCreate(Bundle state){
       super.onCreate(state);
       . . .
       // Restore preferences
       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
       boolean silent = settings.getBoolean("silentMode", false);
    }
    @Override
    protected void onStop(){
       super.onStop();
      // We need an Editor object to make preference changes.
      // All objects are from android.context.Context
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);
      // Commit the edits!
      editor.commit();
    }
}
Files	
  
•  It's	
  possible	
  to	
  store	
  files	
  on	
  the	
  mobile	
  device	
  or	
  on	
  a	
  
removable	
  storage	
  
•  Current	
  applica1on	
  folder	
  only.	
  ExcepAon	
  thrown	
  
otherwise.	
  
–  Modes:	
  MODE_PRIVATE,	
  MODE_WORLD_READABLE,	
  
MODE_WORLD_WRITABLE	
  
•  Reading	
  
–  openFileInput()
•  WriAng	
  
–  openFileOutput()
•  Standard	
  Java	
  streams	
  aer	
  that	
  
StaAc	
  files	
  
•  You	
  can	
  save	
  staAc	
  files	
  into	
  res/raw	
  directory	
  
•  Accessing	
  using	
  
openRawResource(R.raw.<filename>)
•  Returns	
  InputStream
•  Cannot	
  write	
  to	
  data	
  
Files	
  
// Write
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
// Read
FileInputStream fis = openFileInput(FILENAME);
int byteChar;
while((byteChar = fis.read()) != -1)
{
System.out.println((char) byteChar);
}
fis.close()
Reading	
  MODE_WORLD_READABLE	
  file	
  
•  When	
  reading	
  public	
  file,	
  use	
  FileInputStream	
  
(vs.	
  openFileInput)	
  
•  Give	
  full	
  path:	
  /data/data/<package>/files
SQLite	
  
•  Support	
  for	
  SQlite	
  databases	
  
–  Database	
  is	
  private	
  to	
  the	
  applicaAon	
  that	
  creates	
  it	
  
•  SQLiteDatabase	
  object	
  represents	
  a	
  database	
  
•  SQLiteOpenHelper	
  –	
  wrapper	
  for	
  database	
  
acAons	
  
•  Android	
  SDK	
  has	
  a	
  tool	
  called	
  sqlite3	
  which	
  
enables	
  you	
  to	
  browse	
  table	
  contents	
  using	
  sql	
  
commands	
  and	
  command	
  line	
  
•  All	
  databases	
  are	
  stored	
  in	
  /data/data/
<package_name>/databases folder	
  on	
  your	
  
device.	
  
SQLiteDatabase:	
  Open	
  
public void openDatabase() {
try {
db = this.openOrCreateDatabase("MyTestDatabase.db", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE MYDATA(firstname TEXT, lastname TEXT)");
} catch (SQLiteException e) {
e.printStackTrace();
}
}
SQLiteDatabase:	
  Insert	
  
public void insertRows() {
try {
db.execSQL("INSERT INTO MYDATA VALUES ('Jack', 'Smith')");
} catch (Exception e) {
e.printStackTrace();
}
}
SQLiteDatabase:	
  Read	
  
public void readRows() {
try {
Cursor c = db.rawQuery("SELECT * FROM MYDATA", null);
String text = "";
c.moveToFirst();
for(int i=0; i<c.getCount(); i++) {
text += c.getString(0) + " " + c.getString(1);
c.moveToNext();
}
tv.setText(text);
} catch (Exception e) {
e.printStackTrace();
}
}
SQLiteOpenHelper	
  
•  Wraps	
  best	
  pracAce	
  pacern	
  for	
  creaAng,	
  
opening	
  and	
  upgrading	
  databases	
  
•  You	
  hide	
  the	
  logic	
  used	
  to	
  decide	
  if	
  a	
  database	
  
needs	
  to	
  be	
  created	
  or	
  upgraded	
  before	
  it's	
  
opened	
  
Recommended	
  Way:	
  SQLiteOpenHelper	
  
public class DictionaryOpenHelper extends SQLiteOpenHelper {
    private static final int DATABASE_VERSION = 2;
    private static final String DICTIONARY_TABLE_NAME = "dictionary";
    private static final String DICTIONARY_TABLE_CREATE =
                "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
                KEY_WORD + " TEXT, " +
                KEY_DEFINITION + " TEXT);";
    DictionaryOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DICTIONARY_TABLE_CREATE);
    }
}
// Example
public class SQLiteExample extends Activity {
private MyDataHelper dbhelper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dbhelper = new MyDataHelper(this);
dbhelper.deleteAll();
dbhelper.insert("Jussi");
dbhelper.insert("Pekka");
dbhelper.insert("Tiina");
List<String> list = dbhelper.selectAll();
for(String object : list) {
System.out.println(object);
}
}
}
Remote	
  Shell	
  for	
  Databases	
  
Content	
  Providers	
  
•  The	
  recommended	
  way	
  of	
  sharing	
  data	
  in	
  
Android	
  is	
  to	
  use	
  content	
  providers	
  
•  Generic	
  interface	
  for	
  data	
  
•  Permission	
  control	
  and	
  accessing	
  using	
  URI	
  
model	
  
•  NaAve	
  databases	
  available	
  as	
  Content	
  
Providers	
  
•  Publishing	
  your	
  own	
  data	
  source,	
  other	
  apps	
  
can	
  incorporate	
  your	
  database	
  
Content	
  Resolver	
  
•  ApplicaAon	
  context	
  has	
  Content	
  Resolver	
  
which	
  you	
  can	
  use	
  to	
  access	
  data	
  
– ContentResolver cr =
getContentResolver();
•  For	
  accessing	
  other	
  databases,	
  you	
  need	
  a	
  URI	
  
•  URI	
  is	
  arbitraty	
  String,	
  which	
  is	
  defined	
  in	
  
manifest	
  file	
  
Usage	
  
// Query
Cursor c = getContentResolver().query(URI, ..., ... ,...);
// Insert
getContentResolver().insert(URI, newValues);
// Delete
getContentResolver().delete(URIofTheRow, ...);
URIs	
  
•  Content	
  URIs	
  must	
  be	
  unique	
  between	
  
providers.	
  
•  Use	
  your	
  package	
  name	
  
•  General	
  form	
  
–  content://com.<company>.provider.<app>/<data>
•  Example	
  for	
  querying	
  all	
  items	
  
–  content://fi.pohjolainen_jussi.provider.myapp/items
•  Example	
  for	
  querying	
  single	
  item	
  (fih)	
  
–  content://fi.pohjolainen_jussi.provider.myapp/items/5
Manifest	
  
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fi.tamk"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".CallMe"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider android:name=".Data"
android:authorities="fi.pohjolainen_jussi.provider.mycontentprovider"></provider>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
Accessing	
  Content	
  Provider	
  
public class MyContentProvider extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ContentResolver cr = getContentResolver();
Uri uri = Uri.parse("content://fi.pohjolainen_jussi.provider.mycontentprovider");
Cursor cursor = cr.query(uri, null, null, null, null);
}
}
Extend	
  Content	
  Provider	
  
public class MyContentProvider extends ContentProvider {
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {...}
@Override
public String getType(Uri uri) {...}
@Override
public Uri insert(Uri uri, ContentValues values) {...}
@Override
public boolean onCreate() {...}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {...}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {...}
}
URLMatcher	
  
•  The	
  content	
  provider	
  can	
  give	
  different	
  results	
  
depending	
  on	
  the	
  URI:	
  
– content://
fi.pohjolainen_jussi.provider.myapp/items
– content://
fi.pohjolainen_jussi.provider.myapp/
items/5
•  Use	
  UAlity	
  class	
  URLMatcher	
  to	
  differenAate	
  
the	
  given	
  URIs	
  
Example	
  of	
  URIMatcher	
  
public class Data extends ContentProvider {
@Override
public boolean onCreate() {
initializeUriMatcher();
return false;
}
...
// Differentiate between different URI requests
private static final int ALLROWS = 1;
private static final int SINGLE_ROW = 2;
// UriMatcher is utility class for aiding matching URIs in content providers
private UriMatcher uriMatcher;
private void initializeUriMatcher() {
// Root node for the URI Matcher
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// Add a URI to match, and the code to return when this URI is matched
uriMatcher.addURI("fi.pohjolainen_jussi.provider.mycontentprovider", "items", ALLROWS);
uriMatcher.addURI("fi.pohjolainen_jussi.provider.mycontentprovider", "items/#", SINGLE_ROW);
}
}
Example	
  of	
  URIMatcher	
  
public class Data extends ContentProvider {
@Override
public boolean onCreate() {
initializeUriMatcher();
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
switch(uriMatcher.match(uri)) {
case SINGLE_ROW:
String rowNumber = uri.getPathSegments().get(1);
// ..
break;
case ALLROWS:
//
break;
}
return null;
}
}

Mais conteúdo relacionado

Mais procurados

Menu bars and menus
Menu bars and menusMenu bars and menus
Menu bars and menus
myrajendra
 
Day: 1 Introduction to Mobile Application Development (in Android)
Day: 1 Introduction to Mobile Application Development (in Android)Day: 1 Introduction to Mobile Application Development (in Android)
Day: 1 Introduction to Mobile Application Development (in Android)
Ahsanul Karim
 
Android animation
Android animationAndroid animation
Android animation
Krazy Koder
 
A Basic Django Introduction
A Basic Django IntroductionA Basic Django Introduction
A Basic Django Introduction
Ganga Ram
 

Mais procurados (20)

Android adapters
Android adaptersAndroid adapters
Android adapters
 
Notification android
Notification androidNotification android
Notification android
 
SQLITE Android
SQLITE AndroidSQLITE Android
SQLITE Android
 
Introduction to HTML5
Introduction to HTML5Introduction to HTML5
Introduction to HTML5
 
Android application development ppt
Android application development pptAndroid application development ppt
Android application development ppt
 
Menu bars and menus
Menu bars and menusMenu bars and menus
Menu bars and menus
 
Day: 1 Introduction to Mobile Application Development (in Android)
Day: 1 Introduction to Mobile Application Development (in Android)Day: 1 Introduction to Mobile Application Development (in Android)
Day: 1 Introduction to Mobile Application Development (in Android)
 
JavaScript - Chapter 12 - Document Object Model
  JavaScript - Chapter 12 - Document Object Model  JavaScript - Chapter 12 - Document Object Model
JavaScript - Chapter 12 - Document Object Model
 
Android - Android Intent Types
Android - Android Intent TypesAndroid - Android Intent Types
Android - Android Intent Types
 
Android Threading
Android ThreadingAndroid Threading
Android Threading
 
Java Servlets
Java ServletsJava Servlets
Java Servlets
 
Asynchronous JavaScript & XML (AJAX)
Asynchronous JavaScript & XML (AJAX)Asynchronous JavaScript & XML (AJAX)
Asynchronous JavaScript & XML (AJAX)
 
Android animation
Android animationAndroid animation
Android animation
 
A Basic Django Introduction
A Basic Django IntroductionA Basic Django Introduction
A Basic Django Introduction
 
Data Storage In Android
Data Storage In Android Data Storage In Android
Data Storage In Android
 
Dom(document object model)
Dom(document object model)Dom(document object model)
Dom(document object model)
 
Android User Interface
Android User InterfaceAndroid User Interface
Android User Interface
 
Android share preferences
Android share preferencesAndroid share preferences
Android share preferences
 
Event handling
Event handlingEvent handling
Event handling
 
Java tutorial PPT
Java tutorial PPTJava tutorial PPT
Java tutorial PPT
 

Semelhante a Android Data Persistence

Javase7 1641812
Javase7 1641812Javase7 1641812
Javase7 1641812
Vinay H G
 
Windows Phone 8 - 4 Files and Storage
Windows Phone 8 - 4 Files and StorageWindows Phone 8 - 4 Files and Storage
Windows Phone 8 - 4 Files and Storage
Oliver Scheer
 
Windows Phone 8 - 4 Files and Storage
Windows Phone 8 - 4 Files and StorageWindows Phone 8 - 4 Files and Storage
Windows Phone 8 - 4 Files and Storage
Oliver Scheer
 
Boost Your Environment With XMLDB - UKOUG 2008 - Marco Gralike
Boost Your Environment With XMLDB - UKOUG 2008 - Marco GralikeBoost Your Environment With XMLDB - UKOUG 2008 - Marco Gralike
Boost Your Environment With XMLDB - UKOUG 2008 - Marco Gralike
Marco Gralike
 

Semelhante a Android Data Persistence (20)

Android App Development - 09 Storage
Android App Development - 09 StorageAndroid App Development - 09 Storage
Android App Development - 09 Storage
 
Persistences
PersistencesPersistences
Persistences
 
09.Local Database Files and Storage on WP
09.Local Database Files and Storage on WP09.Local Database Files and Storage on WP
09.Local Database Files and Storage on WP
 
Android Training (Storing & Shared Preferences)
Android Training (Storing & Shared Preferences)Android Training (Storing & Shared Preferences)
Android Training (Storing & Shared Preferences)
 
12_Data_Storage_Part_2.pptx
12_Data_Storage_Part_2.pptx12_Data_Storage_Part_2.pptx
12_Data_Storage_Part_2.pptx
 
Android - Data Storage
Android - Data StorageAndroid - Data Storage
Android - Data Storage
 
Android-data storage in android-chapter21
Android-data storage in android-chapter21Android-data storage in android-chapter21
Android-data storage in android-chapter21
 
Javase7 1641812
Javase7 1641812Javase7 1641812
Javase7 1641812
 
Integration patterns in AEM 6
Integration patterns in AEM 6Integration patterns in AEM 6
Integration patterns in AEM 6
 
Memory management
Memory managementMemory management
Memory management
 
Storage 8
Storage   8Storage   8
Storage 8
 
Persistence on iOS
Persistence on iOSPersistence on iOS
Persistence on iOS
 
eZ Publish Cluster Unleashed
eZ Publish Cluster UnleashedeZ Publish Cluster Unleashed
eZ Publish Cluster Unleashed
 
Windows Phone 8 - 4 Files and Storage
Windows Phone 8 - 4 Files and StorageWindows Phone 8 - 4 Files and Storage
Windows Phone 8 - 4 Files and Storage
 
Windows Phone 8 - 4 Files and Storage
Windows Phone 8 - 4 Files and StorageWindows Phone 8 - 4 Files and Storage
Windows Phone 8 - 4 Files and Storage
 
Boost Your Environment With XMLDB - UKOUG 2008 - Marco Gralike
Boost Your Environment With XMLDB - UKOUG 2008 - Marco GralikeBoost Your Environment With XMLDB - UKOUG 2008 - Marco Gralike
Boost Your Environment With XMLDB - UKOUG 2008 - Marco Gralike
 
Softshake - Offline applications
Softshake - Offline applicationsSoftshake - Offline applications
Softshake - Offline applications
 
L04 base patterns
L04 base patternsL04 base patterns
L04 base patterns
 
Assets, files, and data parsing
Assets, files, and data parsingAssets, files, and data parsing
Assets, files, and data parsing
 
Java Web Programming on Google Cloud Platform [2/3] : Datastore
Java Web Programming on Google Cloud Platform [2/3] : DatastoreJava Web Programming on Google Cloud Platform [2/3] : Datastore
Java Web Programming on Google Cloud Platform [2/3] : Datastore
 

Mais de Jussi Pohjolainen

Advanced JavaScript Development
Advanced JavaScript DevelopmentAdvanced JavaScript Development
Advanced JavaScript Development
Jussi Pohjolainen
 
libGDX: Simple Frame Animation
libGDX: Simple Frame AnimationlibGDX: Simple Frame Animation
libGDX: Simple Frame Animation
Jussi Pohjolainen
 
Creating Asha Games: Game Pausing, Orientation, Sensors and Gestures
Creating Asha Games: Game Pausing, Orientation, Sensors and GesturesCreating Asha Games: Game Pausing, Orientation, Sensors and Gestures
Creating Asha Games: Game Pausing, Orientation, Sensors and Gestures
Jussi Pohjolainen
 
Creating Games for Asha - platform
Creating Games for Asha - platformCreating Games for Asha - platform
Creating Games for Asha - platform
Jussi Pohjolainen
 
Intro to Java ME and Asha Platform
Intro to Java ME and Asha PlatformIntro to Java ME and Asha Platform
Intro to Java ME and Asha Platform
Jussi Pohjolainen
 

Mais de Jussi Pohjolainen (20)

Moved to Speakerdeck
Moved to SpeakerdeckMoved to Speakerdeck
Moved to Speakerdeck
 
Java Web Services
Java Web ServicesJava Web Services
Java Web Services
 
Box2D and libGDX
Box2D and libGDXBox2D and libGDX
Box2D and libGDX
 
libGDX: Screens, Fonts and Preferences
libGDX: Screens, Fonts and PreferenceslibGDX: Screens, Fonts and Preferences
libGDX: Screens, Fonts and Preferences
 
libGDX: Tiled Maps
libGDX: Tiled MapslibGDX: Tiled Maps
libGDX: Tiled Maps
 
libGDX: User Input and Frame by Frame Animation
libGDX: User Input and Frame by Frame AnimationlibGDX: User Input and Frame by Frame Animation
libGDX: User Input and Frame by Frame Animation
 
Intro to Building Android Games using libGDX
Intro to Building Android Games using libGDXIntro to Building Android Games using libGDX
Intro to Building Android Games using libGDX
 
Advanced JavaScript Development
Advanced JavaScript DevelopmentAdvanced JavaScript Development
Advanced JavaScript Development
 
Introduction to JavaScript
Introduction to JavaScriptIntroduction to JavaScript
Introduction to JavaScript
 
Introduction to AngularJS
Introduction to AngularJSIntroduction to AngularJS
Introduction to AngularJS
 
libGDX: Scene2D
libGDX: Scene2DlibGDX: Scene2D
libGDX: Scene2D
 
libGDX: Simple Frame Animation
libGDX: Simple Frame AnimationlibGDX: Simple Frame Animation
libGDX: Simple Frame Animation
 
libGDX: Simple Frame Animation
libGDX: Simple Frame AnimationlibGDX: Simple Frame Animation
libGDX: Simple Frame Animation
 
libGDX: User Input
libGDX: User InputlibGDX: User Input
libGDX: User Input
 
Implementing a Simple Game using libGDX
Implementing a Simple Game using libGDXImplementing a Simple Game using libGDX
Implementing a Simple Game using libGDX
 
Building Android games using LibGDX
Building Android games using LibGDXBuilding Android games using LibGDX
Building Android games using LibGDX
 
Creating Asha Games: Game Pausing, Orientation, Sensors and Gestures
Creating Asha Games: Game Pausing, Orientation, Sensors and GesturesCreating Asha Games: Game Pausing, Orientation, Sensors and Gestures
Creating Asha Games: Game Pausing, Orientation, Sensors and Gestures
 
Creating Games for Asha - platform
Creating Games for Asha - platformCreating Games for Asha - platform
Creating Games for Asha - platform
 
Intro to Asha UI
Intro to Asha UIIntro to Asha UI
Intro to Asha UI
 
Intro to Java ME and Asha Platform
Intro to Java ME and Asha PlatformIntro to Java ME and Asha Platform
Intro to Java ME and Asha Platform
 

Último

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 

Android Data Persistence

  • 1. Data  Persistence  in  Android   Jussi  Pohjolainen   Tampere  University  of  Applied  Sciences  
  • 2. Contents   •  Overview   •  About  State  InformaAon   •  Preferences   •  Using  files   •  Using  databases   •  Accessing  Content  Providers  
  • 3. Overview  of  Data  Storing   •  App  data  is  private  to  the  applicaAon   •  Several  mechanism   –  State  Storage:  Ram  memory!   •  Mechanism  for  saving  acAvity’s  state  temporarily   –  Preferences   •  Lightweight  mechanism  to  store  and  retrieve  key-­‐value  pairs   –  Files   •  Open  and  save  files  on  the  device  or  removable  storage   –  SQLite  databases   •  Databases   •  Content  provider  is  used  to  give  the  data  to  other  apps  
  • 4. AcAvity  State:  Using  RAM   •  AcAvity’s  state  informaAon  can  be  lost,  if  it’s   closed   – When  acAvity  is  no  longer  on  the  screen  and  it’s   closed  because  of  freeing  memory   – When  screen  rota1on  is  changed,  the  acAvity  is   destroyed  and  opened  again    
  • 5. How  to  Store  State  InformaAon   •  Store  state:   – onSaveInstanceState(Bundle) •  Read  state   – onRestoreInstanceState(Bundle) •  This  will  store  data  only  temporarily:  for  app   life1me!   •  Data  will  be  held  in  memory  un1l  the  app  is   closed!  
  • 6. Store   @Override public void onSaveInstanceState(Bundle savedInstanceState) { String text = tv.getText().toString(); savedInstanceState.putString("someKey", text); super.onSaveInstanceState(savedInstanceState); }
  • 7. Load   @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); if (savedInstanceState != null) { String strValue = savedInstanceState.getString("someKey"); if (strValue != null) { textfield.setText(strValue); } } }
  • 8. Shared  Preferences:  Permanent  Storage   •  Very  simple  way  of  share  small  amount  of   data  between  acAviAes   •  Also  for  saving  the  state  of  the  app   •  Preferences  have  names,  so  apps  other   components  can  found  them   •  Preferences  can  be  private  or  public  (world   readable,  writeable)  
  • 9. How?   •  SharedPreferences  provides  general  framework   for  saving  and  retrieving   •  To  get  SharedPreferences,  use   –  getSharedPreferences(String name) –  Use  if  you   need  mulAple  preference  files  (idenAfied  by  name)   –  getPreferences() –  Use  if  only  one  preferences  file   is  needed   •  To  write  values,  call  edit() to  get   SharedPreferences.Editor  to  be  used  when   adding  values  to  file.  
  • 10. Preferences  Example   public class Calc extends Activity {     public static final String PREFS_NAME = "MyPrefsFile";     @Override     protected void onCreate(Bundle state){        super.onCreate(state);        . . .        // Restore preferences        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);        boolean silent = settings.getBoolean("silentMode", false);     }     @Override     protected void onStop(){        super.onStop();       // We need an Editor object to make preference changes.       // All objects are from android.context.Context       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);       SharedPreferences.Editor editor = settings.edit();       editor.putBoolean("silentMode", mSilentMode);       // Commit the edits!       editor.commit();     } }
  • 11. Files   •  It's  possible  to  store  files  on  the  mobile  device  or  on  a   removable  storage   •  Current  applica1on  folder  only.  ExcepAon  thrown   otherwise.   –  Modes:  MODE_PRIVATE,  MODE_WORLD_READABLE,   MODE_WORLD_WRITABLE   •  Reading   –  openFileInput() •  WriAng   –  openFileOutput() •  Standard  Java  streams  aer  that  
  • 12. StaAc  files   •  You  can  save  staAc  files  into  res/raw  directory   •  Accessing  using   openRawResource(R.raw.<filename>) •  Returns  InputStream •  Cannot  write  to  data  
  • 13. Files   // Write String FILENAME = "hello_file"; String string = "hello world!"; FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE); fos.write(string.getBytes()); fos.close(); // Read FileInputStream fis = openFileInput(FILENAME); int byteChar; while((byteChar = fis.read()) != -1) { System.out.println((char) byteChar); } fis.close()
  • 14. Reading  MODE_WORLD_READABLE  file   •  When  reading  public  file,  use  FileInputStream   (vs.  openFileInput)   •  Give  full  path:  /data/data/<package>/files
  • 15. SQLite   •  Support  for  SQlite  databases   –  Database  is  private  to  the  applicaAon  that  creates  it   •  SQLiteDatabase  object  represents  a  database   •  SQLiteOpenHelper  –  wrapper  for  database   acAons   •  Android  SDK  has  a  tool  called  sqlite3  which   enables  you  to  browse  table  contents  using  sql   commands  and  command  line   •  All  databases  are  stored  in  /data/data/ <package_name>/databases folder  on  your   device.  
  • 16. SQLiteDatabase:  Open   public void openDatabase() { try { db = this.openOrCreateDatabase("MyTestDatabase.db", MODE_PRIVATE, null); db.execSQL("CREATE TABLE MYDATA(firstname TEXT, lastname TEXT)"); } catch (SQLiteException e) { e.printStackTrace(); } }
  • 17. SQLiteDatabase:  Insert   public void insertRows() { try { db.execSQL("INSERT INTO MYDATA VALUES ('Jack', 'Smith')"); } catch (Exception e) { e.printStackTrace(); } }
  • 18. SQLiteDatabase:  Read   public void readRows() { try { Cursor c = db.rawQuery("SELECT * FROM MYDATA", null); String text = ""; c.moveToFirst(); for(int i=0; i<c.getCount(); i++) { text += c.getString(0) + " " + c.getString(1); c.moveToNext(); } tv.setText(text); } catch (Exception e) { e.printStackTrace(); } }
  • 19. SQLiteOpenHelper   •  Wraps  best  pracAce  pacern  for  creaAng,   opening  and  upgrading  databases   •  You  hide  the  logic  used  to  decide  if  a  database   needs  to  be  created  or  upgraded  before  it's   opened  
  • 20. Recommended  Way:  SQLiteOpenHelper   public class DictionaryOpenHelper extends SQLiteOpenHelper {     private static final int DATABASE_VERSION = 2;     private static final String DICTIONARY_TABLE_NAME = "dictionary";     private static final String DICTIONARY_TABLE_CREATE =                 "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +                 KEY_WORD + " TEXT, " +                 KEY_DEFINITION + " TEXT);";     DictionaryOpenHelper(Context context) {         super(context, DATABASE_NAME, null, DATABASE_VERSION);     }     @Override     public void onCreate(SQLiteDatabase db) {         db.execSQL(DICTIONARY_TABLE_CREATE);     } }
  • 21. // Example public class SQLiteExample extends Activity { private MyDataHelper dbhelper; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); dbhelper = new MyDataHelper(this); dbhelper.deleteAll(); dbhelper.insert("Jussi"); dbhelper.insert("Pekka"); dbhelper.insert("Tiina"); List<String> list = dbhelper.selectAll(); for(String object : list) { System.out.println(object); } } }
  • 22. Remote  Shell  for  Databases  
  • 23. Content  Providers   •  The  recommended  way  of  sharing  data  in   Android  is  to  use  content  providers   •  Generic  interface  for  data   •  Permission  control  and  accessing  using  URI   model   •  NaAve  databases  available  as  Content   Providers   •  Publishing  your  own  data  source,  other  apps   can  incorporate  your  database  
  • 24. Content  Resolver   •  ApplicaAon  context  has  Content  Resolver   which  you  can  use  to  access  data   – ContentResolver cr = getContentResolver(); •  For  accessing  other  databases,  you  need  a  URI   •  URI  is  arbitraty  String,  which  is  defined  in   manifest  file  
  • 25. Usage   // Query Cursor c = getContentResolver().query(URI, ..., ... ,...); // Insert getContentResolver().insert(URI, newValues); // Delete getContentResolver().delete(URIofTheRow, ...);
  • 26. URIs   •  Content  URIs  must  be  unique  between   providers.   •  Use  your  package  name   •  General  form   –  content://com.<company>.provider.<app>/<data> •  Example  for  querying  all  items   –  content://fi.pohjolainen_jussi.provider.myapp/items •  Example  for  querying  single  item  (fih)   –  content://fi.pohjolainen_jussi.provider.myapp/items/5
  • 27. Manifest   <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="fi.tamk" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".CallMe" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <provider android:name=".Data" android:authorities="fi.pohjolainen_jussi.provider.mycontentprovider"></provider> </application> <uses-sdk android:minSdkVersion="8" /> </manifest>
  • 28. Accessing  Content  Provider   public class MyContentProvider extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ContentResolver cr = getContentResolver(); Uri uri = Uri.parse("content://fi.pohjolainen_jussi.provider.mycontentprovider"); Cursor cursor = cr.query(uri, null, null, null, null); } }
  • 29. Extend  Content  Provider   public class MyContentProvider extends ContentProvider { @Override public int delete(Uri uri, String selection, String[] selectionArgs) {...} @Override public String getType(Uri uri) {...} @Override public Uri insert(Uri uri, ContentValues values) {...} @Override public boolean onCreate() {...} @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {...} @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {...} }
  • 30. URLMatcher   •  The  content  provider  can  give  different  results   depending  on  the  URI:   – content:// fi.pohjolainen_jussi.provider.myapp/items – content:// fi.pohjolainen_jussi.provider.myapp/ items/5 •  Use  UAlity  class  URLMatcher  to  differenAate   the  given  URIs  
  • 31. Example  of  URIMatcher   public class Data extends ContentProvider { @Override public boolean onCreate() { initializeUriMatcher(); return false; } ... // Differentiate between different URI requests private static final int ALLROWS = 1; private static final int SINGLE_ROW = 2; // UriMatcher is utility class for aiding matching URIs in content providers private UriMatcher uriMatcher; private void initializeUriMatcher() { // Root node for the URI Matcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // Add a URI to match, and the code to return when this URI is matched uriMatcher.addURI("fi.pohjolainen_jussi.provider.mycontentprovider", "items", ALLROWS); uriMatcher.addURI("fi.pohjolainen_jussi.provider.mycontentprovider", "items/#", SINGLE_ROW); } }
  • 32. Example  of  URIMatcher   public class Data extends ContentProvider { @Override public boolean onCreate() { initializeUriMatcher(); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { switch(uriMatcher.match(uri)) { case SINGLE_ROW: String rowNumber = uri.getPathSegments().get(1); // .. break; case ALLROWS: // break; } return null; } }