The Android File System - PowerPoint PPT Presentation

About This Presentation
Title:

The Android File System

Description:

The Android File System Onboard: Linux Architecture User privileges Initially quite limited; some directories hidden Rooting gives users super user access – PowerPoint PPT presentation

Number of Views:533
Avg rating:3.0/5.0
Slides: 62
Provided by: Itinstaller
Learn more at: http://cs.sou.edu
Category:

less

Transcript and Presenter's Notes

Title: The Android File System


1
The Android File System
  • Onboard Linux Architecture
  • User privileges
  • Initially quite limited some directories hidden
  • Rooting gives users super user access
  • Procedure is different for different devices
  • Destroying the operation of the device bricking
  • Onboard data Applications have their reserved
    storage areas (sandbox)
  • External data
  • SD card or USB connection
  • Public shared /mnt/sdcard/
  • Writing to external storage has no security
    protection

2
Managing Data (Alternatives)
  • Application Direct Access Read only from res/raw
    or assets directories
  • Web-based Interact through web-URLs to access
    cloud-based data
  • Direct File I/O Read/write files onboard or on
    SD cards
  • Use Standard Java stream and Random Access File
    classes
  • Restriction Onboard file I/O restricted to
    application sandbox
  • Restriction SD card writes requires access
    permission
  • Preferences Key/Value pairs of data
  • Database Tables Use the built-in SQL-Lite
    database facility
  • Increase functionality
  • Content Providers expose data to other
    applications
  • Services background processes that run detached
    from any view

3
Application Direct Access
  • Static application files
  • Custom codecs that are not widely supported
  • XML-based configuration data
  • Store either in res/raw or in assets
  • res/raw enables creating sub-directories for
    specific device configurations
  • Files stored either in res/raw or in assets are
    not pre-compiled by Android
  • Files stored directly in the application are
    read-only and cannot be modified
  • Access using standard Java I/O operationsInputSt
    ream is app.getResources().openRawResource(R.raw
    .foo) in BufferedReader in new
    BufferedReader(new InputStreamReader(is)))Input
    Stream rawRes context.getAssets().open(foo.bar"
    ) Reader r new BufferedReader(new
    InputStreamReader(rawRes, "UTF8"))

Note Use lower case alphanumerics to name files
in res/raw
4
Downloading Files
  • Downloading quickly degrades battery life
  • Solutions
  • Pre-fetch A single large download has less
    impact than multiple smaller downloads
  • Reuse existing connections rather than
    reestablishing them
  • Schedule regular downloads at the longest
    intervals that are possible
  • Bundle non-time sensitive requests together

5
Download XML from Server
Requires ltuses-permission androidname "
android.permission.INTERNET " /gt
  • String myFeed getString(R.string.my_feed)
    // HTTP Web address
  • try
  • URL url new URL(myFeed) // Create a new
    HTTP URL connection
  • URLConnection connection url.openConnection()
  • HttpURLConnection httpConnection
    (HttpURLConnection)connection int
    responseCode httpConnection.getResponseCode()
  • if (responseCode HttpURLConnection.HTTP_OK)
  • InputStream in httpConnection.getInputStream(
    )
  • processStream(in) // Use standard Java
    DOM parsing classes
  • catch (MalformedURLException e)
    Log.d(TAG, "Malformed URL", e)
  • catch (IOException e) Log.d(TAG, "IO
    Exception.", e)

6
Download Using Download Manager
  • DownloadManager m (DownloadManager)getSystemServi
    ce(Context.DOWNLOAD_SERVICE)
  • long myReference m.enqueue(new
    Request(Uri.parse(R.string.webLoc)))
  • BroadcastReceiver receiver new
    BroadcastReceiver()
  • _at_Override public void onReceive(Context
    context, Intent intent)
  • long reference intent.getLongExtra(Download
    Manager.EXTRA_DOWNLOAD_ID, -1)
  • if (myReference reference)
  • Query query new Query()
  • Cursor cursor downloadManager.query(query.set
    FilterById(reference))
  • if (cursor.moveToFirst())
  • int fileX cursor.getColumnIndex(DownloadM
    anager.COLUMN_LOCAL_FILENAME)
  • int uriX cursor.getColumnIndex(DownloadManag
    er.COLUMN_LOCAL_URI) String
    fileName cursor.getString(fileX), fileUri
    cursor.getString(uriX)
  • // TODO Do something with the file.
  • cursor.close()
  • registerReceiver(receiver,
  • new IntentFilter(DownloadManager.ACTION_DOWNLOAD
    _COMPLETE) )

Note The cursor object contains information
about downloaded files
7
Listen for Downloaded Files
  • ltreceiver androidname".DownloadReceiver"
    androidexported"true" androidicon"_at_drawable/d
    ownload_icon" gt
  • ltintent-filtergt
  • ltaction androidname"android.intent.action.DOWNLO
    AD_COMPLETE"/gt
  • lt/intent-filtergtlt/receivergt
  • IntentFilter f new IntentFilter(DownloadManager.
    ACTION_DOWNLOAD_COMPLETE))
  • registerReceiver(receiver, f)
  • BroadcastReceiver receiver new
    BroadcastReceiver()
  • _at_Override public void onReceive(Context
    context, Intent intent)
  • String id DownloadManager.EXTRA_DOWNLOAD_ID
  • long references intent.getLongArrayExtra(id)
    // Array of downloaded file ids
  • for (long reference references)
  • String mime getMimeTypeForDownloadedFile
    (reference)
  • // Handle files that this
    activity recognizes.

8
Specifying Download Locations
Note We cannot download to internal storage
using DownloadManager
  • Default Location A shared download cache with
    system generated file names
  • Overriding the download location
    requires ltuses-permission androidname
  • "android.permission.WRITE_EXTERNAL_STORAGE" /gt
  • To designate an arbitrary path in external
    storage Request request new Request(uri)
  • request.setDestinationUri(Uri.fromFile(f))
  • To designate a standard external download folder
    for the application request.setDestinationInExte
    rnalFilesDir(this, Environment.DIRECTORY_DOWNL
    OADS, fileName)
  • To designate location which shares with music
    players request.setDistinationInExternalPublicDi
    r (Environment.DIRECTORY_MUSIC, fileName)

9
SD Card File IO
  • SD Card path getExternalStorageDirectory()
  • How Use standard Java File I/O
  • Notes
  • Manifest "android.permission.WRITE_EXTERNAL_STORA
    GE"
  • Application manifests can set preference to SD
    Card installation
  • Check SD Availability in Java Environment.getExte
    rnalStorageState().equals(Environment.MEDIA_MOUNTE
    D)
  • Convention write to /Android/data/ltpackage_namegt/
    files/
  • ExampleFile sdCard Environment.getExternalStor
    ageDirectory()File dir new File
    (sdcard.getAbsolutePath() "
    /Android/data/ltpackage_namegt/files/
    ")dir.mkdirs() // Make directories with
    missing parents.File file new File(dir,
    "filename") // Instantiate a file object
  • FileOutputStream f new FileOutputStream(file)
    // Open for writing

10
Writing to Internal Storage
  • Writing to internal storage
  • Each application has a designated directory to
    which to write files
  • There is a maximum storage amount, varying per
    device
  • Flags exist to control inter-application access
  • MODE_PRIVATE - No access for other applications
  • MODE_WORLD_READABLE - Read access for other
    applications
  • MODE_WORLD_WRITABLE - Write access for other
    applications
  • MODE_WORLD_READABLE MODE_WORLD_WRITABLE - Read
    / Write access
  • Open file for writing new BufferedWriter( new
    OutputStreamWriter( openFileOutput(fileName,
    MODE_PRIVATE)))

11
Onboard File I/O
  • Write to a designated place for each application
  • Where /data/data/package/files/ using onboard
    storage
  • How Use standard java.io classes, with relative,
    not absolute, paths
  • Applications can
  • Write into its application directory
  • Create subdirectories
  • Give read/write permissions to other applications
    (MODE_PRIVATE, MODE_WORLD_READABLE
    MODE_WORLD_WRITABLE)
  • Android Helper classes in the Context object
  • getDir(String fileName, int permissions) Creates
    or access directory
  • getFilesDir() Get absolute path to application
    directory
  • getCacheDir() Get non-permanent temporary
    storage directory
  • openFileInput(String fileName) Open a file for
    input
  • openFileOutput(String fileName, int permissions)
    Create a new file

Note There is also a sharedPreferences directory
for preferences, a databases directory for SQLite
tables, and a cache directory
12
Copy File from Server
  • public void DownloadFile(String fileURL, String
    fileName)
  •   try   HttpURLConnection c
    (HttpURLConnection) fileURL.openConnection() c.s
    etRequestMethod("GET") c.setDoOutput(false)
    // Tru for POST with intent to send to
    server c.connect() // Establish connection with
    server InputStream in c.getInputStream() //
    Ready to read File root Environment.getExterna
    lFilesDir(null) // Application area
  • // Prepare output stream
  • FileOutputStream out new FileOutputStream(new
    File(root, fileName)) byte buffer new
    byte1024 int len 0 // Note the buffer
    overflow possibility while ((len
    in.read(buffer)) gt 0)   out.write(buffer, 0,
    len)   // Write block
  • f.close()
  • catch (Exception e)   Log.d("Downloader",
    e.getMessage()) 

13
Preferences
  • Initial Purpose
  • Persistent storage for user options
  • Analogous to cookies in Web-based applications
  • More General Purpose
  • Maintains the application state across
    terminations and restarts
  • Provides mechanism for applications to
    persistently store additional data without using
    SQL or Files
  • Preferences Framework
  • Define preferences
  • Display settings
  • Persist user selections

14
Accessing Shared Preference Data
  • // getPreferences is a method in the Activity
    class
  • SharedPreferences prefs getPreferences(Activity
    .MODE_PRIVATE)
  • int intValue getInt("IntKey", 22)
  • long longValue getLong("LongKey", 0)
  • String name getString("NameKey", "")
  • int floatValue getFloat("FloatKey", 0.0)
  • int booleanValue getBoolean("BoolKey", false)
  • SetltStringgt set getStringSet("SetKey", 22)
  • MapltString, ?gt keysAndValues getAll()
  • Notes
  • The second argument is the default if the key was
    not previously stored
  • There is no getDouble() method

15
Modifying SharedPreference Data
  • SharedPreferences preferences
    getPreferences(Activity.MODE_PRIVATE)
  • // or getSharedPreferences("fileName")
  • SharedPreferences.Editor editor
    preferences.edit()
  • editor.putInt("IntKey", 22)
  • editor.putLong("LongKey", 0)
  • editor.putString("NameKey", "")
  • editor.putFloat("FloatKey", 0.0)
  • editor.putBoolean("BoolKey", false)
  • editor.commit()
  • Notes
  • puts can be chained editor.putInt(intKey,
    22).putLong(LongKey, 0)
  • editor.apply() works asynchronously,
    editor.commit() is synchronous
  • editor.clear() erases all of the preference keys
  • editor.remove(Key) deletes a preference
  • Shared preferences use a file name for
    multi-activity sharing

16
Preference Views
  • Preference Screen
  • The view on the left
  • View on the right appears When the user clicks
    after preference screen clicked
  • Selection Screen
  • Modal Dialog on the right
  • Saves selection and disappears after a user
    selection

17
Step 1 Defining Preferences
XML Listing (in res/xml) for the preferences
shown on the previous screen
  • lt?xml version"1.0" encoding"utf-8"?gt lt!--
    /res/xml/flightoptions.xml --gt
  • ltPreferenceScreen xmlnsandroid"http//schemas.an
    droid.com/apk/res/android"
  • androidkey"flight_option_preference"
  • androidtitle"_at_string/PrefTitle"
    androidsummary"_at_string/PrefSummary"gt
  • ltListPreference androidkey"_at_string/SelectedS
    ortOption"
  • androidtitle"_at_string/ListTitle"
    androidsummary"_at_string/ListSummary"
  • androidentries"_at_array/FlightSortOptions" andro
    identryValues"_at_array/FlightSortValues"
  • androiddialogTitle"_at_string/ChooseFlightOptions
    "
  • androiddefaultValue"_at_string/SortDefaultValue"
    /gt
  • lt/PreferenceScreengt
  • public class FlightPreferenceActivity extends
    PreferenceActivity
  • _at_Override protected void onCreate(Bundle
    savedInstanceState)
  • super.onCreate(savedInstanceState)
  • addPreferencesFromResource(R.xml.flightoptions)

18
Define Strings in res/values
  • lt?xml version"1.0" encoding"utf-8"?gt
  • ltresourcesgt
  • ltstring name"AppName"gtPreferences Demolt/stringgt
  • ltstring name"PrefTitle"gtMy Preferenceslt/stringgt
  • ltstring name"PrefSummary"gtSet Search
    Optionslt/stringgt
  • ltstring name"ListTitle"gtFlight Optionslt/stringgt
  • ltstring name"ListSummary"gtSet Search
    Optionslt/stringgt
  • ltstring-array name"FlightSortOptions"gt
  • ltitemgtTotal Costlt/itemgtltitemgt of
    Stopslt/itemgtltitemgtAirlinelt/itemgtlt/string-arraygt
  • ltstring-array name"FlightSortValues"gt
  • ltitemgt0lt/itemgtltitemgt1lt/itemgtltitemgt2lt/itemgtlt/s
    tring-arraygt
  • ltstring name"ChooseFlightOptions"gtChoose Flight
    Optionslt/stringgt
  • ltstring name"SortDefaultValue"gt1lt/stringgt
  • ltstring name"SelectedSortOption"gtSelected Sort
    Optionlt/stringgt
  • ltstring name"menu_prefs_title"gtSettingslt/stringgt
  • ltstring name"menu_quit_title"gtQuitlt/stringgt
  • lt/resourcesgt

19
Manifest
  • lt?xml version"1.0" encoding"utf-8"?gt lt!--
    AndroidManifest.xml --gt
  • ltmanifest xmlnsandroid"http//schemas.android.co
    m/apk/res/android"
  • package"com.syh" androidversionCode"1"
    androidversionName"1.0"gt
  • ltapplication androidicon"_at_drawable/icon"
    androidlabel"_at_string/AppName"gt
  • ltactivity androidname".MainActivity"
    androidlabel"_at_string/AppName"gt
  • ltintent-filtergtltaction androidname"android.inte
    nt.action.MAIN" /gt
  • ltcategory androidname"android.intent.category.
    LAUNCHER" /gt
  • lt/intent-filtergt
  • lt/activitygt
  • ltactivity androidname".PreferenceActivity"
    androidlabel"_at_string/PrefTitle"gt
  • ltintent-filtergtltaction androidname"com.syh.inten
    t.action.FlightPreferences" /gt
  • ltcategory androidname"android.intent.category.P
    REFERENCE" /gt
  • lt/intent-filtergt
  • lt/activitygtlt/applicationgtltuses-sdk
    androidminSdkVersion"3" /gtlt/manifestgt

20
Define Main Android Activity
  • // This is MainActivity.java
  • _at_Override public void onCreate(Bundle
    savedInstanceState)
  • super.onCreate(savedInstanceState)
  • setContentView(R.layout.main) // Assuming
    there is a TextView layout
  • tv (TextView)findViewById(R.id.text1)
  • setOptionText() // Helper method to get user
    preference and adjust view
  • _at_Override public boolean onCreateOptionsMenu(Menu
    menu)
  • MenuInflater inflater getMenuInflater()
  • // Inflate main menu XML with link to preference
    option
  • inflater.inflate(R.menu.mainmenu, menu)
  • return true // Menu is now active

21
Main Activity Selection Responses
  • _at_Override public boolean onOptionsItemSelected
    (MenuItem item)
  • if (item.getItemId() R.id.menu_prefs)
  • Intent intent new Intent().setClass(this,
    com.syh.PreferenceActivity.class)
  • this.startActivityForResult(intent, 0) //
    Second parameter is for a switch in listener
  • else if (item.getItemId() R.id.menu_quit)
    finish()
  • return true // Start preference menu when its
    item is selected
  • _at_Override public void onActivityResult(int
    reqCode, int resCode, Intent data)
  • super.onActivityResult(reqCode, resCode,
    data)
  • SharedPreferences prefs getDefaultSHaredPrefere
    nces(this)
  • String key this.getResources().getString(R.stri
    ng.SelectedSortOption)
  • String default this.getResources().getString(R.
    string.SortDefaultValue)
  • String selection prefs.getString(key ,
    default)
  • String optionText this.getResources().getStri
    ngArray(R.string.FlightSortOptions)
  • tv.setText("option " pref " ("
    optionTextInteger.parseInt(pref) ")")

22
CheckBoxPreference (/res/xml/chkbox.xml)
  • lt?xml version"1.0" encoding"utf-8"?gt
  • ltPreferenceScreen
  • xmlnsandroid "http//schemas.android.com/apk/re
    s/android"
  • androidkey"flight_columns_pref"gt
  • ltCheckBoxPreference androidkey"show_airline_col
    umn_pref"
  • androidtitle"Airline" androidsummary"Show
    Airline column" /gt
  • ltCheckBoxPreference androidkey"show_departure_c
    olumn_pref"
  • androidtitle"Departure" androidsummary"Show
    Departure column" /gt
  • ltCheckBoxPreference androidkey"show_arrival_col
    umn_pref"
  • androidtitle"Arrival" androidsummary"Show
    Arrival column" /gt
  • ltCheckBoxPreference androidkey"show_total_trave
    l_time_column_pref"
  • androidtitle"Total Travel Time"androidsummary
    "Show Total Travel Time column" /gt
  • ltCheckBoxPreference androidkey"show_price_colum
    n_pref"
  • androidtitle"Price" androidsummary"Show
    Price column" /gt
  • lt/PreferenceScreengt

Note For Radio Buttons, use the List Preference
23
Using Check Box Preferences
  • // CheckBoxPreferenceActivity.java
  • import android.os.Bundle
  • import android.preference.PreferenceActivity
  • public class CheckBoxPreferenceActivity extends
    PreferenceActivity
  • _at_Override protected void onCreate(Bundle
    savedInstanceState)
  • super.onCreate(savedInstanceState)
  • addPreferencesFromResource(R.xml.chkbox)
  • // Access preference in an activity
  • SharedPreferences prefs getSharedPreferences("fi
    leName")
  • Boolean option prefs.getBoolean("show_price_colu
    mn_pref", false)

24
EditTextPreference
  • lt?xml version"1.0" encoding"utf-8"?gt
  • ltPreferenceScreen xmlnsandroidhttp//schemas.and
    roid.com/apk/res/android
  • androidtitleSet Package Name"
  • androidsummary"Set the package name for
    generated code"gt
  • ltEditTextPreference androidkey"package_name_pref
    erence"
  • androidtitle"Set Package Name"
    androiddialogTitle"Package Name"
  • androidsummary"Set the package name for
    generated code" /gt
  • lt/PreferenceScreengt

25
Categories of Preferences
  • lt?xml version"1.0" encoding"utf-8"?gt
  • ltPreferenceScreen xmlnsandroid"http//schemas.an
    droid.com/apk/res/android"
  • androidkey"using_categories_in_root_screen"
    androidtitle"Categories"
  • androidsummary"Using Preference Categories"gt
  • ltPreferenceCategory xmlnsandroidhttp//schemas.a
    ndroid.com/apk/res/android
  • androidkey"meats_category" androidtitle"Meats
    " androidsummary"Meat preferences"gt
  • ltCheckBoxPreference androidkey"fish_selection_p
    ref" androidtitle"Fish"
  • androidsummary"Fish is great for the healthy"
    /gt
  • ltCheckBoxPreference androidkey"chicken_selectio
    n_pref" androidtitle"Chicken"
  • androidsummary"A common type of poultry" /gt
  • ltCheckBoxPreference androidkey"lamb_selection_p
    ref" androidtitle"Lamb"
  • androidsummary"Lamb is a young sheep"
    /gtlt/PreferenceCategorygt
  • ltPreferenceCategory xmlnsandroidhttp//schemas.a
    ndroid.com/apk/res/android
  • androidkey"vegi_category" androidtitle"Vegeta
    bles" androidsummary"Vegetable preferences"gt
  • ltCheckBoxPreference androidkey"tomato_selection
    _pref" androidtitle"Tomato "
  • androidsummary"It's actually a fruit" /gt
  • ltCheckBoxPreference androidkey"potato_selection
    _pref" androidtitle"Potato"
  • androidsummary"My favorite vegetable"
    /gtlt/PreferenceCategorygtlt/PreferenceScreengt

Purpose Provide titles to groups of similar
preferences
26
Preference Fragments
  • Android versions 3.0 and newer recommend using
    fragments for preferences instead of activities
  • Check Android Version if (Build.VERSION.SKK_INTlt
    Build.VERSION_CODES.HONEYCOME)
  • / Use preference activity approach /
  • else / Use preference fragment approach /
  • Implementation Steps
  • Define preference screens in XML (as shown on
    previous slides)
  • Add PreferenceFragment to the activity using the
    FragmentManager
  • Create the PreferenceFragment class

27
Preference Fragment in an Activity
  • public class PreferenceFragmentActivity extends
    Activity
  • _at_Override public void onCreate(Bundle
    savedInstanceState)
  • super.onCreate(savedInstanceState) setConten
    tView(R.layout.main) FragmentManager manager
    getFragmentManager() FragmentTransaction
    trans manager.beginTransaction() MyFragment
    fragment new MyFragment() trans.replace(andro
    id.R.id.content, fragment1) trans.addToBackSta
    ck(null)
  • trans.commit()

Note Dont add the fragment to the application
manifest
28
Preference Fragment Class
  • public class MyFragment extends
    PreferenceFragment
  • _at_Override public void onCreate(Bundle
    savedInstanceState)
  • super.onCreate(savedInstanceState) //
    configure the preferences from an XML
    file addPreferencesFromResource(R.xml.preferenc
    es)
  • PreferenceManager manager getPreferenceManager
    ()
  • SharedPreferences shared manager.getSharedPref
    erences()
  • shared.registerOnSharedPreferenceChangeListener(
    this)
  • onSharedPreferenceChanged(SharedPreferences
    pref, String key)
  • / Handle preference change here /

29
SQLite
  • Android SQLite
  • Lightweight database system
  • Standards-compliant
  • Single Tier (no server involved)
  • Open source
  • Standard SQL queries
  • SELECT ID, CITY, STATE FROM STATION WHERE LAT_N
    gt 39.7
  • Application content providers provide
  • Standard interface to SQL tables to other
    applications
  • For application private tables, content providers
    are not needed

30
Authorities / URI
Purpose Publish application SQL tables and data
for external activity access
  • Definition An authority is a registered name on
    an android device (ex Content Provider name.
    Authorities must be unique on the system.
  • Registration Accomplished in an application
    manifest
  • Syntax com.company.someProvider
  • Examples org.acorns.LessonProvider or
    com.android.provider.BookProvider
  • Analogy Authorities are to Android what domain
    names are to the Web
  • Activity access using URIs
  • Syntax content//authority-name/path-segment/path
    -segment/
  • Access book table content//com.anroidbook.provid
    er.BookProvider/books
  • Access particular book content//com.anroidbook.
    provider.BookProvider/books/12
  • Activity Interface Through Content Providers,
    which fill in abstract methods

31
MIME Types
Purpose Indicate a type of data that a content
provider deals with
  • Definition Industry standard way to indicate a
    particular data format
  • Syntax Two text strings separated by slashes
  • First part (category) application, audio, image,
    text, video, etc
  • Second Part (codec) html, css, xml, pdf, rtf,
    etc.
  • Examples text/htm, application/pdf, image/jpeg,
    audio/mpeg, etc.
  • Android MIME Types (Similar syntax as standard
    MIME types)
  • First Part
  • Access single items vnd.android.cursor.item
  • Access multiple items vnd.android.cursor.dir
  • Second Part vnd.yourCompany.type
  • Examples vnd.android.cursor.dir/vnd.google.note
    or vnd.android.cursor.item/vnd.google.note

32
Content Provider Framework
  • An application registers its content provider
    using its manifest
  • The code for the content provider is written
  • An application request data using the published
    MIME type
  • Android looks through the registered manifests
    for an appropriate provider
  • The provider activity is launched to manipulate
    or return data
  • If more than one provider exists, the user
    selects the one to use
  • Android Built-in content providers
    content//media/internal/images/,
    content//media/external/images/,content//contac
    ts/people/

33
Content Providers
A well-defined interface to data for application
access
  • Register an authority using the
    AndroidManifest.xml file
  • Definition An authority is a registered name
  • Analogy authority is to an Android device what a
    domain name is to the Internet
  • Syntax ( Using a package name minimizes
    redundancies on a system)ltprovider
    androidname"fooProvider" androidauthorities"c
    om.company.fooProvider" /gt
  • Exampleltprovider androidname"
    com.acorns.LessonProvider" androidauthorities"c
    om.acorns.provider.Lessons" /gt
  • Another application exampleltprovider
    androidnameNotePadProvider" androidauthoritie
    s"com.google.provider.NotePad" /gt

34
MIME Types
Acronym Multipurpose Internet Mail Extension
  • Specifies the data type an activity can process
  • Register in the AndroidManifest.xml file
  • Example "vnd.android.cursor.dir/vnd.google.note"
    OR "vnd.android.cursor.dir/vnd.google.note"
  • Sample Syntax vnd.android.cursor.ltoptgt/vnd.compan
    y.type
  • vnd non-standard type (vendor)
  • android.cursor required for ContentProvider
    Manifest registrations
  • item single record dir collection of records
  • google company name
  • note content type
  • AndroidManifest.xml registrationltdata
    androidmimeType"vnd.android.cursor.dir/vnd.googl
    e.note" /gt

35
Referring to a Content Provider
  • URI and URL
  • Uniform resource identifier (URI) Identifies the
    name of a resource, but not necessarily
    information regarding its location
  • Uniform resource Location (URL) is a URI, that
    identifies a resource location
  • Text usage URI for content providers URL for
    referring to Web locations
  • URI of a content providercontent//com.company.fo
    oProvider/content//com.acorns.provider.Lessons/
    content//com.google.provider.NotePad/
  • Note Android provided shortcut URIs contacts
    for com.google.android.contacts
  • Refer to the notes SQLite notes
    tablecontent//com.google.provider.NotePad/notes/
  • Refer to the tenth notecontent//com.google.provi
    der/NotePad/notes/10

36
Register the Provider
  • ltprovider androidname"NotePadProvider"
  • androidauthorities"com.google.provid
    er.NotePad" /gt
  • ltactivity androidname"NotesList"
    androidlabel"_at_string/title_notes_list"gt
  • ltintent-filtergt
  • ltaction androidname"android.intent.action
    .MAIN" /gt
  • ltcategory androidname"android.intent.cate
    gory.LAUNCHER" /gt
  • lt/intent-filtergt
  • ltintent-filtergt
  • ltaction androidname"android.intent.action.VIEW"
    /gt
  • ltdata androidmimeType"vnd.android.cursor.dir/vn
    d.google.note" /gt
  • lt/intent-filtergtltintent-filtergt
  • ltaction androidname"android.intent.action.
    GET_CONTENT" /gt
  • ltdata androidmimeType"vnd.android.cursor.item/v
    nd.google.note" gt
  • lt/intent-filtergt lt/activitygt

37
Implement the Provider
  • Plan the Database
  • Extend the ContentProvider class
  • Fill in a variety of methods to be overloaded
  • onCreate() When the database is created
  • onUpgrade() When the database layout changes
  • getType() Return the MIME data type
  • query() Handle queries to the data
  • insert(), delete(), and update() methods

38
A Managed Query in Content Provider
Purpose Query SQL lite table for relevant data
(cursor) Definition An Android cursor is a
collection of rows of data
  • // Specify needed columns
  • string projection new string
  • People._ID, People.NAME, People.NUMBER
  • // Specivy URI using static Contacts constants
  • Uri contactUri Contacts.People.CONTENT_URI
  • // Invoke a content provider query
  • Cursor cursor managedQuery( contactUri,
  • projection, //Which columns to return
  • null, null, // Selection and WHERE clauses
  • Contacts.People.NAME " ASC") // Order-by
    (ascending by name)

Other classes exist (ex SQLiteQueryBuilder) for
using standard SQL strings
39
Navigating through a cursor
  • Manipulate the cursor (row pointer)
  • if (cursor.moveToFirst() false)
  • cursor.isBeforeFirst(), cursor.isAfterLast,
    cursor.isClosed()
  • while (cursor.moveToNext()) / code here /
  • for (cursor.moveToFirst() !cursor.isAfterLast()
    cur.moveToNext)
  • Get column numbers from names
  • int nameColumn cursor.getColumnIndex(People.NAME
    )
  • int phoneColumn cursor.getColumnIndex(People.NUM
    BER)
  • Get Data from column
  • String name cursor.getString(nameColumn)
  • String number cursor.getString(phoneColumn)
  • Prerequisites Know column names, data types,
    column name to index relationship

After a query, the cursor points before the
first use moveToFirst() use moveToNext() for
the initial access
40
Other Access Methods
  • Add
  • ContentValues values new ContentValues()
  • values.put(BookProviderMetaData.BookTableMetaData.
    BOOK_NAME, "book1")
  • values.put(BookProviderMetaData.BookTableMetaData.
    BOOK_AUTHOR, "author-1")
  • ContentResolver resolve context.getContentResolv
    er()
  • URI uri BookProviderMetaData.BookTableMetaData.C
    ONTENT.URI
  • Uri inserted resolve.insert(uri, values)
  • Delete Assume that bookIndex is pre-defined
  • ContentResolver resolve context.getContentResolv
    er()
  • URI uri BookProviderMetaData.BookTableMetaData.C
    ONTENT.URI
  • Uri delURI uri.withAppendedPath(uri,
    Integer.toString(bookIndex))
  • resolve.delete(delUri, null, null)
  • Count
  • URI uri BookProviderMetaData.BookTableMetaData.C
    ONTENT.URI
  • Cursor cursor activity.managedQuery(uri, null,
    null, null, null)
  • Int numberOfRecords cursor.getCount()
  • cursor.close()

See next slide for symbolic constant definitions
41
BookProviderMetaData class
42
Content Resolver
  • Definition A Content Resolver is an Android
    class that matches the URI to an available
    Content Provider that can handle the data
  • Purpose Separate the provider from the data,
    enabling the possibility of multiple content
    providers available to handle the same data types
  • Access Use a collection of method calls to
    insert, retrieve, delete, update data records
  • Example (insert a new note into the notepad)
  • ContentResolver resolver activity.getContentRe
    solver()
  • Uri newUri resolver.insert(Notepad.Notes.CONTE
    NT_URI, values)

Note values is an instance of the ContentValues
class
43
Store Files in an SQLite Database
  • Steps
  • Create the SQLite table with a column called
    _data
  • Get a writeable output stream
  • Write the file to the reserved column name _data
  • I/O Example
  • //Use a content resolver to insert the record
  • ContentResolver contentResolver
    activity.getContentResolver()
  • Uri newUri contentResolver.insert(Notepad.Notes
    .CONTENT_URI, values)
  • //Use the content resolver to get an output
    stream directly
  • OutputStream outStream contentResolver().openOu
    tputStream(newUri)
  • writeFileToRecord(outStream)
  • outStream.close()

ContentValues object contains a set of values
Note The data is actually stored in a separate
area. The _data column contains the Uri reference
to the data
44
DataBase Helper
  • Purpose
  • Manage database creation and version management
  • Responsible for creating and upgrading an SQLite
    database
  • Defer database opening and updating to the first
    use
  • Avoids blocking application startup with compute
    intensive database upgrades
  • Contains methods for getWritableDatabase and
    getReadableDatabase
  • Simplifies Content Provider access to files
  • Eliminates concern over whether the application
    was terminated
  • Implementation
  • Create a class that extends SQLiteOpenHelper
  • Override onCreate() and onUpgrade() methods

45
Helper Code (Two tables Employees, Department)
This application will need to override onCreate
and onUpgrade
  • public class DatabaseHelper extends
    SQLiteOpenHelper
  • static final String dbName"demoDB"
  • static final String employees"Employees"
  • static final String colID"EmployeeID"
  • static final String colName"EmployeeName"
  • static final String colAge"Age"
  • static final String colDept"Dept"
  • static final String depts"Department"
  • static final String colDeptID"DeptID"
  • static final String colDeptName"DeptName"
  • static final String viewEmps"ViewEmps"
  • public DatabaseHelper(Context context) //
    Constructor
  • super(context, dbName, null / Extension to
    cursor class /, 1 / version /)

46
Helper Example (cont.)
  • public void onCreate(SQLiteDatabase db)
  • db.execSQL("CREATE TABLE " "depts
  • " (" colDeptID " INTEGER PRIMARY KEY , "
    colDeptName " TEXT)")
  • db.execSQL("CREATE TABLE "employees
  • " (" colID " INTEGER PRIMARY KEY
    AUTOINCREMENT, "
  • colName " TEXT, " colAge " Integer, "
  • colDept " INTEGER NOT NULL , FOREIGN KEY ("
    colDept ") REFERENCES "
  • deptTable" ("colDeptID"))")
  • db.execSQL("CREATE TRIGGER fk_empdept_deptid ""
    BEFORE INSERT ON "employees
  • " FOR EACH ROW BEGIN" " SELECT CASE WHEN (
    (SELECT " colDeptID " FROM " depts "
    WHERE " colDeptID "new." colDept " ) IS
    NULL)"
  • " THEN RAISE (ABORT, 'Foreign Key Violation')
    END" " END")
  • db.execSQL("CREATE VIEW " viewEmps " AS
    SELECT " employees "." colID
  • " AS _id," " " employees "." colName
    ", " employees "." colAge ", "
  • depts "." colDeptName "" " FROM "
    employees " JOIN " depts
  • " ON " employees "." colDept" " depts
    "." colDeptID )

47
Helper Example (cont.) Upgrading the DB
Called when the version number in the constructor
changes
  • public void onUpgrade(SQLiteDatabase db, int
    oldVersion, int newVersion)
  • db.execSQL("DROP TABLE IF EXISTS "employees)
  • db.execSQL("DROP TABLE IF EXISTS "depts)
  • db.execSQL("DROP TRIGGER IF EXISTS
    dept_id_trigger")
  • db.execSQL("DROP TRIGGER IF EXISTS
    dept_id_trigger22")
  • db.execSQL("DROP TRIGGER IF EXISTS
    fk_empdept_deptid")
  • db.execSQL("DROP VIEW IF EXISTS "viewEmps)
  • onCreate(db)

Note The activity can respond to menu selections
to insert, remove, and update rows
48
Using a Database helper
  • Helper new Helper(context, Helper.DATABASE_NAME,
    null, Helper.VERSION)
  • SQLiteDatabase db Helper.getWritableDatabase()
    // Perform query
  • Cursor cursor db.query(Helper.DATABASE_TABLE,
    result_columns, where,
  • whereArgs, group, having, order)
  • SQLiteDatabase db hoardDBOpenHelper.getWritableD
    atabase() // Insert row
  • db.insert(HoardDBOpenHelper.DATABASE_TABLE, null,
    newValues)
  • SQLiteDatabase db hoardDBOpenHelper.getWritableD
    atabase() // Update row
  • db.update(Helper.DATABASE_TABLE, newValues,
    where, whereArgs)
  • SQLiteDatabase db Helper.getWritableDatabase()
    // Delete matching rows
  • db.delete(Helper.DATABASE_TABLE, where,
    whereArgs)

49
Find media titles and albums
Using the Android provided Media Store Content
Provider
  • String projection MediaStore.Audio.AudioC
    olumns.ALBUM,
  • MediaStore.Audio.AudioColumns.TITLE
  • Uri uri MediaStore.Audio.Media.EXTERNAL_CONTENT_
    URI
  • Cursor cursor getContentResolver().query(uri,
    projection, null, null, null)
  • int aX cursor.getColumnIndexOrThrow(MediaStore.Au
    dio.AudioColumns.ALBUM)
  • int tX cursor.getColumnIndexOrThrow(MediaStore.
    Audio.AudioColumns.TITLE)
  • String result new Stringcursor.getCount()
  • while (cursor.moveToNext())
  • String title cursor.getString(tX), album
    cursor.getString(aX)
  • resultcursor.getPosition() title " ("
    album ")"
  • cursor.close()

Other Native Content Providers Browser,
Contacts, Calendar, Call log
50
Accessing the Contact List
  • int iDCol ContactsContract.Contacts.ID
  • int nameCol ContactsContract.Contacts.DISPLAY_N
    AME
  • Uri uri ContactsContract.Contacts.CONTENT_URI
  • String projection iDCol, nameCol
  • Cursor cursor getContentResolver().query(uri,
    projection, null, null, null)
  • int nameIndex cursor.getColumnIndexOrThrow(name
    Col)
  • int idIndex cursor.getColumnIndexOrThrow(contact
    IDCol)
  • String result new Stringcursor.getCount()
  • while(cursor.moveToNext())
  • String name cursor.getString(nameIndex)
  • String id cursor.getString(idIndex)
  • resultcursor.getPosition() name " (" id
    ")"
  • cursor.close()

51
Searchable Applications
  • Expose the application to search-facilities
  • Alternatives
  • Search bar appearing after hardware search button
    pressed or a program method call
  • Search widget placed somewhere on the application
    view
  • Quick Search implemented as a home screen widget
  • Enable voice search

52
Making an Application Searchable
  • In the manifest
  • Create an xml file with the searchable attributes
  • Mark the application searchable
  • Define the intent for the activity processing
    searches
  • Either create a search activity
  • Launch when the search is initiated
  • Process and display the results
  • Or use a search dialog (floating search box)
  • Hidden by default, but can be initiated by
    calling onSearchRequested(), which is an Activity
    class method
  • If the device doesnt contain a dedicated search
    button, add a menu option or widget that calls
    onSearchRequested()
  • Or use the SearchView widget

53
Searchable configuration in res/xml
Filename searchable.xml
  • lt?xml version"1.0" encoding"utf-8"?gtltsearchable
    xmlnsandroidhttp//schemas.android.com/apk/res
    /android
  •     androidlabel"_at_string/app_label
  •     androidhint"_at_string/search_hint"
    gtlt/searchablegt
  • The label (required attribute) becomes visible
    when search is launched and contains the search
    application name
  • The hint appears in the search box before users
    enter a query. It contains a hint about what can
    be searched
  • Other attributes are for search suggestions and
    voice search

54
Searchable launch in Manifest
  • ltapplicationgt
  • ltactivity androidname".SearchActivity
  • androidlaunchMode"singleTop"gt
  • ltintent-filtergt
  • ltaction androidname"android.intent.action.SEAR
    CH" /gt
  • lt/intent-filtergt
  • ltmeta-data androidname"android.app.searchable"
  • androidresource"_at_xml/searchable" /gt
  • lt/activitygt
  • Note singleTop prevents multiple instances on
    the back stack

55
Search Activity
  • _at_Overridepublic void onCreate(Bundle
    savedInstanceState)
  •   super.onCreate(savedInstanceState)
  • setContentView(R.layout.search)
  • // Get the intent, verify the action and get the
    query
  • Intent intent getIntent()
  • if (Intent.ACTION_SEARCH.equals(intent.getAction(
    )))
  • String query intent.getStringExtra(SearchMana
    ger.QUERY)
  • doMySearch(query) // Process the request

56
Services
  • Services handle background events separate from a
    View
  • Services reside in the main thread of the
    launching process! Use thread facilities to
    avoid blocking the main thread
  • Only foreground activities have a higher
    priority, so services are rarely terminated by
    the OS
  • Proper Handling
  • Main activity makes requests
  • Service starts worker threads to perform requests
  • Bind services to the main thread
  • Callbacks to the main activity completes
    transactions.

57
Creating a Service
  • Create a class extending the service class
  • Register the service in the application
    manifest ltservice androidenabled"true"
  • androidname".MyService" androidpermission"fo
    o.bar.MY_SERVICE_PERMISSION"/gt
  • Start and stop of the service in the main
    activity
  • Use separate threads for compute-bound operations
  • Bind service to the main activities so the main
    activity can call service class methods and then
    update its user interface views
  • Self-terminate the service when it is no longer
    needed

58
Starting and Stopping Services
  • Explicitly start My Service
  • Intent intent new Intent(this,
    MyService.class)
  • // TODO Add extras if required.
  • startService(intent)
  • Implicitly start a music Service
  • Intent intent new Intent(MyMusicService.PLAY_AL
    BUM) intent.putExtra(MyMusicService.ALBUM_NAM
    E_EXTRA, "United")
  • intent.putExtra(MyMusicService.ARTIST_NAME_EXTRA,
    "Pheonix")
  • startService(intent)
  • Explicitly stop My Service
  • stopService(new Intent(this, MyService.class))
  • Implicitly stop Music Service
  • stopService(new Intent(MyMusicService.PLAY_ALBUM)
    )

59
Creating a Bindable Service
Purpose Enable activities to access service
methods
  • public class LocalService extends Service
  •   private final IBinder binder new
    LocalBinder()  public class LocalBinder extends
    Binder
  •   LocalService getService()   return
    LocalService.this  
  • _at_Override public void onCreate()
  • // TODO Actions to perform when service is
    created.
  • // Return instance after activity call
    onBindService() call    _at_Override public
    IBinder onBind(Intent intent)
  • return binder 
  •     / method for clients /    public int
    getRandomNumber() return Math.random()   

60
  • public class BindingActivity extends Activity
    // An Activity using a Bound Service
  •     LocalService service boolean bound
    false    private ServiceConnection connection
    new ServiceConnection() // Anonymous instance
  • _at_Override public void onServiceConnected(Compon
    entName name,  IBinder service)
  • LocalBinder binder(LocalBinder) service  
  • servicebinder.getService() boundtrue
    _at_Override   public void onServiceDisconnected
    (ComponentName arg0)
  • bound false
  •     _at_Override   protected void
    onCreate(Bundle savedInstanceState)
  •   super.onCreate(savedInstanceState)
    setContentView(R.layout.main)     _at_Override
    protected void onStart()
  • super.onStart() Intent intent new
    Intent(this, LocalService.class)       
    bindService(intent, connection,
    Context.BIND_AUTO_CREATE)      _at_Override
    protected void onStop()
  • super.onStop() if (bound)  
    unbindService(connection)  bound false   
        public void onButtonClick(View v)
  •     if (bound) int num service.getRandomNum
    ber()
  •       Toast.makeText(this, "number "num,
    Toast.LENGTH_SHORT).show()

61
Updating the GUI from a Service
  • The activity registers a listening object with
    the service
  • The service broadcasts an intent and the activity
    responds
  • Use a Handler in an activity
  • private final Handler handler new Handler() //
    Process queue of runnables
  • private OnClickListener buttonListener new
    OnClickListener()
  • public void onClick(View v)
  • new Thread(new Runnable()
  •   pubic void run() //.... hard work in
    separate thread
  •         handler.post(new Runnable()   public
    void run()  // ... update the UI    )
  •             ).start()
  •         
  •     

Note There are other possibilities. For example,
one could use AsyncTask, IntentService or Loader
objects
Write a Comment
User Comments (0)
About PowerShow.com