Wednesday, January 4, 2012

[Gd] Holo Everywhere

| More

Android Developers Blog: Holo Everywhere

[This post is by Adam Powell, an Android Framework engineer who cares about style. —Tim Bray]

Android 4.0 showcases the Holo theme family, further refined since its debut in Android 3.0. But as most developers know, a new system theme for some Android devices isn’t a new or uncommon event. For developers new system themes mean more design targets for their apps. Using system themes means developers can take advantage of a user’s existing expectations and it can save a lot of production time, but only if an app designer can reliably predict the results. Before Android 4.0 the variance in system themes from device to device could make it difficult to design an app with a single predictable look and feel. We set out to improve this situation for the developer community in Ice Cream Sandwich and beyond.

Theme.Holo

If you’re not already familiar with Android’s style and theme system, you should read Styles and Themes before continuing.

Compatibility Standard

In Android 4.0, Holo is different. We’ve made the inclusion of the unmodified Holo theme family a compatibility requirement for devices running Android 4.0 and forward. If the device has Android Market it will have the Holo themes as they were originally designed.

This standardization goes for all of the public Holo widget styles as well. The Widget.Holo styles will be stable from device to device, safe for use as parent styles for incremental customizations within your app.

The Holo theme family in Android 4.0 consists of the themes Theme.Holo, Theme.Holo.Light, and Theme.Holo.Light.DarkActionBar. Examples of these themes in action are shown in the screenshots lining this post.

To use a Holo theme, explicitly request one from your manifest on your activity or application element, e.g. android:theme="@android:style/Theme.Holo". Your app will be displayed using the unmodified theme on all compatible Android 4.0 devices. The Holo themes may also be used as stable parent themes for app-level theme customizations.

What about device themes?

We have no desire to restrict manufacturers from building their own themed experience across their devices. In fact we’ve gone further to make this even easier. In Android 4.0’s API (level 14) we’ve added a new public theme family to complement the Holo family introduced in Android 3.0: DeviceDefault. DeviceDefault themes are aliases for the device’s native look and feel. The DeviceDefault theme family and widget style family offer ways for developers to target the device’s native theme with all customizations intact.

Theme.Holo.Light

Formally separating these theme families will also make future merges easier for manufacturers updating to a new platform version, helping more devices update more quickly. Google’s Nexus devices alias DeviceDefault to the unmodified Holo themes.

Making use of your chosen theme

We’ve added a number of theme attributes to report common metrics and color palette info to apps that want to fit in with a theme. These include highlight colors, default padding and margins for common UI elements such as list items, and more. Apps that wish to integrate with their chosen theme (both Holo and DeviceDefault included) can refer to these theme attributes as in the examples below:

Sample button with system-supplied touch highlight:

<ImageButton android:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/button_icon"
android:background="?android:attr/selectableItemBackground" />

Sample widget with a custom pressedHighlightColor attribute, value retrieved from the system theme:

<MyWidget android:layout_width="wrap_content"
android:layout_height="wrap_content"
myapp:pressedHighlightColor="?android:attr/colorPressedHighlight" />

Sample list item layout using system-supplied metrics and text appearance:

<LinearLayout android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingRight="?android:attr/listPreferredItemPaddingRight">
<TextView android:id="@+id/text"
android:textAppearance="?android:attr/textAppearanceListItem" />
<!-- Other views here -->
</LinearLayout>

Theme.Holo.Light.DarkActionBar
(Available in API level 14 and above)

Defaults for Older Apps

If an app does not explicitly request a theme in its manifest, Android 4.0 will determine the default theme based on the app’s targetSdkVersion to maintain the app’s original expectations: For values less than 11, @android:style/Theme; between 11 and 13 @android:style/Theme.Holo; and for 14 and higher @android:style/Theme.DeviceDefault.

Using Holo while supporting Android 2.x

Most Android developers will still want to support 2.x devices for a while as updates and new devices continue to roll out. This doesn’t stop you from taking advantage of newer themes on devices that support them though. Using Android’s resource system you can define themes for your app that are selected automatically based on the platform version of the device it’s running on.

Theme.Holo and Theme.Holo.Light have been available since API level 11, but Theme.Holo.Light.DarkActionBar is new in API level 14.

res/values/themes.xml:

<resources>
<style name="MyTheme" parent="@android:style/Theme">
<!-- Any customizations for your app running on pre-3.0 devices here -->
</style>
</resources>

res/values-v11/themes.xml:

<resources>
<style name="MyTheme" parent="@android:style/Theme.Holo">
<!-- Any customizations for your app running on devices with Theme.Holo here -->
</style>
</resources>

Finally, in AndroidManifest.xml:

<!-- [...] -->
<application android:name="MyApplication"
android:label="@string/application_label"
android:icon="@drawable/app_icon"
android:hardwareAccelerated="true"
android:theme="@style/MyTheme">
<!-- [...] -->

You can go as far with this idea as you like, up to and including defining your own theme attributes with different values across configurations for use in your other resources. To learn more about Android’s resource system, see Application Resources.

Final Thoughts

Android apps running on 4.0 and forward can use the Holo themes and be assured that their look and feel will not change when running on a device with a custom skin. Apps that wish to use the device’s default styling can do so using the DeviceDefault themes that are now in the public API. These changes let you spend more time on your design and less time worrying about what will be different from one device to another. Finally, Android’s resource system allows you to support features from the latest platform version while offering graceful fallback on older devices.

URL: http://android-developers.blogspot.com/2012/01/holo-everywhere.html

[Gd] Automatically setting a vacation responder from a calendar event

| More

Google Apps Developer Blog: Automatically setting a vacation responder from a calendar event

Are you ever at an airport with no internet access, and realize that you forgot to set your "Out of Office" (OOO) message?" I forget regularly, but always remember to block off my calendar. Why not have the calendar automatically update my OOO message? We can! With the Calendar API, we can retrieve calendar events and set a vacation responder for the event duration for any user in the domain using the Email Settings API.

The first step is to authorize the Calendar and Email Settings client to make any call to the APIs respectively. The new Calendar API requires google-api-client library while the Email settings API still works with the gdata-client library in Python. These libraries use different underlying protocols and handle authorization differently.

Fortunately we can use the same code to get an OAuth 2.0 token for both the Calendar API and the Email Settings API.


from oauth2client.file import Storage
from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.tools import run

SCOPES = ('https://www.googleapis.com/auth/calendar '
'https://apps-apis.google.com/a/feeds/emailsettings/2.0/')

FLOW = flow_from_clientsecrets('client_secrets.json', scope=SCOPES)

storage = Storage('vacation.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = run(FLOW, storage)

Now that we have obtained the OAuth 2.0 token from OAuth2WebServerFlow, we can use it in either library. To authorize the Calendar service:


# Create an httplib2.Http object to handle the HTTP
# requests and authorize it with our good Credentials.

http = httplib2.Http()
http = credentials.authorize(http)

# Build authorized service for Calendar API
service = build('calendar', 'v3', http=http)

Authorizing the Email Settings client requires adapting the credentials:


auth2token = gdata.gauth.OAuth2Token(client_id=client_id,
client_secret=client_secret,
scope=SCOPE,
access_token=credentials.access_token,
refresh_token=credentials.refresh_token,
user_agent='vacation-responder-sample/1.0')

email_client = auth2token.authorize(
gdata.apps.emailsettings.client.EmailSettingsClient(
domain=domain))

Now its time to update the vacation responder based on calendar event using the authorized client. Lets query for events containing the string ‘vacation’ from the Calendar API. The following code snippet shows the retrieval of events.


# Convert the date to the RFC 3339 timestamp format
# for Calendar API.
cur_datetime = datetime.datetime.now()
cur_date = cur_datetime.strftime('%Y-%m-%dT%H:%M:%SZ')

events = service.events().list(calendarId=username,
q='vacation', timeMin=cur_date, singleEvents=True,
orderBy='startTime').execute()

By specifying a user’s email address as the calendarID, we can query against any primary calendars in our domain that are shared and readable by the administrator. If the user opts to hide their calendar, we won’t find any of their events. For additional details about the query on calendar events, refer to the calendar query parameters from the reference guide.

Next we can obtain the start and end time of the event and update the vacation responder using the Email Settings client if the event’s duration is day long or more.


if 'items' in events:
for event in events['items']:
startDate = event['start']
endDate = event['end']
# If event is set for the day not just for a time slot.
if 'date' in startDate:
email_client.UpdateVacation(username=username,
enable=True,
subject='Out of office',
message='If urgent call me.',
domain_only=True,
start_date=startDate['date'],
end_date=endDate['date'])
print '\nVacation responder set for the days between %s to %s' %
(startDate['date'], endDate['date'])
break

You can download the sample and build your own application on top of it. We hope that this sample makes it easier to get started, particularly for apps that need to combine APIs from the two API clients. Please feel free to reach us in the Google Domain Info and Management Forum with any questions you have or write us feedback on this post.

Shraddha Gupta   profile

Shraddha is a Developer Programs Engineer for Google Apps. She has her MTech in Computer Science and Engineering from IIT Delhi, India.

URL: http://googleappsdeveloper.blogspot.com/2012/01/automatically-setting-vacation.html