Pages

Showing posts with label preferences. Show all posts
Showing posts with label preferences. Show all posts

Monday, March 28, 2016

Using Android Preferences

We saw before that we can persist an applications data using SQLite database. Android offers another way to store users data through using preferences.

Android preferences is a key/value entries that store data that can be specific to a certain activity or shared among all activities within the application.
the data are stored in a xml file.

Saving Preferences

We can save preferences in three ways:

  1. Preferences can be retrieved only by a single activity.
  2. Preferences can be shared and retrieved among all activities within the application.
  3. Preferences can be shared and retrieved through all applications on the device.
Saving Activity-level preferences:
to save preferences that are accessed only from a single activity, we do it like this:
SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor=prefs.edit();
editor.putString("pref 1", "some text");

editor.commit();

we get a SharedPreferences object by calling getPreferences(int mode) method which takes an integer value as a parameter, the mode value can be one of the following:

  1. Context.MODE_PRIVATE (0): a file creating mode that makes the created file only accessible by applications with the same user ID (access the file from the same application context, will desctribe later).
  2. Context.MODE_WORLD_READABLE (1): file mode makes the file readable from other applications.
  3. Context.MODE_WORLD_WRITEABLE (2): file mode allows other applications to write to the file.
then we get an instance of SharedPreferences.Editor and write the preference value with editor.putString(String key, String value) method.
shared preferences allows you to insert preferences using the following methods:
  1. editor.putBoolean(String key, boolean value).
  2. editor.putFloat(String key,float value).
  3. editor.putInt(String key, int value).
  4. editor.putLong(String key, long value)
  5. editor.putString(String key, String value)
then we call edit.commit() to save the preferences to the file. commit returns a boolean indicating the result of saving, true if successful and false if failed.

Reading preferences values:
To read preferences values:
SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE);
String val=prefs.getString("pref 1", "some text");
we use sharedpreferences.getString(String key, String defaultValue) (or get boolean/float/int) to return the value stored with a specific key or defaultValue if not found.

Saving Application-level preferences:
to save preferences that can be retrieved from all activities in the application we do it like this:
SharedPreferences prefs= getSharedPreferences("demopref", Context.MODE_WORLD_READABLE);
SharedPreferences.Editor editor=prefs.edit();
editor.putString("demostring", "hello");
editor.commit();

same as the code above, but the difference is that we give our preferences file a name (demopref in this case) so that other activities can reference that preferences file.
Sharing preferences across applications:


We can store preferences in one application and read them in another application, this is done reading the preferences file by loading them through the first applications context.

lets assume we have two applications:

  1. Application 1 with package name "com.mina.prefdemo".
  2. Application2 with package name "com.mina.demoapp".
If application1 creates a preferences file with the name "demopref" and inserts a String preference with the key/value "demostring/hello".

now we access this file and value from application 2 like this:
Context con;
try {
con = createPackageContext("com.minasamy.prefdemo", 0);
SharedPreferences pref=con.getSharedPreferences("demopref", Context.MODE_PRIVATE);
String x=pref.getString("demostring", "not found");
txt.setText(x);
} catch (NameNotFoundException e) {
Log.e(Tag, e.toString());
}

Creating Preferences Activities:
android provides another nice way of presenting and saving preferences. you can create Activities that extend PreferenceActivity.
PreferenceActivity is an activity that displays a set of built-in preferences related widgets that are defined in xml file.

the preference activity can be divided to several PreferenceCategory each containing a set of related preferences.
The preferences widgets that Android provide are:

  1. CheckBoxPreference: displays a check box widget.
  2. EditTextPreference: displays an EditText widget to save user prefs.
  3. RingtonePreference: displays a list with the  ringtones on the device.
  4. ListPreference: displays a list of key/value items.
each one of these preferences widgets is associated with a preference key. its value is persisted instantly as the widget selection changes.

we can construct our preferences screen xml (saved in res/xml directory) layout like this:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
>
<PreferenceCategory
android_title="Catogory one"
android_summary="sample summary">
<CheckBoxPreference
android_title="Enable"
android_key="pref_enable"
android_summary="enables a preference"/>
<EditTextPreference
android_summary="Edit text prefrence"
android_title="Edit"
android_key="pref_edit"/>


</PreferenceCategory>
<PreferenceCategory
android_title="Category2"
android_summary="sample summary">
<RingtonePreference
android_key="pref_ring"
android_title="Ringtones preference"/>

<ListPreference
android_key="pref_list"
android_title="List Preference"
android_dialogTitle="List Pref Dialog"
android_entries="@array/pref_items"
android_entryValues="@array/pref_items_values"/>
</PreferenceCategory>


then from our activity:
public class PrefActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);

}
}

and the activity will look like this:





the ListPreference can be associated with String array resources as its key/value entries
<string-array name="pref_items">
<item>Item1</item>
<item>Item2</item>
<item>Item3</item>
<item>Item4</item>
<item>Item5</item>
</string-array>

<string-array name="pref_items_values">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</string-array>


to reference the preference widgets programmatically:
EditTextPreference pref_edit=(EditTextPreference)findPreference("pref_edit");
Read More..

Thursday, March 3, 2016

Implicit Intent Android Tutorial for Beginners Part 3




We have seen in Part 2 how to use Explicit Intents to invoke activities through a very simple example. Now, we will move on to a more interesting concept of Implicit Intents and Intent Filters. 

This requires a little of theoretical understanding before we move on to an example. 

As described earlier, an implicit intent does not name a target component that should act upon the intent. I 
also said that the android platform resolves as to which component is best suited to respond to an Implicit Intent. How does this happen?

Basically, an Intent object has the following information (among other things like Component name, extras and flags) which is of interest for implicit intents:
  • Action
  • Category
  • Data
So, the android platform compares these 3 (action, category and data) to something called "Intent Filters" that are declared by probable target components who are willing to accept Implicit Intent calls.
i.e. Intent Filters are the way of any component to advertise its own capabilities to the Android system. This is done declaratively in the AndroidManifest.xml file.

So here are some important points to remember:
  1. Implicit Intents do not specify a target component
  2. Components willing to receive implicit intents have to declare their ability to handle a specific intent by declaring intent filters
  3. A component can declare any number of Intent Filters
  4. There can be more than one component that declares the same Intent Filters and hence can respond to the same implicit intent. In that case the user is presented both the component options and he can choose which one he wants to continue with
  5. You can set priorities for the intent filters to ensure the order of responses.
There are 3 tests conducted in order to match an intent with intent filters:
  1. Action Test
  2. Category Test
  3. Data Test
For more details about them, you may visit the Android developer documentation here.

Finally we shall look at declaring an implicit intent in one activity which will invoke one of the native activities of the platform by matching the intent filters declared by the same.

The complete code for a very simple implicit intent example that has been described in this article is available for download here.

The InvokeImplicitIntent Activity creates an implicit intent object "contacts". This intent objects component is not set. However, the action is set to "android.content.intent.ACTION_VIEW" and the datas URI is set to "People.CONTENT_URI". 

Such an intent matches with the intent filter declared by the view contacts native activity.
So, when you run this application, it displays the native UI for viewing the existing contacts on the phone!

Here is the relevant piece of code for the same:
           Button viewContacts = (Button)findViewById(R.id.ViewContacts);
        
            viewContacts.setOnClickListener(new OnClickListener() {
            
             public void onClick(View v) {
              Intent contacts = new Intent();
              contacts.setAction(android.content.Intent.ACTION_VIEW);
              contacts.setData(People.CONTENT_URI);
              startActivity(contacts);
             }
            });


In this manner many of the native applications can be seamlessly invoked as one of the activities in our applications through implicit intents.

---------------------------------------------------------------------------------------------------------
Updated on 31st March 2010:
The above example uses Android SDK 1.5.
From SDK 1.6 and above, the Contact.People class has been deprecated and we need to use the ContactsContract class. So the line in code
       contacts.setData(People.CONTENT_URI);

has to be replaced by

       contacts.setData(ContactsContract.Contacts.CONTENT_URI);

Here is the complete source code that has been tested with Android SDK 2.1

Read More..