English | Site Directory

Android - An Open Handset Alliance Project

Android SDK M5 Release - API Changes Overview

This is a high level description of the changes in the M5 release of the Android SDK since the last public release, M3.

AndroidManifest.xml

There are several changes to the AndroidManifest.xml file that will hit you immediately when porting an application to M5 and will need to be updated. The most likely ones you will see are:

  • The class= parameter throughout the AndroidManifest.xml file has been renamed, replace all instances of class= with android:name=.
  • The android:value= parameters used throughout the AndroidManifest.xml file have been renamed, replace all android:value= occurrences with android:name=.
  • The android:id= parameters used throughout the AndroidManifest.xml file have been renamed, replace all android:id= occurrences with android:name=.
  • In <intent-filter>, the previous <type>, <scheme>, <authority> and <path> tags are now replaced with a single <data> tag and uses attributes android:mimeType, android:scheme, android:host and android:path to replace those tags respectively. A new attribute: android:port has been added as well. Without these changes, intent-filters will not work correctly.

    So, for example:
    <intent-filter>
        <action android:value="android.intent.action.INSERT" />
        <category android:value="android.intent.category.DEFAULT" />
        <type android:value="vnd.android.cursor.dir/vnd.google.note" />
    </intent-filter>
        
    Would be replaced with:
    <intent-filter>
        <action android:name="android.intent.action.INSERT" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
    </intent-filter>
        

Take a look at the AndroidManifest.xml document for more details.

Layout

Layout Files also need to be updated before they will work correctly:

  • The main change is that id= has been replaced with android:id= and all occurrences of id= should be changed.

Adapters

  • android.widget.SimpleCursorAdapter has been improved:
    • Now supports ImageViews.
    • The user can specify which column in the Cursor should be used to convert the Cursor to a String.
    • Alternatively, the user can supply a CursorToStringConverter explicitly.
    • A FilterQueryProvider can be passed to the adapter to generate filtering queries for AutoCompleteTextView.
    • While SimpleCursorAdapter supports only TextView and ImageView, the user can now supply a ViewBinder to easily add support for any sort of View.
  • These new features greatly reduce the need to extend SimpleCursorAdapter or one of its parents.

Widgets and Views

  • Classes:
  • Coordinates:
    • The "window coordinates", represented in android.view.View by the fields mWindowLeft and mWindowTop, have been removed. The public accessor methods getWindowLeft(), getWindowTop(), getWindowRight() and getWindowBottom() have likewise been removed.
  • Threading:
  • Events:
  • Touch Mode:
    • Touch mode is a mode of operation where it is not necessary to explicitly give focus to or control focus of actionable items such as buttons, so the user can see what item will take input. A touch capable device will enter "touch mode" when the user touches the screen. From this point forwards, only views for which isFocusableInTouchMode() is true will be focusable, such as text editing widgets, other views like buttons will only take focus when touched. If the user hits a directional key, like the D-pad, the device will exit touch mode, and all views will become focusable. See Touch Mode and Focus Handling in android.view.View for more details.
  • Request Focus:
    • android.view.View.takeFocus() has been removed. android.view.View.requestFocus() should be used in one of its forms instead. requestFocus() now behaves like the old takeFocus() method did, including returning a boolean indicating whether the call was successful.
    • Replace all calls to takeFocus() with requestFocus().
    • Existing calls to requestFocus() will work as long as what you are calling it on are focusable, and if in touch mode, focusable in touch mode.
    • Update overrides of requestFocus() to return a boolean indicating whether or not the view you are forwarding the request to took it (usually just by putting a return statement in front of the forwarding calls to requestFocus).
  • Scrolling:
  • Finer Grained Focus Passing:
    • View.requestFocus() and View.onFocusChanged() work together to give a newly focused item a hint about the most interesting rectangle of the previously focused view. Take a look at the InternalSelectionFocus example in the ApiDemos sample.
  • ListView and GridView:
    • android.widget.ListView and android.widget.GridView now allow their content to be stacked from the bottom edge. You can enable this feature using the setStackFromBottom() method. This feature formerly existed in ListView as the gravity (ListView.setGravity()). The gravity variation has been removed.
  • ListActivity:
  • View:
  • ExpandableListView:
    • android.widget.ExpandableListView is a new widget that provides a two-level tree-type widget. The top-level items are groups and are each expandable/collapsible to reveal the group's children. It shows indicators (by default) to the left of each item to show the current state of the item. The indicators along with the position they should be drawn are settable.
    • The android.widget.ExpandableListAdapter provides data to this widget. It is similar to a regular Adapter, but has two sets of methods: one for groups and one for children.
    • There is an example in the API Demos > Views > Lists > Expandable > 1, 2, 3.
    • Internally, this widget inherits from android.widget.ListView and has a connector to translate between "flat list" positions to group + child positions. Some methods will be available from ListView that return the "flat list" position, so developers should probably be aware of this. Worst case, there are methods exposed (getExpandableListPosition and getFlatListPosition) to convert between the two.
      • The expandable list position is usually represented as a "packed position" containing the type of position (either child, group, or null), and a group position (for both group and children), and a child position (for children). Methods starting with getPackedPosition... help with unpacking.
  • SurfaceView:
    • When using android.view.SurfaceView it is no longer necessary to force the window to be transparent or otherwise do anything special. See the SurfaceView examples in ApiDemos to see how the class should be used.
  • Drawing Cache:
    • android.view.View now offers a drawing cache: when the drawing cache is enabled (see android.view.View.setDrawingCacheEnabled()), the View copies itself into a Bitmap when getDrawingCache() is invoked. This can be used to improve drawing performance for complex views as ViewGroup will automatically query the drawing cache of its children to attempt faster drawing. It is also possible to control the quality of the drawing cache using android.view.View.setDrawingCacheQuality() or the corresponding XML attribute.
    • android.view.ViewGroup can enable or disable the drawing cache of all of its children at once using ViewGroup.setChildrenDrawingCacheEnabled().
    • ViewGroup now offers a layout animation (see Layout Animations for more information about layout animations) cache: if enabled, the children's drawing caches are enabled when a layout animation starts, thus offering better performance. The layout animation cache can be disabled using ViewGroup.setAnimationCacheEnabled().
    • android.widget.AbsListView (and therefore ListView and GridView) now offers a scrolling cache: if enabled, the children's drawing caches are enabled when a scroll operation starts, thus offering better performance. The scrolling cache can be disabled using AbsListView.setScrollingCacheEnabled().
    • The persistence of the drawing cache can be set using ViewGroup.setPersistentDrawingCache(). A persistent drawing cache means that the Bitmap used by the children as a drawing cache is kept in memory after the cache was used. For instance, with the persistent drawing cache set to PERSISTENT_SCROLLING_CACHE, the drawing caches of a ListView's children are kept in memory after a scroll operation. This avoids creating new Bitmaps over and over again, thus providing better performance.
    • By default, android.view.ViewGroup will always try to draw its children using their drawing cache. For instance, you have a ListView with a persistent scrolling cache. A scroll operation will create the cache for all of the children and this cache will be used to draw the children during scrolling. When the scrolling is over, the cache is kept and ViewGroup reuses the cache to draw the children on screen. In some situations however, you might want to keep the cache in memory but not use it for drawing outside of specific operations (like animations or scrolling); this is usually what you want if you set the cache quality to low. In that case you can call ViewGroup.setAlwaysDrawnWithCacheEnabled() to prevent the ViewGroup from drawing with the cache.

Menus

  • There are three new menu types: the icon menu, the expanded menu, and context menus.
  • Icon and expanded menus:
    • Icon menus are the first menu to appear when pressing the menu button. A maximum of six menu items will be shown; if the user has more than six items in the options menu, the sixth item will be a 'More' item which will launch the expanded menu. Icon menus will not show checkbox or radio buttons, nor shortcuts.
    • Expanded menus list all of the menu items (although when shown it will start at the sixth item since the first five were shown in the icon menu). This menu type shows checkboxes, radio buttons, and item shortcut keys. Pressing the menu key here will collapse the entire menu system, pressing the back key will go back to the icon menu.
    • From either of these two types of menu, a submenu can be opened that only shows its items.
    • The API is similar to the previous Menu API with a couple of notes:
      • Divider/separators have been removed.
      • Icons have been added to each menu item. An icon will be shown in both of these menu types.
      • Internally, Views and Drawables are lazy loaded, so performance should have increased.
  • Context Menus:
    • These are pop-up style menus initiated by long pressing (either clicking the center button or touching for roughly 2 seconds) existing Views in an application.
    • Example use: when long pressing a contact in the Contacts application, a context menu appears with 'View contact', 'Call Mobile', 'Add star', 'Edit contact', 'Delete contact'.
    • The API for adding to a context menu is similar to the regular Menu API (in fact, the ContextMenu interface extends the Menu interface with the additional functionality for setting the header).
    • See android.view.ContextMenu for usage information.
    • The API for setting the triggers to launch a context menu are new:
      • A View is the starting point for launching a context menu. When a user long presses a View, the View and its parents begin populating the context menu (via View.onPopulateContextMenu()). However, each View can also have a android.view.View.OnPopulateContextMenuListener which will be called when this populating sequence occurs for the View. This listener will most likely be a developer's hook into populating a context menu for his application.
      • The parameters to the method in this listener:
        • The ContextMenu menu that should be populated (very similar API to the options Menu, with added functionality to set the header of the context menu to either a title, title+icon, or a custom View).
        • The View v that triggered the context menu. In some cases such as a ListView, it makes more sense to add a OnPopulateContextMenuListener to a parent View than to individual child Views. v will be the ListView in this example.
        • Object menuInfo that contains extra information relevant to the triggering of the context menu. Most AdapterViews will pass android.widget.AdapterView.ContextMenuInfo, while an ExpandableListView will pass android.widget.ExpandableListView.ExpandableListContextMenuInfo. In these cases, the object will have the child's exact information: the child View, its ID, and its position in the adapter.
      • Finally, when all of the Views and their OnPopulateContextMenuListeners have populated the ContextMenu, it will be shown. At the top will be a header that is developer-settable.
      • When the user clicks or closes the menu, the Activity#onContextItemSelected and Activity#onContextMenuClosed will be called respectively. To get the extra information contained in the menuInfo object, use Menu.Item.getMenuInfo().
    • Unlike options menu, the object implementing ContextMenu is freshly created each time the ContextMenu is shown and each item needs to be re-added to the menu.
  • Specific Menu API Changes:

Animations

  • In android.view.View, setCurrentAnimation() and getCurrentAnimation() have been renamed setAnimation() and getAnimation().
  • android.view.animation.Animation is now an abstract class and not an interface anymore.
  • android.view.animation.BaseAnimation has been removed, animations implementer should extend the android.view.animation.Animation class instead.
  • Animation interpolators can now be defined in XML.
  • android.view.ViewGroup can now keep its children's animations after they are over. This is useful when you are using an animation whose fillAfter property is set to true and when the final state of the animation is different from the normal state of the child. See ViewGroup.setKeepAnimations() for more details.
  • Animation listeners are working now.
  • Layout Animations:
    • Layouts (and more generally descendants of ViewGroup) can be animated using an android.view.animation.LayoutAnimationController. See ViewGroup and ApiDemos for more details. A LayoutAnimationController is associated with a regular Animation and the ViewGroup will query the controller for a copy of that Animation for each of its children. Every child will have the same animated behavior (for instance, fade in or fade out) each individual's animation will start at a different time. The role of a LayoutAnimationController is to compute the start time of each child's animation. For instance, GridLayoutAnimationController will compute the start time based on the X and Y position of a child in a GridView whereas LayoutAnimationController will simply use the index of the child in the ViewGroup. The controller lets you specify the order (normal, reverse or random) and priority of the animations (columns first, rows first or both).

Alerts

As an alternative to the android.app.AlertDialog.show() methods, there is now an android.app.AlertDialog.Builder which you can use instead, for example:

AlertDialog.show(this, getResources().getString(R.string.delete_title), 
        getResources().getString(R.string.delete_message),
        getResources().getString(R.string.yes_button), new OnClickListener() {
            public void onClick(DialogInterface dialog, int arg1) {
                Cursor c = mCursor;
                c.deleteRow();
                managedCommitUpdates(c);
                setResult(RESULT_OK);
                finish();
            }
        },
        getResources().getString(R.string.no_button), new OnClickListener(){
            public void onClick(DialogInterface dialog, int arg1) {
                // do nothing
            }
        },
        true, new OnCancelListener() {
            public void onCancel(DialogInterface dialog) {
                // do nothing
            }
        });
}
with code like this:
new AlertDialog.Builder(this)
        .setTitle(getResources().getString(R.string.delete_title))
        .setMessage(R.string.delete_message)
        .setPositiveButton(R.string.no_button, new OnClickListener() {
            public void onClick(DialogInterface dialog, int arg1) {
               Cursor c = mCursor;
               c.deleteRow();
               managedCommitUpdates(c);
               setResult(RESULT_OK);
               finish();
            }
        })
       .setNegativeButton(R.string.yes_button, new OnClickListener() {
           public void onClick(DialogInterface dialog, int arg1) {
               // do nothing
           }
       })
       .show();
This way it is only necessary to define those listeners that you wish to use.

SQLite/Content Provider

  • The QueryBuilder class has been moved to the android.database.sqlite package and renamed SQLiteQueryBuilder as it now is responsible for building the SQL that is passed to android.database.sqlite.SQLiteDatabase.
  • The android.net.ContentURI class has be replaced with the new android.net.Uri class. This is not a 1:1 replacement and engenders a number of necessary changes in the way you use and manipulate URIs in Android applications. android.content.ContentUris provides some static helper methods for appending and parsing IDs. android.net.Uri.Builder is a builder class to help with creating new Uris (from existing ones if necessary). Take a look at the Notepad sample from the SDK to see how to use these classes to replace the ContentURI usage.

    Some suggested replacements:
    OldNew
    new ContentURI(String) Uri.parse(String)
    ContentURI.create(String) Uri.parse(String)
    ContentUri.countPathSegments() Uri.getPathSegments().size()
    ContentUri.getPathSegment() Uri.getPathSegments().get()
    or
    Uri.getLastPathSegment()
    ContentURI.addPath() Uri.Builder.appendPath()
    ContentURI.addId(id) uri = Uri.withAppendedPath(SOME_URI, id);
    or
    uri = ContentUris.appendId(uri.buildUpon(), id).build();
  • The previously unused groupBy and having parameters have been removed from ContentProvider.query().
  • ContentProvider has a new method, openFile() that takes a URI and returns a file descriptor to the opened file. The ContentProvider.openFileHelper() method covers the common case, override openFile and call it if you don't need anything fancy. It is now the responsibility of the ContentProvider to open the file, it no longer needs to have a special column with the file name, can open any file it wants, and also no longer needs to make the files world-readable. A file descriptor is returned to the client.
  • android.content.ContentURIParser has been removed, use android.content.UriMatcher instead.
  • ContentProvider.onSyncStart() and ContentProvider.onSyncStop() now each take an account parameter.
  • SQLiteCursor.supportsUpdates() could have returned true when updates were not supported, this is fixed.
  • SQLiteCursor.commitUpdates() now returns true when there are no updates to commit.
  • SQLiteCursor has a new method, hasUpdates() which returns true if any updates were made to the cursor.
  • The custom Android SQLite functions are now available in the sqlite3 shell tool.
  • SQLiteDatabase.query() may also take a SQLiteDatabase.CursorFactory now as well as the constructor.
  • android.database.Cursor has the new method getWantsAllOnMoveCalls() which tells the client side to send move notifications to the content provider for all moves, not just ones that cross window boundaries.
  • Cursor has the new method getExtras() which lets the cursor provide out of band data to the users.
  • Cursor has the new method respond() which lets the user send out of band data back to the Cursor implementation.
  • android.database.ArrayCursor has been replaced by android.database.ArrayListCursor.
  • Reading floating point and long values from android.database.sqlite.SQLiteCursor now works correctly.

Geographical and Location Based

  • The location manager now allows a provider to be selected directly by name:
    android.location.LocationManager.getProvider(String name).
  • The Geo APIs now require permissions to be set on the calling activity:

    android.Manifest.permission.ACCESS_LOCATION - required to access any location-based services
    android.Manifest.permission.ACCESS_GPS - required to access the "gps" provider, if it exists
    android.Manifest.permission.ACCESS_ASSISTED_GPS - requires to access the "agps" provider, if it exists
    android.Manifest.permission.ACCESS_CELL_ID - required to access the "cell" provider, if it exists.

    Activities must obtain all relevant permissions; for example, to access assisted GPS requires all of the first three permissions listed above.

  • There are new APIs for forward and reverse geocoding in the android.location package:
    • These APIs are currently mocks only and are subject to change before release. Details on how to specify data for the API to playback to you is described below.
    • android.location.Address defines a postal address.
    • android.location.Location (which existed in M3) defines a location via latitude/longitude.
    • android.location.Geocoder defines interfaces to obtain a Location from an Address (geocoding) or an address from a Location (reverse geocoding). It also supports business search.
  • Geocoding can be mocked by creating a file in /data/misc/location/geodb. The file syntax is:
    address <id number>
    line <line number> "<text>"
    locality "<text>"
    region" <text>"
    postalCode" <text>"
    countryCode" <text>"
    countryName" <text>"
    latitude "<number>"
    longitude "<text>"
    phone "<text>"
    url "<text>"
    extra "<key>" "<data>"
    
    location <center latitude> <center longitude> <latitude span> <longitude span> <id> [<id> ...] "<text>"
    business <latitude> <longitude> <latitude span> <longitude span> <id> [<id> ...] "<text>"
        

    For example:

    address 3
    latitude "38.898763"
    longitude "-77.036655"
    line 0 "1600 Pennsylvania Ave NW"
    line 1 "Washington, DC 20006"
    locality "Washington"
    region "DC"
    postalCode "20006"
    countryCode "US"
    countryName "United States"
    
    location 0 0 180 360 3 "1600 Pennsylvania Avenue, Washington DC"
    location 0 0 180 360 3 "1600 Pennsylvania Ave, Washington DC"
    location 0 0 180 360 3 "1600 Pennsylvania Avenue, Washington D.C."
    location 0 0 180 360 3 "1600 Pennsylvania Ave, Washington D.C."
    
    business 38.898763 -77.036655 50 50 3 "White House"
        

    This defines four query strings that will all return the address with id "3" for a location search anywhere in the world (because the latitude span is 180 and the longitude span is 360). Additionally, a business search for "White House" centered within 50 degrees of the actual location will return the same address.

Notification Manager

  • Transient notifications are not called notifications anymore. They are now called android.widget.Toasts. This name may not be permanent, but the rest of the API should be quite settled:
    • Toasts are run through the Toast class, which have options for all of the parameters that we were getting the whole matrix of, except that they always show "views."
    • There is a convenience method, Toast.makeText() that takes either a CharSequence or a resource id (a new addition in this change) and returns a Toast object constructed with a properly formatted TextView. You're then free to call whatever methods you need to on that toast, especially show(). E.g.:
      Toast.makeText(context, R.string.some_string, Toast.LENGTH_SHORT).show();
            
    • The notification manager now only does persistent notifications, and they are just called notifications. android.app.NotificationManager now has two methods: notify(id, notification) and cancel(id).
  • The notification UI for the status bar has changed. You should make sure that your notification behaves correctly with the new UI. In particular, the notification used to be displayed in a bubble but is now an entry in a list and should behave accordingly.

Browser

  • The version of webkit used in Android has been updated through a series of incremental patches. This should not affect most developers since the changes are primarily bug fixes to the rendering engine.
  • BrowserCallback has been removed and the functionality has been separated with two new classes: android.webkit.WebViewClient and android.webkit.WebChromeClient.
  • BrowserCallbackAdapter has also been removed.

GTalk (formerly XMPP)

  • The com.google.android.xmppService package has been replaced by the com.google.android.gtalkservice package. This was done to better reflect the fact that this is a Google-specific service, and not part of the Android core.

    This service has two goals: to provide a convenient way for developers to send peer-to-peer messages from their applications between handsets, and to provide an API for sending and receiving instant messages from Google's Talk servers. Since it is not intended to be a generic XMPP API or gateway, and since in the future it will likely move to a binary protocol that will not be compatible with XMPP, we have renamed the Service to avoid confusion.

    Developers who need standards-compliant XMPP functionality are encouraged to use a third-party library that provides that functionality.

  • As an extension to the above change, all use of XMPP naming has been purged in favor of GTalk. For example, com.google.android.xmppService.IXmppService has been renamed com.google.android.gtalkservice.IGTalkService.
  • IGTalkService now has group chat support. This is not 100% compatible with XMPP multi-user chat (MUC), but rather implements a subset of the XMPP MUC spec. This is consistent with Google's GTalk service and what other GTalk clients support. In particular, only private chat rooms are supported.
  • The GTalkService APIs for message sending have changed. com.google.android.gtalkservice.IChatSession has been created specifically for chat related functionality. The sendDataMessage() method has been replicated (for convenience) in the new IChatSession interface.
  • Added com.google.android.gtalkservice.IRosterListener for controlling message/roster/presence notification in the GTalkService API, so the GTalk app can control whether new messages (or roster and presence updates) are notified through a callback interface (using Binder) or post the message on the statusbar. This allows the GTalk app to be in control of how the user sees new messages, etc.
  • Miscellaneous API clean up, for example:
    IGTalkSession.blockContact(String contact, boolean block)
        
    to
    IGTalkSession.blockContact(String contact) and
    IGTalkSession.unblockContact(String contact)
        

OpenGL

Media

  • MediaPlayer:
    • Added support for OGG Vorbis (.ogg) and MIDI (.mid, .smf), XMF (.xmf, .mxmf), iMelody (.imy), RTTTL/RTX (.rtttl, .rtx) and OTA (.ota) audio file formats.
    • Added convenience methods for creating a android.media.MediaPlayer object from a Uri. See MediaPlayer.create(Context, Uri) and MediaPlayer.create(Context, Uri, Surface) for more details.
    • Added method for grabbing a frame from a video clip to use a thumbnail.
    • Added method to set power management behavior.
    • Added method to determine whether media is currently playing.
    • Added support for http streaming of MP4 media.
    • MediaPlayer.prepare() is now called from MediaPlayer.create() and you will get an exception if you call MediaPlayer.prepare() after using create().
  • MidiFile has been deleted in favor of android.media.MediaPlayer which offers improved functionality and a unified API for all multimedia files and streams.
  • There are numerous bugfixes in the media framework.

Search Manager

  • A new early-look API, android.app.SearchManager, is now available. This provides the ability to search for user, system or network based data, making search a seamless, system-wide feature.
  • There are two example activities, SearchInvoke and SearchQueryResults, which can be found under the App / Search section in the ApiDemos SDK Sample.
Build m5-rc15f - 23 Apr 2008 12:29