SlideShare una empresa de Scribd logo
1 de 8
Persistent Data Storage

Android allows applications to permanently store data on the mobile device for later use and protects it from
accidental or malicious access by other programs. Saving and loading data is an essential requirement for most
applications. At a minimum, activities should save their UI state each time they move out of the foreground.
This ensures that the same UI state is presented when it’s next seen, even if the process has been killed and
restarted before that happens. It’s also likely that you’ll need to save preferences, to let users customize the
application, and persist data entered or recorded. Just as important is the ability to load data from files,
databases, or Content Providers.

An application can store data using several techniques depending on the size of the data, its structure, its
lifetime, and whether it will be shared with other programs.
     1. Preferences are a simple, lightweight key/value pair mechanism for saving primitive application data,
         most commonly UI state, user preferences, or application settings.
     2. Android also provides access to the local file system, both through specialized methods and the normal
         Java.IO classes.
     3. For a more robust persistence layer, Android provides the SQLite database library. The SQLite
         relational database offers a powerful native SQL database over which you have total control.
     4. Content Providers offer a generic interface to any data source. They effectively decouple the underlying
         data storage technique from the application layer. They let you expose a well-defined interface for using
         and sharing private data.

By default, access to all files, databases, and preferences is restricted to the application that created them.
Content Providers offer a managed way for your applications to share private data with other applications. As a
result, your applications can use the Content Providers offered by others, including native providers.

There are two lightweight techniques for saving simple application data for Android applications: (1) Shared
Preferences and (2) a pair of event handlers used for saving the details of an Activity instance. Both mechanisms
use a name-value pair mechanism to store simple primitive values.
  1. Shared Preferences support the primitive types boolean, float, long, int, and String making
      them an ideal way to quickly store default values, class instance variables, the current UI state, and user
      preferences. They are most commonly used to persist data across user sessions and to share settings
      between application components.
  2. Alternatively, Activities offer the onSaveInstanceState handler. It’s designed specifically to persist
      the UI state when the Activity becomes eligible for termination by a resource-hungry run time. The
      handler works like the Shared Preference mechanism. It offers a Bundle parameter that represents a key/
      value map of primitive types that can be used to save the Activity’s instance values. This Bundle is then
      made available as a parameter passed in to the onCreate() and onRestoreInstanceState()
      method handlers. This UI state Bundle is used to record the values needed for an Activity to provide an
      identical UI following unexpected restarts.

1. Shared Preferences

Shared preferences are preferences that are shared between all activities of an application and can be managed
with the help of the getSharedPreferences() method of the Context class. This method takes two
arguments, the name of the set of shared preferences and the operating mode. MODE_PRIVATE is the default
operating mode and means the created set of preferences can be accessed only by the application that created it.
Basically, the shared preferences are shared across the application’s components but aren’t available to other
applications. The getSharedPreferences() method returns a SharedPreferences object that holds
the contents of the specified preference set through which you can retrieve or modify the preference values.
public static final String PREF_SET_NAME = "PrefSet";

 SharedPreferences preferences = getSharedPreferences(PREF_SET_NAME,MODE_PRIVATE);

Remark: Note that if several application components call the getSharedPreferences() method with the
same preference set name, then the same SharedPreferences object is returned to all callers (meaning they
will see each other's edits as soon as they are made).

To edit/modify a shared preference, use the SharedPreferences.Editor class. Get the Editor object
by calling edit() on the SharedPreferences object you want to change and then use mutators/setters
put<type> to save value of specific types. To save edits, call commit() on the Editor, as illustrated in the
following generic example.

 SharedPreferences.Editor editor = preferences.edit();
 editor.putInt("key1", int_value);
 editor.putString("key2", string_value);
 editor.commit();

To access/retrieve saved shared preferences use the type-safe get<type> methods. Each getter takes a key and a
default value (used when no value is available for that key).

 int value1 = preferences.getInt("key1", 0);
 String value2 = preferences.getString("key2", "abc");

If a preference does not need to be shared across multiple components of an application, but is needed only by
one Activity for example, then you can use the getPreferences() method of the Activity class (instead
of the getSharedPreferences() method of the Context class). The getPreferences() method
invokes the getSharedPreferences() method with the name of the activity class as the name for that set
of preferences. The code to modify and access these preferences (called activity preferences) is the same as for
shared preferences.

1.1. Implementing the Continue Game option using Preferences

We will illustrate the use of activity preferences by implementing the option to continue an old game in our
Sudoku application. A player can decide to quit playing a Sudoku game at any point in time. To allow the player
to come back later and continue where they left off, we first need to save the current state of the puzzle (i.e., the
numbers in each of the 9x9 = 81 tiles) whenever the game is paused. Therefore, in the onPause() method of
the Game activity, we first concatenate the numbers from the 81 tiles into a string, using method
toPuzzleString() and then store the value of this string paired with a key into the shared preferences. In
our code below we use the constant "puzzle" as the key.

     private static final String PREF_PUZZLE = "puzzle" ;

     @Override
     protected void onPause() {
        super.onPause();

         // Save the current puzzle
         String s = toPuzzleString(puzzle);
         getPreferences(MODE_PRIVATE).edit().putString(PREF_PUZZLE, s).commit();
     }
Now that the puzzle is saved, in order to read it when needed, we will just modify method getPuzzle(),
which loads a puzzle (according to the difficulty level selected by the player). All we need to do is use a flag,
for example -1, to indicate that the puzzle saved in the preferences should be loaded (instead of starting a new
puzzle of a certain difficulty level).

    /** Given a difficulty level, come up with a new puzzle */
     private int[] getPuzzle(int diff) {
        String puz;
        switch (diff) {
          case -1: puz = getPreferences(MODE_PRIVATE).getString(PREF_PUZZLE,
                    easyPuzzle);
                    break;
           case 0: puz = hardPuzzle;
                    break;
           case 1: puz = mediumPuzzle;
                    break;
           case 2:
           default: puz = easyPuzzle;
                    break;
        }
        return fromPuzzleString(puz);
     }

Now when player chooses the option to continue an old game, we can call the same method used for starting a
new game, startGame(), but passing it -1 instead of a difficulty level (0, 1 or 2) to indicate that the puzzle
to be loaded is the one stored in preferences.

 public class Sudoku extends Activity implements OnClickListener {

     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

         // Set up click listeners for all the buttons
         View continueButton = this.findViewById(R.id.continue_button);
         continueButton.setOnClickListener(this);
         View newButton = this.findViewById(R.id.new_button);
         newButton.setOnClickListener(this);
         View aboutButton = this.findViewById(R.id.about_button);
         aboutButton.setOnClickListener(this);
         View exitButton = this.findViewById(R.id.exit_button);
         exitButton.setOnClickListener(this);
     }

     public void onClick(View v) {
        switch (v.getId()) {
        case R.id.continue_button:
           startGame(-1);
           break;
        case R.id.about_button:
           Intent i = new Intent(this, About.class);
           startActivity(i);
           break;
        case R.id.new_button:
           openNewGameDialog();
break;
         case R.id.exit_button:
            finish();
            break;
         }
     }

     /** Start a new game with the given difficulty level */
     private void startGame(int i) {
        Intent intent = new Intent(Sudoku.this, Game.class);
        intent.putExtra(Game.KEY_DIFFICULTY, i);
        startActivity(intent);
     }
 }

2. Storing the State of an Activity Instance

To save Activity instance variables, Android offers a specialized alternative to preferences. By overriding an
Activity’s onSaveInstanceState event handler, you can use its Bundle parameter to save instance
values. Values are stored/retrieved to/from this Bundle object using the same get and put methods as shown
for preferences. This handler will be triggered whenever an Activity completes its active life cycle, but only
when it’s not being explicitly finished. As a result, it’s used to ensure a consistent Activity state between active
life cycles of a single user session. The saved Bundle is passed in to the onRestoreInstanceState()
and onCreate() methods if the application is forced to restart during a session.

2.1. Remembering the Selected Tile when Screen Orientation Changes

We will illustrate how to use the onSaveInstanceState event handler to remember the current position of
the selected tile when the player changes the screen orientation while Sudoku is running. In this case, we need to
store the values of data fields selX and selY (indicating the selected tile) from the PuzzleView class. Thus,
as for shared preferences we first define two constants "selX" and "selY" as keys for the values to be stored.
Note that normally, Android views save their state automatically, but since we made our own view, we don’t get
that for free.

Notice that the PuzzleView class is a View (not an Activity). The View class also has a
onSaveInstanceState()                  method   that     is       invoked        automatically    by     the
Activity.onSaveInstanceState() method for every hosted view that has an ID. Normally, this ID
would come from XML, but since PuzzleView was created in code, we need to set it ourselves. Thus, we
make up an arbitrary number (any value will work as long as it is positive) and then use the setId() method
to assign it to our view in the constructor.

In the onSaveInstanceState() method we call the superclass to get its state, and then save it plus the
additional value-key pairs in a Bundle object. Later, onRestoreInstanceState() will be called to read
the information we saved. We get our own x and y positions from the Bundle, and then we call the superclass to
let it get whatever it needs.

 public class PuzzleView          extends View {
    private int selX;                // X index of selection
    private int selY;                // Y index of selection
    …
    private static final          String    SELX = "selX";
    private static final          String    SELY = "selY";
    private static final          String    VIEW_STATE = "viewState";
    private static final          int ID    = 42;
public PuzzleView(Context context) {
        ...
        setId(ID);
     }

     @Override
     protected Parcelable onSaveInstanceState() {
        Parcelable p = super.onSaveInstanceState();
        Bundle bundle = new Bundle();
        bundle.putInt(SELX, selX);
        bundle.putInt(SELY, selY);
        bundle.putParcelable(VIEW_STATE, p);
        return bundle;
     }

     @Override
     protected void onRestoreInstanceState(Parcelable state) {
        Bundle bundle = (Bundle) state;
        select(bundle.getInt(SELX), bundle.getInt(SELY));
        super.onRestoreInstanceState(bundle.getParcelable(VIEW_STATE));
        return;
     }
 }

3. Describing Application Preferences/Settings using XML files

Beginning with the 0.9 SDK, Android has introduced a framework for managing application
preferences/settings. This framework does not change anything shown above. Instead, the framework is more
for presenting a consistent set of preference-setting options for users, so different applications do not have to
"reinvent the wheel". Basically, the framework allows you to describe an application's preferences/settings in an
XML file stored in your project's res/xml/ directory. Given that, Android can present a pleasant user UI for
manipulating those preferences, which are then stored in a SharedPreferences object, which can be
obtained through the getDefaultSharedPreferences() method of the PreferencesManager
class. This method is similar to getPreferences() and getSharedPreferences(), in the sense that
it returns a SharedPreferences object which offers a series of type-safe getters to access preference
values.

We illustrate an XML file containing application preferences with our Sudoku example. In Sudoku the user has
the option to have music playing while he is playing the game. This application setting is described in the
following XML file.

res/xml/settings.xml
 <?xml version="1.0" encoding="utf-8"?>
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
       android:key="music"
       android:title="@string/music_title"
       android:summary="@string/music_summary"
       android:defaultValue="true" />
 </PreferenceScreen>

Note that music_title and music_summary are defined in the res/values/strings.xml
     ...
     <string name="music_title">Music</string>
<string name="music_summary">Play background music</string>
     ...
The root of the preference XML document is a PreferenceScreen element. Inside a
PreferenceScreen element you can have preference definitions. These are subclasses of Preference,
such as CheckBoxPreference as shown above, which allows you to check a checkbox.

Once you have set up your preference XML, you can use a nearly-built-in activity for allowing your users to set
their preferences. The activity is "nearly-built-in" because you need to subclass it to point it to your preference
XML, plus hook it into the rest of your application. For our Sudoku example, let’s call this activity Settings.

 public class Settings extends PreferenceActivity {

     // Options names and default values
     private static final String OPT_MUSIC = "music";
     private static final boolean OPT_MUSIC_DEF = true;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
     }

     /** Get the current value of the music option */
     public static boolean getMusic(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context)
              .getBoolean(OPT_MUSIC, OPT_MUSIC_DEF);
     }
 }

As you can see, all you need to do is extend the PreferenceActivity class and, in the onCreate()
method, call the addPreferencesFromResource() method specifying the XML resource containing
your preferences (in our example, R.xml.settings).

Note: Do not forget to add this activity to your AndroidManifest.xml file.

Now we have to link this activity with the rest of the Sudoku application. Specifically, we have to invoke this
activity (through an Intent) when the user presses the Menu button.

 public class Sudoku extends Activity implements OnClickListener {
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
       super.onCreateOptionsMenu(menu);
       MenuInflater inflater = getMenuInflater();
       inflater.inflate(R.menu.menu, menu);
       return true;
    }

     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.settings:
           startActivity(new Intent(this, Settings.class));
           return true;
        }
        return false;
     }
}




If you have a lot of preferences for users to set, having them all in one big list may become troublesome.
Android's preference framework gives you a few ways to impose a bit of structure on your bag of preferences,
including categories and screens. Categories are added via a PreferenceCategory element in your
preference XML and are used to group together related preferences. Rather than have your preferences all as
children of the root PreferenceScreen, you can put a few PreferenceCategory elements in the
PreferenceScreen, and then put your preferences in their appropriate categories. Visually, this adds a
divider with the category title between groups of preferences. If you have lots and lots of preferences – more
than is convenient for users to scroll through – you can also put them on separate "screens" by introducing the
PreferenceScreen element. Any children of PreferenceScreen go on their own screen. If you nest
PreferenceScreens, the parent screen displays the screen as a placeholder entry – tapping that entry brings
up the child screen. For example, here is a preference XML file that contains both PreferenceCategory
and nested PreferenceScreen elements.

 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
   <PreferenceCategory android:title="Simple Preferences">
     <CheckBoxPreference
       android:key="@string/checkbox"
       android:title="Checkbox Preference"
       android:summary="Check it on, check it off"
/>
     <RingtonePreference
        android:key="@string/ringtone"
        android:title="Ringtone Preference"
        android:showDefault="true"
        android:showSilent="true"
        android:summary="Pick a tone, any tone"
     />
   </PreferenceCategory>
   <PreferenceCategory android:title="Detail Screens">
     <PreferenceScreen
        android:key="detail"
        android:title="Detail Screen"
        android:summary="Additional preferences held in another page">
        <CheckBoxPreference
           android:key="@string/checkbox2"
           android:title="Another Checkbox"
           android:summary="On. Off. It really doesn't matter."
        />
     </PreferenceScreen>
   </PreferenceCategory>
 </PreferenceScreen>

If you tap on the Detail Screen entry, you are taken to the child preference screen:

Más contenido relacionado

La actualidad más candente

04 programmation mobile - android - (db, receivers, services...)
04 programmation mobile - android - (db, receivers, services...)04 programmation mobile - android - (db, receivers, services...)
04 programmation mobile - android - (db, receivers, services...)TECOS
 
Annihilate test smells by refactoring to patterns
Annihilate test smells by refactoring to patternsAnnihilate test smells by refactoring to patterns
Annihilate test smells by refactoring to patternscenny2
 
Strategies for Mitigating Complexity in React Based Redux Applicaitons
Strategies for Mitigating Complexity in React Based Redux ApplicaitonsStrategies for Mitigating Complexity in React Based Redux Applicaitons
Strategies for Mitigating Complexity in React Based Redux Applicaitonsgarbles
 
Tk2323 lecture 3 intent
Tk2323 lecture 3   intentTk2323 lecture 3   intent
Tk2323 lecture 3 intentMengChun Lam
 
JAVA GUI PART III
JAVA GUI PART IIIJAVA GUI PART III
JAVA GUI PART IIIOXUS 20
 
Advance Java Programming (CM5I) 2.Swing
Advance Java Programming (CM5I) 2.SwingAdvance Java Programming (CM5I) 2.Swing
Advance Java Programming (CM5I) 2.SwingPayal Dungarwal
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New EvolutionAllan Huang
 

La actualidad más candente (9)

04 programmation mobile - android - (db, receivers, services...)
04 programmation mobile - android - (db, receivers, services...)04 programmation mobile - android - (db, receivers, services...)
04 programmation mobile - android - (db, receivers, services...)
 
Graphical User Components Part 2
Graphical User Components Part 2Graphical User Components Part 2
Graphical User Components Part 2
 
Annihilate test smells by refactoring to patterns
Annihilate test smells by refactoring to patternsAnnihilate test smells by refactoring to patterns
Annihilate test smells by refactoring to patterns
 
Strategies for Mitigating Complexity in React Based Redux Applicaitons
Strategies for Mitigating Complexity in React Based Redux ApplicaitonsStrategies for Mitigating Complexity in React Based Redux Applicaitons
Strategies for Mitigating Complexity in React Based Redux Applicaitons
 
Tk2323 lecture 3 intent
Tk2323 lecture 3   intentTk2323 lecture 3   intent
Tk2323 lecture 3 intent
 
Advance JFACE
Advance JFACEAdvance JFACE
Advance JFACE
 
JAVA GUI PART III
JAVA GUI PART IIIJAVA GUI PART III
JAVA GUI PART III
 
Advance Java Programming (CM5I) 2.Swing
Advance Java Programming (CM5I) 2.SwingAdvance Java Programming (CM5I) 2.Swing
Advance Java Programming (CM5I) 2.Swing
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New Evolution
 

Destacado

Destacado (6)

Cross platform-mobile-applications
Cross platform-mobile-applicationsCross platform-mobile-applications
Cross platform-mobile-applications
 
JAVA 2 EE
JAVA 2 EEJAVA 2 EE
JAVA 2 EE
 
Android UI
Android UI Android UI
Android UI
 
Manual reportes jsp
Manual reportes jspManual reportes jsp
Manual reportes jsp
 
Jsp
JspJsp
Jsp
 
Java Persistence Api (Jpa)
Java Persistence Api (Jpa)Java Persistence Api (Jpa)
Java Persistence Api (Jpa)
 

Similar a Data Storage

Android Training (Storing & Shared Preferences)
Android Training (Storing & Shared Preferences)Android Training (Storing & Shared Preferences)
Android Training (Storing & Shared Preferences)Khaled Anaqwa
 
Android Workshop 2013
Android Workshop 2013Android Workshop 2013
Android Workshop 2013Junda Ong
 
Data Storage In Android
Data Storage In Android Data Storage In Android
Data Storage In Android Aakash Ugale
 
Lab 8 User-CF Recommender System – Part I 50 points .docx
Lab 8 User-CF Recommender System – Part I 50 points .docxLab 8 User-CF Recommender System – Part I 50 points .docx
Lab 8 User-CF Recommender System – Part I 50 points .docxsmile790243
 
Oleksandr Tolstykh
Oleksandr TolstykhOleksandr Tolstykh
Oleksandr TolstykhCodeFest
 
Android tutorial (2)
Android tutorial (2)Android tutorial (2)
Android tutorial (2)Kumar
 
Anatomy of android application
Anatomy of android applicationAnatomy of android application
Anatomy of android applicationNikunj Dhameliya
 
Android webinar class_3
Android webinar class_3Android webinar class_3
Android webinar class_3Edureka!
 
02 hello world - Android
02   hello world - Android02   hello world - Android
02 hello world - AndroidWingston
 
Chapter 7 - Defining Your Own Classes - Part II
Chapter 7 - Defining Your Own Classes - Part IIChapter 7 - Defining Your Own Classes - Part II
Chapter 7 - Defining Your Own Classes - Part IIEduardo Bergavera
 
Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)Pinaki Poddar
 
Java căn bản - Chapter7
Java căn bản - Chapter7Java căn bản - Chapter7
Java căn bản - Chapter7Vince Vo
 
Android App Development - 06 Fragments
Android App Development - 06 FragmentsAndroid App Development - 06 Fragments
Android App Development - 06 FragmentsDiego Grancini
 

Similar a Data Storage (20)

Android
AndroidAndroid
Android
 
Android Training (Storing & Shared Preferences)
Android Training (Storing & Shared Preferences)Android Training (Storing & Shared Preferences)
Android Training (Storing & Shared Preferences)
 
Lesson 4
Lesson 4Lesson 4
Lesson 4
 
Android Workshop 2013
Android Workshop 2013Android Workshop 2013
Android Workshop 2013
 
Android Basic Components
Android Basic ComponentsAndroid Basic Components
Android Basic Components
 
Data Storage In Android
Data Storage In Android Data Storage In Android
Data Storage In Android
 
Lab 8 User-CF Recommender System – Part I 50 points .docx
Lab 8 User-CF Recommender System – Part I 50 points .docxLab 8 User-CF Recommender System – Part I 50 points .docx
Lab 8 User-CF Recommender System – Part I 50 points .docx
 
Lesson 3
Lesson 3Lesson 3
Lesson 3
 
Oleksandr Tolstykh
Oleksandr TolstykhOleksandr Tolstykh
Oleksandr Tolstykh
 
Android tutorial (2)
Android tutorial (2)Android tutorial (2)
Android tutorial (2)
 
Anatomy of android application
Anatomy of android applicationAnatomy of android application
Anatomy of android application
 
Android webinar class_3
Android webinar class_3Android webinar class_3
Android webinar class_3
 
Activity & Shared Preference
Activity & Shared PreferenceActivity & Shared Preference
Activity & Shared Preference
 
02 hello world - Android
02   hello world - Android02   hello world - Android
02 hello world - Android
 
Chapter 7 - Defining Your Own Classes - Part II
Chapter 7 - Defining Your Own Classes - Part IIChapter 7 - Defining Your Own Classes - Part II
Chapter 7 - Defining Your Own Classes - Part II
 
Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)Slice for Distributed Persistence (JavaOne 2010)
Slice for Distributed Persistence (JavaOne 2010)
 
Android - Saving data
Android - Saving dataAndroid - Saving data
Android - Saving data
 
Java căn bản - Chapter7
Java căn bản - Chapter7Java căn bản - Chapter7
Java căn bản - Chapter7
 
Android intents in android application-chapter7
Android intents in android application-chapter7Android intents in android application-chapter7
Android intents in android application-chapter7
 
Android App Development - 06 Fragments
Android App Development - 06 FragmentsAndroid App Development - 06 Fragments
Android App Development - 06 Fragments
 

Último

H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 

Último (20)

H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 

Data Storage

  • 1. Persistent Data Storage Android allows applications to permanently store data on the mobile device for later use and protects it from accidental or malicious access by other programs. Saving and loading data is an essential requirement for most applications. At a minimum, activities should save their UI state each time they move out of the foreground. This ensures that the same UI state is presented when it’s next seen, even if the process has been killed and restarted before that happens. It’s also likely that you’ll need to save preferences, to let users customize the application, and persist data entered or recorded. Just as important is the ability to load data from files, databases, or Content Providers. An application can store data using several techniques depending on the size of the data, its structure, its lifetime, and whether it will be shared with other programs. 1. Preferences are a simple, lightweight key/value pair mechanism for saving primitive application data, most commonly UI state, user preferences, or application settings. 2. Android also provides access to the local file system, both through specialized methods and the normal Java.IO classes. 3. For a more robust persistence layer, Android provides the SQLite database library. The SQLite relational database offers a powerful native SQL database over which you have total control. 4. Content Providers offer a generic interface to any data source. They effectively decouple the underlying data storage technique from the application layer. They let you expose a well-defined interface for using and sharing private data. By default, access to all files, databases, and preferences is restricted to the application that created them. Content Providers offer a managed way for your applications to share private data with other applications. As a result, your applications can use the Content Providers offered by others, including native providers. There are two lightweight techniques for saving simple application data for Android applications: (1) Shared Preferences and (2) a pair of event handlers used for saving the details of an Activity instance. Both mechanisms use a name-value pair mechanism to store simple primitive values. 1. Shared Preferences support the primitive types boolean, float, long, int, and String making them an ideal way to quickly store default values, class instance variables, the current UI state, and user preferences. They are most commonly used to persist data across user sessions and to share settings between application components. 2. Alternatively, Activities offer the onSaveInstanceState handler. It’s designed specifically to persist the UI state when the Activity becomes eligible for termination by a resource-hungry run time. The handler works like the Shared Preference mechanism. It offers a Bundle parameter that represents a key/ value map of primitive types that can be used to save the Activity’s instance values. This Bundle is then made available as a parameter passed in to the onCreate() and onRestoreInstanceState() method handlers. This UI state Bundle is used to record the values needed for an Activity to provide an identical UI following unexpected restarts. 1. Shared Preferences Shared preferences are preferences that are shared between all activities of an application and can be managed with the help of the getSharedPreferences() method of the Context class. This method takes two arguments, the name of the set of shared preferences and the operating mode. MODE_PRIVATE is the default operating mode and means the created set of preferences can be accessed only by the application that created it. Basically, the shared preferences are shared across the application’s components but aren’t available to other applications. The getSharedPreferences() method returns a SharedPreferences object that holds the contents of the specified preference set through which you can retrieve or modify the preference values.
  • 2. public static final String PREF_SET_NAME = "PrefSet"; SharedPreferences preferences = getSharedPreferences(PREF_SET_NAME,MODE_PRIVATE); Remark: Note that if several application components call the getSharedPreferences() method with the same preference set name, then the same SharedPreferences object is returned to all callers (meaning they will see each other's edits as soon as they are made). To edit/modify a shared preference, use the SharedPreferences.Editor class. Get the Editor object by calling edit() on the SharedPreferences object you want to change and then use mutators/setters put<type> to save value of specific types. To save edits, call commit() on the Editor, as illustrated in the following generic example. SharedPreferences.Editor editor = preferences.edit(); editor.putInt("key1", int_value); editor.putString("key2", string_value); editor.commit(); To access/retrieve saved shared preferences use the type-safe get<type> methods. Each getter takes a key and a default value (used when no value is available for that key). int value1 = preferences.getInt("key1", 0); String value2 = preferences.getString("key2", "abc"); If a preference does not need to be shared across multiple components of an application, but is needed only by one Activity for example, then you can use the getPreferences() method of the Activity class (instead of the getSharedPreferences() method of the Context class). The getPreferences() method invokes the getSharedPreferences() method with the name of the activity class as the name for that set of preferences. The code to modify and access these preferences (called activity preferences) is the same as for shared preferences. 1.1. Implementing the Continue Game option using Preferences We will illustrate the use of activity preferences by implementing the option to continue an old game in our Sudoku application. A player can decide to quit playing a Sudoku game at any point in time. To allow the player to come back later and continue where they left off, we first need to save the current state of the puzzle (i.e., the numbers in each of the 9x9 = 81 tiles) whenever the game is paused. Therefore, in the onPause() method of the Game activity, we first concatenate the numbers from the 81 tiles into a string, using method toPuzzleString() and then store the value of this string paired with a key into the shared preferences. In our code below we use the constant "puzzle" as the key. private static final String PREF_PUZZLE = "puzzle" ; @Override protected void onPause() { super.onPause(); // Save the current puzzle String s = toPuzzleString(puzzle); getPreferences(MODE_PRIVATE).edit().putString(PREF_PUZZLE, s).commit(); }
  • 3. Now that the puzzle is saved, in order to read it when needed, we will just modify method getPuzzle(), which loads a puzzle (according to the difficulty level selected by the player). All we need to do is use a flag, for example -1, to indicate that the puzzle saved in the preferences should be loaded (instead of starting a new puzzle of a certain difficulty level). /** Given a difficulty level, come up with a new puzzle */ private int[] getPuzzle(int diff) { String puz; switch (diff) { case -1: puz = getPreferences(MODE_PRIVATE).getString(PREF_PUZZLE, easyPuzzle); break; case 0: puz = hardPuzzle; break; case 1: puz = mediumPuzzle; break; case 2: default: puz = easyPuzzle; break; } return fromPuzzleString(puz); } Now when player chooses the option to continue an old game, we can call the same method used for starting a new game, startGame(), but passing it -1 instead of a difficulty level (0, 1 or 2) to indicate that the puzzle to be loaded is the one stored in preferences. public class Sudoku extends Activity implements OnClickListener { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Set up click listeners for all the buttons View continueButton = this.findViewById(R.id.continue_button); continueButton.setOnClickListener(this); View newButton = this.findViewById(R.id.new_button); newButton.setOnClickListener(this); View aboutButton = this.findViewById(R.id.about_button); aboutButton.setOnClickListener(this); View exitButton = this.findViewById(R.id.exit_button); exitButton.setOnClickListener(this); } public void onClick(View v) { switch (v.getId()) { case R.id.continue_button: startGame(-1); break; case R.id.about_button: Intent i = new Intent(this, About.class); startActivity(i); break; case R.id.new_button: openNewGameDialog();
  • 4. break; case R.id.exit_button: finish(); break; } } /** Start a new game with the given difficulty level */ private void startGame(int i) { Intent intent = new Intent(Sudoku.this, Game.class); intent.putExtra(Game.KEY_DIFFICULTY, i); startActivity(intent); } } 2. Storing the State of an Activity Instance To save Activity instance variables, Android offers a specialized alternative to preferences. By overriding an Activity’s onSaveInstanceState event handler, you can use its Bundle parameter to save instance values. Values are stored/retrieved to/from this Bundle object using the same get and put methods as shown for preferences. This handler will be triggered whenever an Activity completes its active life cycle, but only when it’s not being explicitly finished. As a result, it’s used to ensure a consistent Activity state between active life cycles of a single user session. The saved Bundle is passed in to the onRestoreInstanceState() and onCreate() methods if the application is forced to restart during a session. 2.1. Remembering the Selected Tile when Screen Orientation Changes We will illustrate how to use the onSaveInstanceState event handler to remember the current position of the selected tile when the player changes the screen orientation while Sudoku is running. In this case, we need to store the values of data fields selX and selY (indicating the selected tile) from the PuzzleView class. Thus, as for shared preferences we first define two constants "selX" and "selY" as keys for the values to be stored. Note that normally, Android views save their state automatically, but since we made our own view, we don’t get that for free. Notice that the PuzzleView class is a View (not an Activity). The View class also has a onSaveInstanceState() method that is invoked automatically by the Activity.onSaveInstanceState() method for every hosted view that has an ID. Normally, this ID would come from XML, but since PuzzleView was created in code, we need to set it ourselves. Thus, we make up an arbitrary number (any value will work as long as it is positive) and then use the setId() method to assign it to our view in the constructor. In the onSaveInstanceState() method we call the superclass to get its state, and then save it plus the additional value-key pairs in a Bundle object. Later, onRestoreInstanceState() will be called to read the information we saved. We get our own x and y positions from the Bundle, and then we call the superclass to let it get whatever it needs. public class PuzzleView extends View { private int selX; // X index of selection private int selY; // Y index of selection … private static final String SELX = "selX"; private static final String SELY = "selY"; private static final String VIEW_STATE = "viewState"; private static final int ID = 42;
  • 5. public PuzzleView(Context context) { ... setId(ID); } @Override protected Parcelable onSaveInstanceState() { Parcelable p = super.onSaveInstanceState(); Bundle bundle = new Bundle(); bundle.putInt(SELX, selX); bundle.putInt(SELY, selY); bundle.putParcelable(VIEW_STATE, p); return bundle; } @Override protected void onRestoreInstanceState(Parcelable state) { Bundle bundle = (Bundle) state; select(bundle.getInt(SELX), bundle.getInt(SELY)); super.onRestoreInstanceState(bundle.getParcelable(VIEW_STATE)); return; } } 3. Describing Application Preferences/Settings using XML files Beginning with the 0.9 SDK, Android has introduced a framework for managing application preferences/settings. This framework does not change anything shown above. Instead, the framework is more for presenting a consistent set of preference-setting options for users, so different applications do not have to "reinvent the wheel". Basically, the framework allows you to describe an application's preferences/settings in an XML file stored in your project's res/xml/ directory. Given that, Android can present a pleasant user UI for manipulating those preferences, which are then stored in a SharedPreferences object, which can be obtained through the getDefaultSharedPreferences() method of the PreferencesManager class. This method is similar to getPreferences() and getSharedPreferences(), in the sense that it returns a SharedPreferences object which offers a series of type-safe getters to access preference values. We illustrate an XML file containing application preferences with our Sudoku example. In Sudoku the user has the option to have music playing while he is playing the game. This application setting is described in the following XML file. res/xml/settings.xml <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <CheckBoxPreference android:key="music" android:title="@string/music_title" android:summary="@string/music_summary" android:defaultValue="true" /> </PreferenceScreen> Note that music_title and music_summary are defined in the res/values/strings.xml ... <string name="music_title">Music</string>
  • 6. <string name="music_summary">Play background music</string> ... The root of the preference XML document is a PreferenceScreen element. Inside a PreferenceScreen element you can have preference definitions. These are subclasses of Preference, such as CheckBoxPreference as shown above, which allows you to check a checkbox. Once you have set up your preference XML, you can use a nearly-built-in activity for allowing your users to set their preferences. The activity is "nearly-built-in" because you need to subclass it to point it to your preference XML, plus hook it into the rest of your application. For our Sudoku example, let’s call this activity Settings. public class Settings extends PreferenceActivity { // Options names and default values private static final String OPT_MUSIC = "music"; private static final boolean OPT_MUSIC_DEF = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings); } /** Get the current value of the music option */ public static boolean getMusic(Context context) { return PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(OPT_MUSIC, OPT_MUSIC_DEF); } } As you can see, all you need to do is extend the PreferenceActivity class and, in the onCreate() method, call the addPreferencesFromResource() method specifying the XML resource containing your preferences (in our example, R.xml.settings). Note: Do not forget to add this activity to your AndroidManifest.xml file. Now we have to link this activity with the rest of the Sudoku application. Specifically, we have to invoke this activity (through an Intent) when the user presses the Menu button. public class Sudoku extends Activity implements OnClickListener { @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.settings: startActivity(new Intent(this, Settings.class)); return true; } return false; }
  • 7. } If you have a lot of preferences for users to set, having them all in one big list may become troublesome. Android's preference framework gives you a few ways to impose a bit of structure on your bag of preferences, including categories and screens. Categories are added via a PreferenceCategory element in your preference XML and are used to group together related preferences. Rather than have your preferences all as children of the root PreferenceScreen, you can put a few PreferenceCategory elements in the PreferenceScreen, and then put your preferences in their appropriate categories. Visually, this adds a divider with the category title between groups of preferences. If you have lots and lots of preferences – more than is convenient for users to scroll through – you can also put them on separate "screens" by introducing the PreferenceScreen element. Any children of PreferenceScreen go on their own screen. If you nest PreferenceScreens, the parent screen displays the screen as a placeholder entry – tapping that entry brings up the child screen. For example, here is a preference XML file that contains both PreferenceCategory and nested PreferenceScreen elements. <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="Simple Preferences"> <CheckBoxPreference android:key="@string/checkbox" android:title="Checkbox Preference" android:summary="Check it on, check it off"
  • 8. /> <RingtonePreference android:key="@string/ringtone" android:title="Ringtone Preference" android:showDefault="true" android:showSilent="true" android:summary="Pick a tone, any tone" /> </PreferenceCategory> <PreferenceCategory android:title="Detail Screens"> <PreferenceScreen android:key="detail" android:title="Detail Screen" android:summary="Additional preferences held in another page"> <CheckBoxPreference android:key="@string/checkbox2" android:title="Another Checkbox" android:summary="On. Off. It really doesn't matter." /> </PreferenceScreen> </PreferenceCategory> </PreferenceScreen> If you tap on the Detail Screen entry, you are taken to the child preference screen: