Profile

Cover photo
Joanna Smith
Works at Google
3,882 followers|763,961 views
AboutPostsCollectionsPhotosVideos

Stream

Joanna Smith

Shared publicly  - 
 
Preferences made easy! Or, easier, at least. We really do want you to #BuildBetterApps, so we're making preferences simpler with the Preferences Support Library.
 
Preferences Support Library: Preference Fragments for API 7+, no matter the Activity
Pro-tip by +Ian Lake

Creating your preferences from XML files means less code and a consistent user experience across apps. However, this required that you use PreferenceActivity and even then you could only use PreferenceFragment on API 11+ devices. Well, no more: the Preferences Support v7 Library (http://goo.gl/BPE0M1) makes it possible to use any Activity class (such as an AppCompatActivity) with PreferenceFragmentCompat (http://goo.gl/kKXszC) and add preferences using the same preference XML files (http://goo.gl/wOcIxI), while adding support for elements such as SwitchPreference (previously only available on API 14+ devices) to all API 7+ devices.

A simple implementation would include a PreferenceFragmentCompat such as:
public class PreferencesFragment extends PreferenceFragmentCompat {
 @Override
  public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    addPreferencesFromResource(R.xml.preferences);
  }
}

You’ll also need to set preferenceTheme in your theme:
<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
  <!-- Set colorPrimary, colorPrimaryDark, colorAccent, etc →
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

Customizing the preferenceTheme allows for increased control over the styling and layouts used for each preference type without affecting other parts of your Activity.

Even better, PreferenceFragmentCompat uses RecyclerView for showing the list of preferences, allowing you to integrate scrolling techniques (http://goo.gl/119brU) with the help of the Android Design Support Library (http://goo.gl/8LN2Aj).

One thing you’ll note isn’t in here is preference headers and you’d be totally right. However, that doesn’t mean a single list of preferences need to span a 10” tablet screen. Instead, your Activity can implement OnPreferenceStartFragmentCallback (http://goo.gl/IZWZBP) to handle preferences with an app:fragment attribute or OnPreferenceStartScreenCallback (http://goo.gl/CFp5Cr) to handle PreferenceScreen preferences. This allows you to construct a ‘header’ style PreferenceFragmentCompat in one pane and use those callbacks to replace a second pane without working in two separate types of XML files.

So what about the preferences-v14 library? You’ll find it offers the same API as the preferences-v7 library, but built on framework Fragments and DialogFragments.

If you’re building apps for Android TV, you’ll find the preference-v17 library (http://goo.gl/i2A1zF) incredibly helpful - providing an optimized Leanback version of preferences via LeanbackPreferenceFragment (http://goo.gl/eLqNEv) built on top of these preference APIs.

#BuildBetterApps
37 comments on original post
10
Add a comment...

Joanna Smith

Shared publicly  - 
 
Layouts are the only part of your app that users see. So we’re making them easier to make
 
Percentage Based Dimensions and Margins with the Percent Support Library
Pro-tip by +Joanna Smith

There are a lot of options to help you position your Views just right. But adding a LinearLayout to your beautiful RelativeLayout just to gain access to layout_weight for that perfect positioning is ridiculous. And we hear you on that. Which is why Android introduced the new Percent Support Library (https://goo.gl/XTOD5G). Its PercentFrameLayout and PercentRelativeLayout provide an easy way to specify View dimensions and margins in terms of a percentage of the overall size.

That means if you want a view to take up exactly 50% of the available width and height, you’d use a layout such as
<android.support.percent.PercentRelativeLayout>
 <ImageView
  android:id=”@+id/centered_image”
  android:layout_gravity=”center”
  app:layout_widthPercent="50%"
  app:layout_heightPercent="50%" />
 <TextView
  android:id=”@+id/caption”
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_below=”@id/centered_image”
  android:layout_gravity=”center_horizontal”
  app:layout_marginStartPercent=”25%”
  app:layout_marginEndPercent=”25%” />
</android.support.percent.PercentRelativeLayout>

Note that we use layout_marginStartPercent/EndPercent to set a margin based on a percentage of the total width.

Fun fact: if the percentage you set is more of a guideline than hard limit, you can also set layout_width/height=”wrap_content” in addition to layout_widthPercent/heightPercent and Views larger than the allowed percentage value will instead be resized using wrap_content rules.

So check out the Percent library today and use this efficient layout to #BuildBetterApps  
34 comments on original post
11
2
Raul Santos's profile photoAnnyce Davis's profile photo
Add a comment...

Joanna Smith

Shared publicly  - 
 
 
Use ShareCompat to easily build and read incoming share intents Pro-tip by +Ian Lake

The ‘share’ action is an iconic part of Android apps, providing a standard way of sending and receiving data from other apps - be it a simple text string, an image, any arbitrary content (say, a file from your app), or even multiple items. Constructing and reading these Intents requires either knowing the exact constants to use or using ShareCompat (http://goo.gl/WDegTC).

ShareCompat.IntentBuilder provides a fluent API for constructing ACTION_SEND (http://goo.gl/XTuFzv) and ACTION_SEND_MULTIPLE (http://goo.gl/QVzeg8) intents.

Constructing a simple share intent with text then becomes:
Intent shareIntent = ShareCompat.IntentBuilder.from(activity)
  .setType(“text/plain”)
  .setText(shareText)
  .getIntent();
// Avoid ActivityNotFoundException
if (intent.resolveActivity(getPackageManager()) != null) {
  startActivity(shareIntent);
}

You’ll also find methods for setting the subject, email to/cc/bcc addresses, and an HTML version of your text.

Sharing an image is similar:
Intent shareIntent = ShareCompat.IntentBuilder.from(activity)
  .setType(“image/png”)
  .setStream(uriToImage)
  .getIntent();

Preferably using a URI generated from a FileProvider (https://goo.gl/wdBrnk) to ensure all apps can access the file even if they don’t have storage permissions.

On the receiving side, ShareCompat.IntentReader can be used to retrieve the information from intents:

ShareCompat.IntentReader intentReader = ShareCompat.IntentReader.from(activity);
if (intentReader.isShareIntent()) {
  String[] emailTo = intentReader.getEmailTo();
  String subject = intentReader.getSubject();
  String text = intentReader.getHtmlText();
  // Compose an email
}

While not guaranteed from a security or verification perspective, using ShareCompat also includes information on the sending application which the receiving application can take advantage of through IntentReader.getCallingPackage() or the convenience methods such as getCallingApplicationIcon() and getCallingApplicationLabel() allowing your app to attribute shared content if that data is present.

#BuildBetterApps  
9 comments on original post
5
Add a comment...

Joanna Smith

Shared publicly  - 
 
Runtime permissions are a big change, after all. Gotta be prepared for when you don't have permission.
 
How to deal with permission denial on Android M
Pro-tip by +Wojtek Kaliciński

M Developer Preview 2 now includes a new method for Runtime Permissions: Activity.shouldShowRequestPermissionRationale().
It informs your app if it should display an explanation for the permission it is requesting before actually showing the permission dialog.

On a fresh app install, the method returns false, so you can ask for any required permissions straight away. If the user previously declined a permission, the method will return true. In that case you should consider displaying an explanation before invoking the permission dialog again. You should only do it if the permission is not self-explanatory.

Finally, if the app has no chance of having the permission granted, calls to shouldShowRequestPermissionRationale() will return false. This can happen for several reasons, such as the user selecting ""do not show again"" in the permission dialog. A false result means it doesn’t make sense to show any additional prompts with explanations.

Please note that, due to a bug, Fragment.shouldShowRequestPermissionRationale() always returns false on the M Developer Preview 2. This will be fixed in a future release. You can use getActivity().shouldShowRequestPermissionRationale() from Fragments in the meantime.

Check out our sample showing Runtime Permissions in action: https://goo.gl/9xpwqN"
4 comments on original post
5
1
fauziah yana's profile photo
Add a comment...

Joanna Smith
moderator

Development Patterns  - 
 
Sometimes, it's the small changes that can make big impacts.
 
Choose a snackbar over a toast to make your users happy
Pro-tip by +Joanna Smith

Toasts are great for giving the user a simple message. But they don’t really do anything other than exist: they just appear on the screen, linger for a bit, and then fade away. Generally, this is fine, but if you’re using a toast to communicate with your users often, it can get annoying.

Instead, consider a Snackbar (http://goo.gl/nwRGer). Snackbars also appear at the bottom of the screen and eventually fade away. But unlike a toast, a snackbar can be dismissed with a swipe. This is pretty great when you want to inform the user that an action has completed, because they can read the message and then swipe it away when they’re done - giving users like me a chance to control exactly how long it remains on screen.

But snackbars aren’t just dismissable toasts. Snackbars can be enhanced to offer an action to the user. Consider a photo deletion, where you were using a toast to say “Photo deleted!” and causing me to wait for 15 seconds before getting those pixels back. With a snackbar confirmation instead, you can still use the bottom of the screen to say “Photo deleted!” but you can also make me happy by letting me swipe it away. You can even prevent the “NO!” moment when I tried to tap “Share” and hit the trash can icon instead. Because you can add an “UNDO” action to that snackbar, offering me a chance to immediately correct my mistake instead of growling at your app (or interrupting me with a confirmation dialog every time). Now look at what a happy user I am!

To add an action to a snackbar, simply call setAction() with your action string and a click event listener, and you’re all set.

It’s these minor adjustments that can fill your app with magic moments and anticipate your users’ needs. That is what makes the difference between an app users love and rate, and an app users uninstall and forget about. So check the design docs on snackbars and toasts to learn more about how and when to use each component. Then add the Android Design Support Library (http://goo.gl/Xf7Jp6) to your project to start using Snackbars. And, of course, don’t forget to #BuildBetterApps.
17 comments on original post
7
Add a comment...

Joanna Smith

Shared publicly  - 
 
Some people are more important than knowing my lives have refilled. Not everyone, but, you know, some people. Let your notification earn its rightful place at the top of the list by providing metadata about those important people.
 
Add people metadata to notifications to influence notification ranking and priority mode
Pro-tip by +Ian Lake

Android notifications always try to order notifications by importance. For a long time this was determined only by the notification’s priority and timestamp. With Android 5.0, a number of new metadata fields were added that influence ranking decisions. One of the most important of those is the option to associate people with the notification, via addPerson()
(http://goo.gl/LQw8J0)

addPerson() takes a URI in one of three forms:
- a CONTENT_LOOKUP_URI (http://goo.gl/2xA4ph) or the “permanent” link to an individual contact already in the user’s Contacts content provider
- a tel: schema for phone numbers, which will use ContactsContract.PhoneLookup (http://goo.gl/K6C36e) to find the associated user
- a mailto: schema for email addresses

This search results in one of three outcomes for each notification: no match found, a match found, or a starred contact found. Notifications from starred contacts are deemed the most important, while any match is deemed a higher priority than no contact at all. This means that adding people information may break a tie between similar notifications, favoring the notification that includes people in the user’s contacts.

If you’ve used priority mode to filter out notifications to only the essential, you may have noticed that one of the options there is to only receive calls or messages from starred contacts - this uses the same people metadata to determine whether a notification should interrupt a user. Adding this information can be key to ensuring that user’s expectations in priority mode are honored.

You don’t need to build your own contacts provider (http://goo.gl/4lwvU4) or even have the Contacts permission to take advantage of addPerson() - adding what information you have in the form of email addresses or phone numbers can be enough to improve the user’s notification experience, leveraging the contacts they already have on their device.
11 comments on original post
3
Add a comment...

Joanna Smith
moderator

Development Patterns  - 
 
These small changes make a huge difference for users who otherwise may not be able to use your app at all. Just saying.
 
Put Android’s accessibility services to work as a testing tool
Pro-tip by +Joanna Smith

Android provides a ton of accessibility support, and building that into your app is easy to do. But once you’ve finished making your app accessible, you’ll want to be sure that you’ve done a good job. As with any other app development process, you need to test your app.

The easiest way to do this is to use the accessibility services that are already on your device. Then, just walk through your app, trying every component and cleaning up the bad behavior. The goal here is to be certain that nothing surprises you, and that the app flow is clear and interactive and accessible.

First, consider users who rely on a screen reader. Fortunately, most devices already have a screen reader installed, in the form of TalkBack. TalkBack works by speaking the UI elements aloud as the user focuses on them.

To enable TalkBack, simply navigate to Settings > Accessibility > TalkBack, and either check the box or slide the control to the on position. TalkBack will immediately become active. A tap will bring an element into focus and tell you what it is, a double tap anywhere on the screen will select the current focused element, and swiping in any direction will move the focus in that direction. As a bonus, all of TalkBack’s settings are adjustable (https://goo.gl/vXr6fD), so that you can test any scenario you need to.

Once enabled, you need to start using your app to see if TalkBack understands each UI component. If a button isn’t read aloud, you should give it a label. Any image or graphic needs a content description explaining what it is. And for elements like EditText, you’ll want to use a hint to explain what the user should enter, without interfering with the text input.

Secondly, consider users that rely on focus-based navigation instead of touch navigation. To test focus-based navigation, you’ll want to simulate a directional-pad. This can easily be done in the Android Emulator (https://goo.gl/K49tmG), which has a d-pad by default. But if you’d like to test on a device, you can download the Eyes-Free Keyboard (https://goo.gl/4nJldM).

Once you have your d-pad, simply begin using your app again, testing each component and transition. This will allow you to be certain that your UI elements are all focusable and reachable. And even more importantly, you can confirm that the focus order is logical for your app. Because when a user cannot simply tap on the element they are interested in, they need another way to get there.

Finally, you can rely on accessibility settings to test specific cases that may be relevant to your app. If your app relies on audio, captions are available on devices running Android 4.4 or higher. Magnification gestures and large text will enable you to see what your app looks like when stretched or zoomed. And color inversion and color correction are experimental features on Android 5.0 for low-vision or color-blind users. You may want to check that your app is still clear and comprehensible when the colors have been modified.

So test your app and continue to #BuildBetterApps.
11 comments on original post
4
1
김경철's profile photo
Add a comment...
Have her in circles
3,882 people
hoody bird's profile photo
Rojer Mike's profile photo
Patrick Fuentes's profile photo
mayank sud's profile photo
Atusi Nakamura (中村 敦)'s profile photo
guadalupe concepcion zapata maldonado's profile photo
AJ Kohn's profile photo
Long Nguyen's profile photo
Rahul Uppalwar's profile photo

Joanna Smith

Shared publicly  - 
 
Clearly, this is going to be the best conference of the year. And the most delicious.
 
The Big Android BBQ (http://goo.gl/AKWeJJ) is almost here, and we'll be there serving up a healthy portion of best practices for Android development and performance! #BABBQ will be held at the Hurst Convention Center in Dallas in Ft.Worth, Texas on October 22-23, 2015.

Register here (https://goo.gl/mzDItm) through August 25th and you will get 25% off when you use the promotional code "ANDROIDDEV25."

Now, sit back, and enjoy this video of some Android cowfolk preparing for this year’s BBQ!

https://goo.gl/wfdy3U

#PerfMatters #BuildBetterApps
10 comments on original post
7
David Dzado's profile photoBig Android BBQ's profile photoMarty Ballard's profile photo
3 comments
 
5th year for me!
Add a comment...

Joanna Smith
moderator

Development Patterns  - 
 
Layouts are the only part of your app that users see. So we’re making them easier to make.
 
Percentage Based Dimensions and Margins with the Percent Support Library
Pro-tip by +Joanna Smith

There are a lot of options to help you position your Views just right. But adding a LinearLayout to your beautiful RelativeLayout just to gain access to layout_weight for that perfect positioning is ridiculous. And we hear you on that. Which is why Android introduced the new Percent Support Library (https://goo.gl/XTOD5G). Its PercentFrameLayout and PercentRelativeLayout provide an easy way to specify View dimensions and margins in terms of a percentage of the overall size.

That means if you want a view to take up exactly 50% of the available width and height, you’d use a layout such as
<android.support.percent.PercentRelativeLayout>
 <ImageView
  android:id=”@+id/centered_image”
  android:layout_gravity=”center”
  app:layout_widthPercent="50%"
  app:layout_heightPercent="50%" />
 <TextView
  android:id=”@+id/caption”
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_below=”@id/centered_image”
  android:layout_gravity=”center_horizontal”
  app:layout_marginStartPercent=”25%”
  app:layout_marginEndPercent=”25%” />
</android.support.percent.PercentRelativeLayout>

Note that we use layout_marginStartPercent/EndPercent to set a margin based on a percentage of the total width.

Fun fact: if the percentage you set is more of a guideline than hard limit, you can also set layout_width/height=”wrap_content” in addition to layout_widthPercent/heightPercent and Views larger than the allowed percentage value will instead be resized using wrap_content rules.

So check out the Percent library today and use this efficient layout to #BuildBetterApps  
34 comments on original post
8
3
Vijith Menon's profile photoJean Bernard Breu (jeanjean)'s profile photo
Add a comment...

Joanna Smith

Shared publicly  - 
 
 
Choose a snackbar over a toast to make your users happy
Pro-tip by +Joanna Smith

Toasts are great for giving the user a simple message. But they don’t really do anything other than exist: they just appear on the screen, linger for a bit, and then fade away. Generally, this is fine, but if you’re using a toast to communicate with your users often, it can get annoying.

Instead, consider a Snackbar (http://goo.gl/nwRGer). Snackbars also appear at the bottom of the screen and eventually fade away. But unlike a toast, a snackbar can be dismissed with a swipe. This is pretty great when you want to inform the user that an action has completed, because they can read the message and then swipe it away when they’re done - giving users like me a chance to control exactly how long it remains on screen.

But snackbars aren’t just dismissable toasts. Snackbars can be enhanced to offer an action to the user. Consider a photo deletion, where you were using a toast to say “Photo deleted!” and causing me to wait for 15 seconds before getting those pixels back. With a snackbar confirmation instead, you can still use the bottom of the screen to say “Photo deleted!” but you can also make me happy by letting me swipe it away. You can even prevent the “NO!” moment when I tried to tap “Share” and hit the trash can icon instead. Because you can add an “UNDO” action to that snackbar, offering me a chance to immediately correct my mistake instead of growling at your app (or interrupting me with a confirmation dialog every time). Now look at what a happy user I am!

To add an action to a snackbar, simply call setAction() with your action string and a click event listener, and you’re all set.

It’s these minor adjustments that can fill your app with magic moments and anticipate your users’ needs. That is what makes the difference between an app users love and rate, and an app users uninstall and forget about. So check the design docs on snackbars and toasts to learn more about how and when to use each component. Then add the Android Design Support Library (http://goo.gl/Xf7Jp6) to your project to start using Snackbars. And, of course, don’t forget to #BuildBetterApps.
17 comments on original post
7
1
Giovanni Laquidara's profile photo
Add a comment...

Joanna Smith

Shared publicly  - 
 
We've been working on new content that clarifies some best practices for Android development. Hopefully you're as excited as we are (but nbd if not--because you will be when we launch)!
 
100 days of Google Dev, Episode 61/100

Every Android app should have, at its core, a solid foundation to build on.

Android Development Patterns will teach you how to build better apps by explaining the fundamental components of Android development, the reasoning behind them, and best practices for using them in your app.

#GoogleDev100

https://goo.gl/lPbi5m
7 comments on original post
9
1
Bryan Madaras's profile photo
Add a comment...

Joanna Smith

Shared publicly  - 
 
 
Put Android’s accessibility services to work as a testing tool
Pro-tip by +Joanna Smith

Android provides a ton of accessibility support, and building that into your app is easy to do. But once you’ve finished making your app accessible, you’ll want to be sure that you’ve done a good job. As with any other app development process, you need to test your app.

The easiest way to do this is to use the accessibility services that are already on your device. Then, just walk through your app, trying every component and cleaning up the bad behavior. The goal here is to be certain that nothing surprises you, and that the app flow is clear and interactive and accessible.

First, consider users who rely on a screen reader. Fortunately, most devices already have a screen reader installed, in the form of TalkBack. TalkBack works by speaking the UI elements aloud as the user focuses on them.

To enable TalkBack, simply navigate to Settings > Accessibility > TalkBack, and either check the box or slide the control to the on position. TalkBack will immediately become active. A tap will bring an element into focus and tell you what it is, a double tap anywhere on the screen will select the current focused element, and swiping in any direction will move the focus in that direction. As a bonus, all of TalkBack’s settings are adjustable (https://goo.gl/vXr6fD), so that you can test any scenario you need to.

Once enabled, you need to start using your app to see if TalkBack understands each UI component. If a button isn’t read aloud, you should give it a label. Any image or graphic needs a content description explaining what it is. And for elements like EditText, you’ll want to use a hint to explain what the user should enter, without interfering with the text input.

Secondly, consider users that rely on focus-based navigation instead of touch navigation. To test focus-based navigation, you’ll want to simulate a directional-pad. This can easily be done in the Android Emulator (https://goo.gl/K49tmG), which has a d-pad by default. But if you’d like to test on a device, you can download the Eyes-Free Keyboard (https://goo.gl/4nJldM).

Once you have your d-pad, simply begin using your app again, testing each component and transition. This will allow you to be certain that your UI elements are all focusable and reachable. And even more importantly, you can confirm that the focus order is logical for your app. Because when a user cannot simply tap on the element they are interested in, they need another way to get there.

Finally, you can rely on accessibility settings to test specific cases that may be relevant to your app. If your app relies on audio, captions are available on devices running Android 4.4 or higher. Magnification gestures and large text will enable you to see what your app looks like when stretched or zoomed. And color inversion and color correction are experimental features on Android 5.0 for low-vision or color-blind users. You may want to check that your app is still clear and comprehensible when the colors have been modified.

So test your app and continue to #BuildBetterApps.
11 comments on original post
5
Add a comment...
Joanna's Collections
People
Have her in circles
3,882 people
hoody bird's profile photo
Rojer Mike's profile photo
Patrick Fuentes's profile photo
mayank sud's profile photo
Atusi Nakamura (中村 敦)'s profile photo
guadalupe concepcion zapata maldonado's profile photo
AJ Kohn's profile photo
Long Nguyen's profile photo
Rahul Uppalwar's profile photo
Work
Employment
  • Google
    DPE, present
Links
Story
Tagline
You had me at "Hello, World!"
Introduction
I am a Developer Programs Engineer at Google, working with the Google+ development community.

I recently graduated from the University of Texas at Austin, having studied Computer Science, with a thesis based in CS Education.

I love learning new trivia, and trying to challenge (read: scare) myself.
Bragging rights
avid reader, adequate bowler
Basic Information
Gender
Female