Warning: Table './devblogsdb/cache_page' is marked as crashed and last (automatic?) repair failed query: SELECT data, created, headers, expire, serialized FROM cache_page WHERE cid = 'http://www.softdevblogs.com/?q=aggregator' in /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/database.mysql.inc on line 135

Warning: Cannot modify header information - headers already sent by (output started at /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/database.mysql.inc:135) in /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/bootstrap.inc on line 729

Warning: Cannot modify header information - headers already sent by (output started at /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/database.mysql.inc:135) in /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/bootstrap.inc on line 730

Warning: Cannot modify header information - headers already sent by (output started at /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/database.mysql.inc:135) in /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/bootstrap.inc on line 731

Warning: Cannot modify header information - headers already sent by (output started at /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/database.mysql.inc:135) in /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/bootstrap.inc on line 732
Software Development Blogs: Programming, Software Testing, Agile, Project Management
Skip to content

Software Development Blogs: Programming, Software Testing, Agile Project Management

Methods & Tools

Subscribe to Methods & Tools
if you are not afraid to read more than one page to be a smarter software developer, software tester or project manager!

Feed aggregator
warning: Cannot modify header information - headers already sent by (output started at /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/database.mysql.inc:135) in /home/content/O/c/n/Ocnarfparking9/html/softdevblogs/includes/common.inc on line 153.

Unix: Find files greater than date

Mark Needham - 6 hours 48 min ago

For the latter part of the week I’ve been running some tests against Neo4j which generate a bunch of log files and I wanted to filter those files based on the time they were created to do some further analysis.

This is an example of what the directory listing looks like:

$ ls -alh foo/database-agent-*
-rw-r--r--  1 markneedham  wheel   2.5K 23 Jun 14:00 foo/database-agent-mac17f73-1-logs-archive-201606231300176.tar.gz
-rw-r--r--  1 markneedham  wheel   8.6K 23 Jun 11:49 foo/database-agent-mac19b6b-1-logs-archive-201606231049507.tar.gz
-rw-r--r--  1 markneedham  wheel   8.6K 23 Jun 11:49 foo/database-agent-mac1f427-1-logs-archive-201606231049507.tar.gz
-rw-r--r--  1 markneedham  wheel   2.5K 23 Jun 14:00 foo/database-agent-mac29389-1-logs-archive-201606231300176.tar.gz
-rw-r--r--  1 markneedham  wheel    11K 23 Jun 13:44 foo/database-agent-mac3533f-1-logs-archive-201606231244152.tar.gz
-rw-r--r--  1 markneedham  wheel   4.8K 23 Jun 14:00 foo/database-agent-mac35563-1-logs-archive-201606231300176.tar.gz
-rw-r--r--  1 markneedham  wheel   3.8K 23 Jun 13:44 foo/database-agent-mac35f7e-1-logs-archive-201606231244165.tar.gz
-rw-r--r--  1 markneedham  wheel   4.8K 23 Jun 14:00 foo/database-agent-mac40798-1-logs-archive-201606231300176.tar.gz
-rw-r--r--  1 markneedham  wheel    12K 23 Jun 13:44 foo/database-agent-mac490bf-1-logs-archive-201606231244151.tar.gz
-rw-r--r--  1 markneedham  wheel   2.5K 23 Jun 14:00 foo/database-agent-mac5f094-1-logs-archive-201606231300189.tar.gz
-rw-r--r--  1 markneedham  wheel   5.8K 23 Jun 14:00 foo/database-agent-mac636b8-1-logs-archive-201606231300176.tar.gz
-rw-r--r--  1 markneedham  wheel   9.5K 23 Jun 11:49 foo/database-agent-mac7e165-1-logs-archive-201606231049507.tar.gz
-rw-r--r--  1 markneedham  wheel   2.7K 23 Jun 11:49 foo/database-agent-macab7f1-1-logs-archive-201606231049507.tar.gz
-rw-r--r--  1 markneedham  wheel   2.8K 23 Jun 13:44 foo/database-agent-macbb8e1-1-logs-archive-201606231244151.tar.gz
-rw-r--r--  1 markneedham  wheel   3.1K 23 Jun 11:49 foo/database-agent-macbcbe8-1-logs-archive-201606231049520.tar.gz
-rw-r--r--  1 markneedham  wheel    13K 23 Jun 13:44 foo/database-agent-macc8177-1-logs-archive-201606231244152.tar.gz
-rw-r--r--  1 markneedham  wheel   3.8K 23 Jun 13:44 foo/database-agent-maccd92c-1-logs-archive-201606231244151.tar.gz
-rw-r--r--  1 markneedham  wheel   3.9K 23 Jun 13:44 foo/database-agent-macdf24f-1-logs-archive-201606231244165.tar.gz
-rw-r--r--  1 markneedham  wheel   3.1K 23 Jun 11:49 foo/database-agent-mace075e-1-logs-archive-201606231049520.tar.gz
-rw-r--r--  1 markneedham  wheel   3.1K 23 Jun 11:49 foo/database-agent-mace8859-1-logs-archive-201606231049507.tar.gz

I wanted to split the files in half so that I could have the ones created before and after 12pm on the 23rd June.

I discovered that this type of filtering is actually quite easy to do with the ‘find’ command. So if I want to get the files after 12pm I could write the following:

$ find foo -name database-agent* -newermt "Jun 23, 2016 12:00" -ls
121939705        8 -rw-r--r--    1 markneedham      wheel                2524 23 Jun 14:00 foo/database-agent-mac17f73-1-logs-archive-201606231300176.tar.gz
121939704        8 -rw-r--r--    1 markneedham      wheel                2511 23 Jun 14:00 foo/database-agent-mac29389-1-logs-archive-201606231300176.tar.gz
121934591       24 -rw-r--r--    1 markneedham      wheel               11294 23 Jun 13:44 foo/database-agent-mac3533f-1-logs-archive-201606231244152.tar.gz
121939707       16 -rw-r--r--    1 markneedham      wheel                4878 23 Jun 14:00 foo/database-agent-mac35563-1-logs-archive-201606231300176.tar.gz
121934612        8 -rw-r--r--    1 markneedham      wheel                3896 23 Jun 13:44 foo/database-agent-mac35f7e-1-logs-archive-201606231244165.tar.gz
121939708       16 -rw-r--r--    1 markneedham      wheel                4887 23 Jun 14:00 foo/database-agent-mac40798-1-logs-archive-201606231300176.tar.gz
121934589       24 -rw-r--r--    1 markneedham      wheel               12204 23 Jun 13:44 foo/database-agent-mac490bf-1-logs-archive-201606231244151.tar.gz
121939720        8 -rw-r--r--    1 markneedham      wheel                2510 23 Jun 14:00 foo/database-agent-mac5f094-1-logs-archive-201606231300189.tar.gz
121939706       16 -rw-r--r--    1 markneedham      wheel                5912 23 Jun 14:00 foo/database-agent-mac636b8-1-logs-archive-201606231300176.tar.gz
121934588        8 -rw-r--r--    1 markneedham      wheel                2895 23 Jun 13:44 foo/database-agent-macbb8e1-1-logs-archive-201606231244151.tar.gz
121934590       32 -rw-r--r--    1 markneedham      wheel               13427 23 Jun 13:44 foo/database-agent-macc8177-1-logs-archive-201606231244152.tar.gz
121934587        8 -rw-r--r--    1 markneedham      wheel                3882 23 Jun 13:44 foo/database-agent-maccd92c-1-logs-archive-201606231244151.tar.gz
121934611        8 -rw-r--r--    1 markneedham      wheel                3970 23 Jun 13:44 foo/database-agent-macdf24f-1-logs-archive-201606231244165.tar.gz

And to get the ones before 12pm:

$ find foo -name database-agent* -not -newermt "Jun 23, 2016 12:00" -ls
121879391       24 -rw-r--r--    1 markneedham      wheel                8856 23 Jun 11:49 foo/database-agent-mac19b6b-1-logs-archive-201606231049507.tar.gz
121879394       24 -rw-r--r--    1 markneedham      wheel                8772 23 Jun 11:49 foo/database-agent-mac1f427-1-logs-archive-201606231049507.tar.gz
121879390       24 -rw-r--r--    1 markneedham      wheel                9702 23 Jun 11:49 foo/database-agent-mac7e165-1-logs-archive-201606231049507.tar.gz
121879393        8 -rw-r--r--    1 markneedham      wheel                2812 23 Jun 11:49 foo/database-agent-macab7f1-1-logs-archive-201606231049507.tar.gz
121879413        8 -rw-r--r--    1 markneedham      wheel                3144 23 Jun 11:49 foo/database-agent-macbcbe8-1-logs-archive-201606231049520.tar.gz
121879414        8 -rw-r--r--    1 markneedham      wheel                3131 23 Jun 11:49 foo/database-agent-mace075e-1-logs-archive-201606231049520.tar.gz
121879392        8 -rw-r--r--    1 markneedham      wheel                3130 23 Jun 11:49 foo/database-agent-mace8859-1-logs-archive-201606231049507.tar.gz

Or we could even find the ones last modified between 12pm and 2pm:

$ find foo -name database-agent* -not -newermt "Jun 23, 2016 14:00" -newermt "Jun 23, 2016 12:00" -ls
121934591       24 -rw-r--r--    1 markneedham      wheel               11294 23 Jun 13:44 foo/database-agent-mac3533f-1-logs-archive-201606231244152.tar.gz
121934612        8 -rw-r--r--    1 markneedham      wheel                3896 23 Jun 13:44 foo/database-agent-mac35f7e-1-logs-archive-201606231244165.tar.gz
121934589       24 -rw-r--r--    1 markneedham      wheel               12204 23 Jun 13:44 foo/database-agent-mac490bf-1-logs-archive-201606231244151.tar.gz
121934588        8 -rw-r--r--    1 markneedham      wheel                2895 23 Jun 13:44 foo/database-agent-macbb8e1-1-logs-archive-201606231244151.tar.gz
121934590       32 -rw-r--r--    1 markneedham      wheel               13427 23 Jun 13:44 foo/database-agent-macc8177-1-logs-archive-201606231244152.tar.gz
121934587        8 -rw-r--r--    1 markneedham      wheel                3882 23 Jun 13:44 foo/database-agent-maccd92c-1-logs-archive-201606231244151.tar.gz
121934611        8 -rw-r--r--    1 markneedham      wheel                3970 23 Jun 13:44 foo/database-agent-macdf24f-1-logs-archive-201606231244165.tar.gz

Or we can filter by relative time e.g. to find the files last modified in the last 1 day, 5 hours:

$ find foo -name database-agent* -mtime -1d5h -ls
121939705        8 -rw-r--r--    1 markneedham      wheel                2524 23 Jun 14:00 foo/database-agent-mac17f73-1-logs-archive-201606231300176.tar.gz
121939704        8 -rw-r--r--    1 markneedham      wheel                2511 23 Jun 14:00 foo/database-agent-mac29389-1-logs-archive-201606231300176.tar.gz
121934591       24 -rw-r--r--    1 markneedham      wheel               11294 23 Jun 13:44 foo/database-agent-mac3533f-1-logs-archive-201606231244152.tar.gz
121939707       16 -rw-r--r--    1 markneedham      wheel                4878 23 Jun 14:00 foo/database-agent-mac35563-1-logs-archive-201606231300176.tar.gz
121934612        8 -rw-r--r--    1 markneedham      wheel                3896 23 Jun 13:44 foo/database-agent-mac35f7e-1-logs-archive-201606231244165.tar.gz
121939708       16 -rw-r--r--    1 markneedham      wheel                4887 23 Jun 14:00 foo/database-agent-mac40798-1-logs-archive-201606231300176.tar.gz
121934589       24 -rw-r--r--    1 markneedham      wheel               12204 23 Jun 13:44 foo/database-agent-mac490bf-1-logs-archive-201606231244151.tar.gz
121939720        8 -rw-r--r--    1 markneedham      wheel                2510 23 Jun 14:00 foo/database-agent-mac5f094-1-logs-archive-201606231300189.tar.gz
121939706       16 -rw-r--r--    1 markneedham      wheel                5912 23 Jun 14:00 foo/database-agent-mac636b8-1-logs-archive-201606231300176.tar.gz
121934588        8 -rw-r--r--    1 markneedham      wheel                2895 23 Jun 13:44 foo/database-agent-macbb8e1-1-logs-archive-201606231244151.tar.gz
121934590       32 -rw-r--r--    1 markneedham      wheel               13427 23 Jun 13:44 foo/database-agent-macc8177-1-logs-archive-201606231244152.tar.gz
121934587        8 -rw-r--r--    1 markneedham      wheel                3882 23 Jun 13:44 foo/database-agent-maccd92c-1-logs-archive-201606231244151.tar.gz
121934611        8 -rw-r--r--    1 markneedham      wheel                3970 23 Jun 13:44 foo/database-agent-macdf24f-1-logs-archive-201606231244165.tar.gz

Or the ones modified more than 1 day, 5 hours ago:

$ find foo -name database-agent* -mtime +1d5h -ls
121879391       24 -rw-r--r--    1 markneedham      wheel                8856 23 Jun 11:49 foo/database-agent-mac19b6b-1-logs-archive-201606231049507.tar.gz
121879394       24 -rw-r--r--    1 markneedham      wheel                8772 23 Jun 11:49 foo/database-agent-mac1f427-1-logs-archive-201606231049507.tar.gz
121879390       24 -rw-r--r--    1 markneedham      wheel                9702 23 Jun 11:49 foo/database-agent-mac7e165-1-logs-archive-201606231049507.tar.gz
121879393        8 -rw-r--r--    1 markneedham      wheel                2812 23 Jun 11:49 foo/database-agent-macab7f1-1-logs-archive-201606231049507.tar.gz
121879413        8 -rw-r--r--    1 markneedham      wheel                3144 23 Jun 11:49 foo/database-agent-macbcbe8-1-logs-archive-201606231049520.tar.gz
121879414        8 -rw-r--r--    1 markneedham      wheel                3131 23 Jun 11:49 foo/database-agent-mace075e-1-logs-archive-201606231049520.tar.gz
121879392        8 -rw-r--r--    1 markneedham      wheel                3130 23 Jun 11:49 foo/database-agent-mace8859-1-logs-archive-201606231049507.tar.gz

There are lots of other flags you can pass to find but these ones did exactly what I wanted!

Categories: Programming

Beginning An Agile Effort: Breaking Down The Big Picture

26955153324_91f40a31cc_k

How the big picture gets made…

A high-level narrative or story is a good first step in the process of turning an idea into something that delivers real business value.  However, it is only a step along the path through the backlog onion.  Software development (including new development, enhancements, and maintenance work) requires translating the big picture into a product backlog that includes features and epics.  As work progresses the backlog is further decomposed and groomed into user stories and tasks.  The process of moving from any big picture to a backlog in software development follows a predictable pattern.   

  1. Decompose the big picture by identifying the functional and architectural features directly identified or inferred in the story.  This initial step yields a combination of business requirements and the beginning of both the technical and business architecture that will be needed to support the features.  Features of all types are a description of need and outcome and do not represent a decision on how that outcome will be implemented (real options).
  2. Organize the features using a mapping technique such as Agile Story Maps to look for gaps.  Ask yourself and the team whether there are features that needed to achieve the goal identified in the big picture story.  This also a chance for the product owner to reject stories that are not needed to attain the overall goal.
  3. Identify the minimum viable product (MVP). The identification of a minimum viable product at this point identifies the set of features that are needed to deploy a product.  An MVP begins the discussion of priority and a release strategy.  Simply put, features in the MVP will need to be decomposed before features that will be needed later.

An Agile Story Map and an MVP allow a team to cut a wedge into the planning onion that slices from the outer layers directly to the core.  In the Scaled Agile Framework Enterprise (SAFe) the wedge might be called a Product Increment (PI) or a release for efforts using other frameworks and methods.

  1. Features and epics, while easily recognizable, rarely can be tackled by a single team in a single sprint; therefore, they need to be decomposed or split.  The process of decomposing epics and features breaks these large pieces of work into smaller pieces that can be understood and developed within the context of an individual sprint. The backlog of user stories is decomposed as needed so that, as a story gets closer to being accepted into a sprint and developed, the story becomes more and more granular.
  2. Backlog grooming the final step before a story is accepted into a sprint or drawn onto the Kanban board.  Grooming ensures that the story is ready for development (properly formed, sized correctly, understood and have acceptance criteria), and that a team can get started quickly.

The big picture defines the outside of the backlog onion.  However, after we peel the outside of the onion we can cut wedges directly to the core. Slicing wedges, like a minimum viable product, allows a team or teams to decompose and groom only the features and epics immediately needed.  Thereby getting the effort started quickly and effectively.   
Next, a simple example!


Categories: Process Management

Introducing Firebase Authentication

Google Code Blog - Thu, 06/23/2016 - 21:35

Originally posted on Firebase blog

Posted by Laurence Moroney, Developer Advocate and Alfonso Gómez Jordana, Associate Product Manager

For most developers, building an authentication system for your app can feel a lot like paying taxes. They are both relatively hard to understand tasks that you have no choice but doing, and could have big consequences if you get them wrong. No one ever started a company to pay taxes and no one ever built an app just so they could create a great login system. They just seem to be inescapable costs.

But now, you can at least free yourself from the auth tax. With Firebase Authentication, you can outsource your entire authentication system to Firebase so that you can concentrate on building great features for your app. Firebase Authentication makes it easier to get your users signed-in without having to understand the complexities behind implementing your own authentication system. It offers a straightforward getting started experience, optional UX components designed to minimize user friction, and is built on open standards and backed by Google infrastructure.

Implementing Firebase Authentication is relatively fast and easy. From the Firebase console, just choose from the popular login methods that you want to offer (like Facebook, Google, Twitter and email/password) and then add the Firebase SDK to your app. Your app will then be able to connect securely with the real time database, Firebase storage or to your own custom back end. If you have an auth system already, you can use Firebase Authentication as a bridge to other Firebase features.

Firebase Authentication also includes an open source UI library that streamlines building the many auth flows required to give your users a good experience. Password resets, account linking, and login hints that reduce the cognitive load around multiple login choices - they are all pre-built with Firebase Authentication UI. These flows are based on years of UX research optimizing the sign-in and sign-up journeys on Google, Youtube and Android. It includes Smart Lock for Passwords on Android, which has led to significant improvements in sign-in conversion for many apps. And because Firebase UI is open source, the interface is fully customizable so it feels like a completely natural part of your app. If you prefer, you are also free to create your own UI from scratch using our client APIs.

And Firebase Authentication is built around openness and security. It leverages OAuth 2.0 and OpenID Connect, industry standards designed for security, interoperability, and portability. Members of the Firebase Authentication team helped design these protocols and used their expertise to weave in latest security practices like ID tokens, revocable sessions, and native app anti-spoofing measures to make your app easier to use and avoid many common security problems. And code is independently reviewed by the Google Security team and the service is protected in Google’s infrastructure.

Fabulous use Firebase Auth to quickly implement sign-in

Fabulous uses Firebase Authentication to power their login system. Fabulous is a research-based app incubated in Duke University’s Center for Advanced Hindsight. Its goal is to help users to embark on a journey to reset poor habits, replacing them with healthy rituals, with the ultimate goal of improving health and well-being.

The developers of Fabulous wanted to implement an onboarding flow that was easy to use, required minimal updates, and reduced friction with the end user. They wanted an anonymous option so that users could experiment with it before signing up. They also wanted to support multiple login types, and have an option where the user sign-in flow was consistent with the look and feel of the app.

“I was able to implement auth in a single afternoon. I remember that I spent weeks before creating my own solution that I had to update each time the providers changed their API”
- Amine Laadhari, Fabulous CTO.

Malang Studio cut time-to market by months using Firebase Auth

Chu-Day is an application (available on Android and iOS) that helps couples to never forget the dates that matter most to them. It was created by the Korean firm Malang Studio, that develops character-centric, gamified lifestyle applications.

Generally, countdown and anniversary apps do not require users to sign-in, but Malang Studio wanted to make Chu-day special, and differentiate it from others by offering the ability to connect couples so they could jointly countdown to a special anniversary date. This required a sign-in feature, and in order to prevent users from dropping out, Chu-day needed to make the sign-in process seamless.

Malang Studio was able to integrate an onboarding flow in for their apps, using Facebook and Google Sign-in, in one day, without having to worry about server deployment or databases. In addition, Malang Studio has also been taking advantage of the Firebase User Management Console, which helped them develop and test their sign-in implementation as well as manage their users:

“Firebase Authentication required minimum configuration so implementing social account signup was easy and fast. User management feature provided in the console was excellent and we could easily implement our user auth system.”
- Marc Yeongho Kim, CEO / Founder from Malang Studio

For more about Firebase Authentication, visit the developers site and watch our I/O 2016 session, “Best practices for a great sign-in experience.”

Categories: Programming

Designing for Multi-Window

Android Developers Blog - Thu, 06/23/2016 - 18:10

Posted by Ian Lake, Developer Advocate

As a developer, there’s a wide range of features added in Android N to take advantage of, but when it comes to designing and building your UI, having strong multi-window support should be at the forefront.

The primary mode that users will be interacting with multi-window is through split-screen mode, which is available on both handheld devices and larger tablets. In this mode, two apps split the available screen space and the user can drag the divider between the two split screens to resize the apps. As you might imagine, this mode offers some unique design challenges beyond what was needed previously.



An even more responsive UI

The lessons learned from previous versions of Android, the mobile web, and desktop environments still apply to Android N. Designing a responsive UI is still an important first step towards an amazing multi-window experience.

A responsive UI is one that adapts to the size provided, picking the best representation of the content and the appropriate navigation patterns to make a great user experience on any device. Check out the Building a Responsive UI blog post for details on how to design and build an effective responsive UI.

Adapting your layout

As you’re designing layouts for the largest and smallest screens and everything in between, it is important to make resizing a smooth and seamless transition as mentioned in the split screen layout guidelines. If you already have a similar layout between mobile and tablet, you’ll find much of your work taken care of for you.

However, if your mobile and tablet layouts are vastly different and there’s no way to smoothly transition between the two, you should not transition between them when resizing. Instead, focus on making your tablet UI scale down using the same responsive UI patterns. This ensures that users do not have to relearn their UI when resizing your app.

Note that the minimalHeight and minimalWidth layout attributes allow you to set a minimum size you want reported to your Activity, but they do not mean the user cannot resize your activity smaller - it actually means that your activity will be cropped to the size the user requests, potentially forcing elements of your UI off the screen. Strive to support down to the minimum size of 220x220dp.

Design configurations to consider

While many of the sizes and aspect ratios possible in multi-window are similar to existing devices (1/3rd of a landscape tablet is similar to existing mobile devices in screen size), there are a few configurations that are much more common when considering multi-window.

The first is a 16x9 layout on mobile devices in portrait. In this case, the vertical space is extremely limited. If you have a number of fixed elements stacked on top of one another (a toolbar, scrolling content, and a bottom navigation bar), you might find there’s not actually any room for the scrolling content - the most important part!

The second case to consider is the 34.15% layout on tablets. The very wide aspect ratio in device portrait or very tall aspect ratio in device landscape orientation are more extreme than what is found on existing devices. Consider using your mobile layouts as a starting point for this configuration.

Patterns to avoid

When it comes to multi-window, there are a few patterns you want to avoid entirely.

The first is UI interactions that rely on swiping from the edge of the screen. This has already been somewhat of an issue when it comes to the on screen navigation bar prominent on many devices (such as Nexus devices), but is even more so in split-screen mode. Since there is (purposefully) no way to determine if your activity is on the top or bottom or the left or the right, don’t make edge swipes the only way to access functionality in your app. That doesn’t mean you have to avoid them entirely - just make sure there is an alternative. A good example of this is the temporary navigation drawer - an edge swipe opens the drawer, but it is also accessible by pressing the hamburger icon in the toolbar.

The second is disabling multi-window entirely. While there are certainly cases where this makes sense (i.e., it is fundamentally an immersive experience such as a game), there are also cases where your activity and any Activities launched from that Activity are forced to support multi-window. As mentioned in the Preparing for Multi-Window blog post, when you support external apps launching your activity, your activity inherits the multi-window properties of the calling Activity.

Designing for Multi-Window is designing for every device

Building a responsive UI that reacts to the space available is critical to a great multi-window experience, but it is an exercise that can benefit all of your users across the wide variety of Android devices.

So use this as an opportunity to #BuildBetterApps

Follow the Android Development Patterns Collection for more!

Categories: Programming

Product Owners and Learning, Part 3

Part 1 was about how the PO needs to see the big picture and develop the ranked backlog. Part 2 was about the learning that arises from small stories. This part is about ranking.

If you specify deliverables in your big picture and small picture roadmaps, you have already done a gross form of ranking. You have already made the big decisions: which feature/parts of features do you want when? You made those decisions based on value to someone.

I see many POs try to use estimation as their only input into ranking stories. How long will something take to complete? If you have a team who can estimate well, that might be helpful. It’s also helpful to see some quick wins if you can. See my most recent series of posts on Estimation for more discussion on ranking by estimation.

Estimation talks about cost. What about value? In agile, we want to work (and deliver) the most valuable work first.

Once you start to think about value, you might even think about value to all your different somebodies. (Jerry Weinberg said, “Quality is value to someone.”)  Now, you can start considering defects, technical debt, and features.

The PO must rank all three possibilities for a team: features, defects, and technical debt. If you are a PO who has feature-itis, you don’t serve the team, the customer, or the product. Difficult as it is, you have to think about all three to be an effective PO.

The features move the product forward on its roadmap. The defects prevent customers from being happy and prevent movement forward on the roadmap. Technical debt prevents easy releasing and might affect the ease of the team to deliver. Your customers might not see technical debt. They will feel the effects of technical debt in the form of longer release times.

Long ago, I suggested that a specific client consider three backlogs to store the work and then use pair-wise comparison with each item at the top of each queue. (They stored their product backlog, defects, and technical debt in an electronic tool. It was difficult to see all of the possible work.) That way, they could see the work they needed to do (and not forget), and they could look at the value of doing each chunk of work. I’m not suggesting keeping three backlogs is a good idea in all cases. They needed to see—to make visible—all the possible work. Then, they could assess the value of each chunk of work.

You have many ways to see value. You might look at what causes delays in your organization:

  • Technical debt in the form of test automation debt. (Insufficient test automation makes frictionless releasing impossible. Insufficient unit test automation makes experiments and spikes impossible or quite long.)
  • Experts who are here, there, and everywhere, providing expertise to all teams. You often have to wait for those experts to arrive to your team.
  • Who is waiting for this? Do you have a Very Important Customer waiting for a fix or a feature?

You might see value in features for immediate revenue. I have worked in organizations where, if we released some specific feature, we could gain revenue right away. You might look at waste (one way to consider defects and technical debt).

Especially in programs, I see the need for the PO to say, “I need these three stories from this feature set and two stories from that other feature set.” The more the PO can decompose feature sets into small stories, the more flexibility they have for ranking each story on its own.

Here are questions to ask:

  • What is most valuable for our customers, for us to do now?
  • What is most valuable for our team, for us to do now?
  • What is most valuable for the organization, for us to do now?
  • What is most valuable for my learning, as a PO, to decide what to do next?

You might need to rearrange those questions for your context. The more your PO works by value, the more progress the team will make.

The next post will be about when the PO realizes he/she needs to change stories.

If you want to learn how to deliver what your customers want using agile and lean, join me in the next Product Owner workshop.

Categories: Project Management

Introducing the Android Basics Nanodegree

Google Code Blog - Wed, 06/22/2016 - 22:50

Posted by Shanea King-Roberson, Lead Program Manager Twitter: @shaneakr Instagram: @theshanea


Do you have an idea for an app but you don’t know where to start? There are over 1 billion Android devices worldwide, providing a way for you to deliver your ideas to the right people at the right time. Google, in partnership with Udacity, is making Android development accessible and understandable to everyone, so that regardless of your background, you can learn to build apps that improve the lives of people around you.

Enroll in the new Android Basics Nanodegree. This series of courses and services teaches you how to build simple Android apps--even if you have little or no programming experience. Take a look at some of the apps built by our students:

The app "ROP Tutorial" built by student Arpy Vanyan raises awareness of a potentially blinding eye disorder called Retinopathy of Prematurity that can affect newborn babies.

And user Charles Tommo created an app called “Dr Malaria” that teaches people ways to prevent malaria.

With courses designed by Google, you can learn skills that are applicable to building apps that solve real world problems. You can learn at your own pace to use Android Studio(Google’s official tool for Android app development) to design app user interfaces and implement user interactions using the Java programming language.

The courses walk you through step-by-step on how to build an order form for a coffee shop, an app to track pets in a shelter, an app that teaches vocabulary words from the Native American Miwok tribe, and an app on recent earthquakes in the world. At the end of the course, you will have an entire portfolio of apps to share with your friends and family.

Upon completing the Android Basics Nanodegree, you also have the opportunity to continue your learning with the Career-track Android Nanodegree (for intermediate developers). The first 50 participants to finish the Android Basics Nanodegree have a chance to win a scholarship for the Career-track Android Nanodegree. Please visit udacity.com/legal/scholarshipfor additional details and eligibility requirements. You now have a complete learning path to help you become a technology entrepreneur or most importantly, build very cool Android apps, for yourself, your communities, and even the world.

All of the individual courses that make up this Nanodegree are available online for no charge at udacity.com/google. In addition, Udacity provides paid services, including access to coaches, guidance on your project, help staying on track, career counseling, and a certificate upon completion for a fee.

You will be exposed to introductory computer science concepts in the Java programming language, as you learn the following skills.

  • Build app user interfaces
  • Implement user interactions
  • Store information in a database
  • Pull data from the internet into your app
  • Identify and fix unexpected behavior in the app
  • Localize your app to support other languages

To enroll in the Android Basics Nanodegree program, click here.

See you in class!

Categories: Programming

Introducing the Android Basics Nanodegree

Android Developers Blog - Wed, 06/22/2016 - 18:48

Posted by Shanea King-Roberson, Lead Program Manager Twitter: @shaneakr Instagram: @theshanea


Do you have an idea for an app but you don’t know where to start? There are over 1 billion Android devices worldwide, providing a way for you to deliver your ideas to the right people at the right time. Google, in partnership with Udacity, is making Android development accessible and understandable to everyone, so that regardless of your background, you can learn to build apps that improve the lives of people around you.

Enroll in the new Android Basics Nanodegree. This series of courses and services teaches you how to build simple Android apps--even if you have little or no programming experience. Take a look at some of the apps built by our students:

The app "ROP Tutorial" built by student Arpy Vanyan raises awareness of a potentially blinding eye disorder called Retinopathy of Prematurity that can affect newborn babies.

And user Charles Tommo created an app called “Dr Malaria” that teaches people ways to prevent malaria.

With courses designed by Google, you can learn skills that are applicable to building apps that solve real world problems. You can learn at your own pace to use Android Studio (Google’s official tool for Android app development) to design app user interfaces and implement user interactions using the Java programming language.

The courses walk you through step-by-step on how to build an order form for a coffee shop, an app to track pets in a shelter, an app that teaches vocabulary words from the Native American Miwok tribe, and an app on recent earthquakes in the world. At the end of the course, you will have an entire portfolio of apps to share with your friends and family.

Upon completing the Android Basics Nanodegree, you also have the opportunity to continue your learning with the Career-track Android Nanodegree (for intermediate developers). The first 50 participants to finish the Android Basics Nanodegree have a chance to win a scholarship for the Career-track Android Nanodegree. Please visit udacity.com/legal/scholarship for additional details and eligibility requirements. You now have a complete learning path to help you become a technology entrepreneur or most importantly, build very cool Android apps, for yourself, your communities, and even the world.

All of the individual courses that make up this Nanodegree are available online for no charge at udacity.com/google. In addition, Udacity provides paid services, including access to coaches, guidance on your project, help staying on track, career counseling, and a certificate upon completion for a fee.

You will be exposed to introductory computer science concepts in the Java programming language, as you learn the following skills.

  • Build app user interfaces
  • Implement user interactions
  • Store information in a database
  • Pull data from the internet into your app
  • Identify and fix unexpected behavior in the app
  • Localize your app to support other languages

To enroll in the Android Basics Nanodegree program, click here.

See you in class!

Categories: Programming

My Improved Travel Checklist

NOOP.NL - Jurgen Appelo - Wed, 06/22/2016 - 17:20
My Improved Travel Checklist

Last week in London, I wanted to shoot a video, but it appeared that I had left my camera’s memory cards at home. On my previous trip, it had been my Android tablet that I had forgotten to bring with me. The trip before that, it was my stack of local currency, my power adapters, my sunglasses, or whatever, which I hadn’t properly packed.

Sure, I have a travel checklist. But clearly, it had turned into a checklost. With at least 50 confirmed upcoming events around the world, it was time for me to redesign it.

Four Preferred Places

My original checklist was one large unorganized list of reminders. This regularly led to problems because, by scanning the list too quickly, I easily overlooked an item that was buried among all the other things that I only knew too well. So I divided the checklist into four parts:

  • Personal items (that I carry on my body)
  • Shoulder bag
  • Handbag (typically carry on luggage)
  • Extra bag (typically check in luggage)

Each travel item on my improved checklist now has a preferred place. This not only helps to keep the individual lists smaller, and easier to check more carefully, but it also helps me keep things in the right bag. I don’t want to have that situation again where I thought I had my universal adapters or chargers packed in the other bag (but found out later that I hadn’t).

(And preferred means that items can change places depending on context. For example, my keys will have moved to my shoulder bag before I arrive at the airport, while my passport may temporarily move to my pocket while suffering the security and customs rituals.)

Standard versus Extra

Another thing I noticed messing up my packing efforts was that some standard items are by default in my bags (such as passports and adapters), other extra things are by default out of my bags (such as clothes and toiletries), and some items had a Schrödinger-kind of existence, not clearly being in or out, until I opened my bags to have a look (such as device chargers and headphones).

After the reorganization, packing my bags with my improved checklist now consists of two distinct activities:

  1. Checking that all standard items are where they should be;
  2. Adding all extra items to the place where I want them.

Hopefully, this will save me some stress and headaches in the future.

For example, I once had to interrupt my trip to the airport because my passport was not in my bag: it was still under the scanner next to my computer. I always know that my passports are in my shoulder bag, except for the one or two times when, apparently, I was wrong. And thus, I made it a separate activity to check that I am not deceiving myself, thinking that the standard items are where they should be before adding all extra items. And a Schrödinger-kind of existence is not part of the improved design.

Optional Stuff

And then, of course, there are the optional items that mainly depend on the weather forecasts. I remember once nearly freezing to death in Helsinki because I had no warm coat or gloves. I was once drying my clothes in my hotel room in London because, stupidly, I had brought no umbrella. And more than once, I have been sweating in the sun because I was silly enough to bring only dark blue jeans and long-sleeve shirts.

Short versus Long trips

Finally, things can always change a bit depending on context.

On short trips (one or two nights), I don’t need to take the larger bag with me. But this means I must jam any books, running gear, and clean clothes into my hand luggage, which is not always possible, or else just leave some of it at home. And on long trips (ten or more nights), the large bag magically changes into an extra large suitcase, and this also changes what I can bring with me (usually a lot more clothes).

Well, there you have it: the philosophy behind my new-and-improved travel checklist. I include the full list below (as it is now).

Is there anything missing that you have on your travel checklist, and that may be useful for me as well?

Personal
Phone
Wallet
Jacket
House keys
Car keys

Shoulder bag – standard items
Passport(s)
Credit cards and bank cards
Travel cards and loyalty cards
Pens and markers
Presentation clicker
Spare batteries
Memory sticks
Display adapter

Shoulder bag – extra items
Tablet + charger
Headphones
Foreign currency

Handbag – standard items
Spare underwear, socks, and shirt
Spare medicine, contact lenses
GoPro camera
GoPro stick
GoPro batteries
GoPro charger
GoPro memory
GoPro USB
GoPro microphone
Glasses
Sunglasses
Universal adapters
USB chargers
Business cards

Handbag – extra items
Notebook + charger
Underwear
Toiletries
Gloves, scarf, ear muffs [IF forecast = cold]
Umbrella [IF forecast = wet]
Travel clothes [IF distance = long]

Large bag – standard items
Laundry bag

Large bag – extra items
Clothes
Extra shoes
Belt
Running shoes and clothes
Novel
Book / giveaway
Fleece jacket [IF forecast = cold]
Warm socks and sweater [IF forecast = cold]
Raincoat [IF forecast = wet]
Short pants [IF forecast = hot]

photo (c) 2013 Chris Lott, Creative Commons 2.0

My new book Managing for Happiness is available from June 2016. PRE-ORDER NOW!

Managing for Happiness cover (front)

The post My Improved Travel Checklist appeared first on NOOP.NL.

Categories: Project Management

Product Owners and Learning, Part 1

When I work with clients, they often have a “problem” with product ownership. The product owners want tons of features, don’t want to address technical debt, and can’t quite believe how long features will take.  Oh, and the POs want to change things as soon as they see them.

I don’t see this as problems.To me, this is all about learning. The team learns about a feature as they develop it. The PO learns about the feature once the PO sees it. The team and the PO can learn about the implications of this feature as they proceed. To me, this is a significant value of what agile brings to the organization. (I’ll talk about technical debt a little later.)

AgileRoadmap.copyright-1080x794One of the problems I see is that the PO sees the big picture. Often, the Very Big Picture. The roadmap here is a 6-quarter roadmap. I see roadmaps this big more often in programs, but if you have frequent customer releases, you might have it for a project, also.

I like knowing where the product is headed. I like knowing when we think we might want releases. (Unless you can do continuous delivery. Most of my clients are not there. They might not ever get there, either. Different post.)

Here’s the problem with the big picture. No team can deliver according to the big picture. It’s too big. Teams need the roadmap (which I liken to a wish list) and they need a ranked backlog of small stories they can work on now.

Example.AgileRoadmapOneQuarter In Agile and Lean Program Management, I have this picture of what an example roadmap might look like.

This particular roadmap works in iteration-based agile. It works in flow-based agile, too. I don’t care what a team uses to deliver value. I care that a team delivers value often. This image uses the idea that a team will release internally at least once a month. I like more often if you can manage it.

Releasing often (internally or externally) is a function of small stories and the ability to move finished work through your release system. For now, let’s imagine you have a frictionless release system. (Let me know if you want a blog post about how to create a frictionless release system. I keep thinking people know what they need to do, but maybe it’s as clear as mud to  you.)

The smaller the story, the easier it is for the team to deliver. Smaller stories also make it easier for the PO to adapt. Small stories allow discovery along with delivery (yes, that’s a link to Ellen Gottesdiener’s book). And, many POs have trouble writing small stories.

That’s because the PO is thinking in terms of feature sets, not features. I gave an example for secure login in How to Use Continuous Planning. It’s not wrong to think in feature sets. Feature sets help us create the big picture roadmap. And, the feature set is insufficient for the frequent planning and delivery we want in agile.

I see these problems in creating feature sets:

  • Recognizing the different stories in the feature set (making the stories small enough)
  • Ranking the stories to know which one to do first, second, third, etc.
  • What to do when the PO realizes the story or ranking needs to change.

I’ll address these issues in the next posts.

If you want to learn how to deliver what your customers want using agile and lean, join me in the next Product Owner workshop.

Categories: Project Management

Product Owners and Learning, Part 2

In Part 1, I talked about the way POs think about the big picture and the ranked backlog. The way to get from the big picture to the ranked backlog is via deliverables in the form of small (user) stories. See the wikipedia page about user stories. Notice that they are a promise for a conversation.

I talked about feature sets in the first post, so let me explain that here. A feature set is several related stories. (You might think of a feature set as a theme or an epic.) Since I like stories the team can complete in one day or less, I like those stories to be small, say one day or less. I have found that the smaller the story, the more feedback the team gets earlier from the product owner. The more often the PO sees the feature set evolving, the better the PO can refine the future stories. The more often the feedback, the easier it is for everyone to change:

  • The team can change how they implement, or what the feature looks like.
  • The PO can change the rest of the backlog or the rank order of the features.

I realize that if you commit to an entire feature set or a good chunk for an iteration, you might not want to change what you do in this iteration. If you have an evolving feature set, where the PO needs to see some part before the rest, I recommend you use flow-based agile (kanban). A kanban with WIP limits will allow you to change more often. (Let me know if that part was unclear.)

Now, not everyone shares my love of one-day stories. I have a client whose team regularly takes stories of size 20 or something like that. The key is that the entire team swarms on the story and they finish the story in two days, maybe three. When I asked him for more information, he explained this it in this way.

“Yes, we have feature sets. And, our PO just can’t see partial finishing. Well, he can see it, but he can’t use it. Since he can’t use it, he doesn’t want to see anything until it’s all done.”

I asked him if he ever had problems where they had to redo the entire feature. He smiled and said,

“Yes. Just last week we had this problem. Since I’m the coach, I explained to the PO that the team had effectively lost those three days when they did the “entire” feature instead of just a couple of stories. The PO looked at me and said, “Well, I didn’t lose that time. I got to learn along with the team. My learning was about flow and what I really wanted. It wasn’t a waste of time for me.”

“I learned then about the different rates of learning. The team and the PO might learn differently. Wow, that was a big thing for me. I decided to ask the PO if he wanted me to help him learn faster. He said yes, and we’ve been doing that. I’m not sure I’ll ever get him to define more feature sets or smaller stories, but that’s not my goal. My goal is to help him learn faster.”

Remember that PO is learning along with the developers and testers. This is why having conversations about stories works. As the PO explains the story, the team learns. In my experience, the PO also learns. It’s also why paper prototypes work well. Instead of someone (PO or BA or anyone) developing the flow, when the team develops the flow in paper with the PO/BA, everyone learns together.

Small stories and conversations help the entire team learn together.

Small features are about learning faster. If you, too, have the problem where the team is learning at a different rate than the PO, ask yourself these questions:

  • What kind of acceptance criteria do we have for our stories?
  • Do those acceptance criteria make sense for the big feature (feature set) in addition to the story?
  • If we have a large story, what can we do to show progress and get feedback earlier?
  • How are we specifying stories? Are we using specific users and having conversations about the story?

I’ve written about how to make small stories in these posts:

The smaller the story, the more likely everyone will learn from the team finishing it.

I’ll address ranking in the next post.

If you want to learn how to deliver what your customers want using agile and lean, join me in the next Product Owner workshop.

Categories: Project Management

How to Have Better Fridays

Recently, I’ve been teaching more people Agile Results. 

I teach them really fast, because I just focus on teaching them the most important tool in Agile Results:

Monday Vision, Daily Wins, Friday Reflection

But before I walk through, I share a quick story of how it all started.

Monday Vision was Born for Better Fridays

It was a warm, sunny, Friday afternoon.
My colleague and I were on our way to our favorite pizza place.
It was a beautiful day.  It should have been a great day.
But I felt like a beast of burden with the weight of the world on my back.
Our backlog was overflowing, we didn’t make it through what we thought we would, and we had been slogging away.
And for what?
Well, I caught myself looking in the rear view mirror, more than looking ahead.
Instead of feeling great, I felt like crap.
So I turned to my colleague and asked him how much we realistically have to spend on work when we get back.
We lied to each other and ourselves.  Then we got real.
We figured the best thing we could possibly do would be to prioritize the value we could deliver next week.
With that, we enjoyed our pizza, and when we got back to work, we figured out what a great next week would look like.
I never wanted us to have another Friday where we couldn’t go into weekend feeling good about what we had accomplished for the week.
And that’s how Monday Vision was born.

Monday Vision, Daily Wins, Friday Reflection for Better Fridays

One I tell that little story, people get it pretty quickly.  They’ve been there.  They feel the pain.

They slogged away all week and at the end of the week, instead of feeling good about their achievements, they feel like they haven’t done enough.

They are never done.  They are overwhelmed. 

Instead of feeling like they earned their weekend for rest and relaxation, they feel guilty that they should work on their never-ending backlog and laundry-list of To-Dos.

Monday Vision for Better Fridays

So then I walk them through how to do Monday Vision, so they can have better Fridays.

On Mondays, imagine if it were Friday.  Really step into your future Friday and feel it.   What are Three Wins you really want to have under your belt?

What would you want to be able to say to your manager or to your team or to yourself, about what you accomplished or achieved for the week?

Get clarity on that.

Use that simple story of your Three Wins that you want to be able to talk about on Friday, as your way to prioritize your focus for the week on Monday.

Now you are doing “Monday Vision.”

Daily Wins for Better Fridays

Each day, identify your Three Wins for that day.  This is the “Daily Wins” practice.

You will have those days where your Three Wins might be, “Great Breakfast,” “Great Lunch”, “Great Dinner.”

There will be days that knock you down, and you wonder how you will get back up.

But then you will also have those days where you are on top of the world and your Three Wins for today will be magnificent.

You might even say, they will be your masterpiece.

Either way, get in the habit of starting your day by identifying Three Wins you want to achieve.

That will help you focus and prioritize all that you do in a more meaningful way for results that matter.

If you don’t know how to do this, just imagine if you were closing out your day, what are Three Wins that you want to be able to say you’ve achieved, either to you, your manager, your team or that someone special.

Friday Reflection for Better Fridays

Lastly, there is Friday Reflection.

Friday Reflection is your chance to dig deep and gain some new personal productivity insights.

Ask yourself, “What are three things going well?” and ask yourself, “What are three things to improve?”

Be honest with yourself about your answers.

You are the one that will win or lose from what you learn.

This is your chance to change any long-standing patterns of your personal productivity challenges.

Do you bite off more than you can chew?  Do you get randomized during the week?

Do you have a hard time figuring out what is actually valued?

Use what you learn to feed into next week.  This is your chance to change and practice your Growth Mindset.

Don’t expect any of these exercises to be easy, but they get easier with practice.

And that’s just it.  This isn’t a one-time trick.

This is a very precise set of productivity habits and practices that you can use for your lifetime to master time management, master your energy, master your motivation, and become more of what you are capable of.

Unleash your productivity, the Agile Way.

Best wishes for better Fridays.

Categories: Architecture, Programming

Beginning Agile Efforts: 4 Critical Factors For Team Dynamics

Team Dynamics

Team Dynamics

Teams are a common theme in the discussion of how Agile delivers value.  Teams are a collection of individuals that bring a range of capabilities.  Some people are specialists, others generalists and a very few are  renaissance people that are great at a wide range of activities.  Understanding the depth and breadth of capabilities in team members provides the team with the flexibility to dynamically allocate capabilities based on the technical context and business need (staff liquidity).  This is an incredibly powerful theory that only works if the team dynamics are conducive.  Team dynamics are an expression of how the team interacts with each other and those outside the team. When assessing the dynamics of a team there are many factors that are important; however, a few are more critical than others.

  1. Team Cohesiveness – Cohesiveness is a reflection of how well a team sticks to together to accomplish a goal.  Cohesive teams know each other’s capabilities and capacity.  Cohesiveness is one factor that leads to psychological safety. A feeling of safety  allows team members to take risks without causing insecurity or fear of embarrassment if everything does not work out.  The cohesiveness of the team can be intuited from the length of time a team stays together and how invested team members are in the success of the team.
  2. Roles and Norms. Even the most Agile team is composed of different people playing different roles. Team performs well when team members recognize the roles that a team needs and then serve in those roles and are comfortable shifting roles when needed by the team. Roles include technical tasks, as well as roles such as leader, researcher and reviewer.  Clarity of roles norms helps build trust within the team and outside the team.  Trust reinforces team cohesion.  Roles and norms can be best assessed by an outsider by observing the teamwork. Alternately, retrospectives can be used to surface discussions of potential role and norm problems.  
  3. Conflict Resolution.  All teams will have conflict. Teams need to have a pallet of conflict resolution techniques.  Conflict resolutions techniques can include simple  talking, active listening, multi-voting, cost/benefit analysis or coaching. Teams need to prepare for inevitable conflict both by being aware of the signs of conflict and then have the wherewithal to deal  the conflict.  Observation can tell a coach a lot about a team’s ability deal with conflict. Alternately, one means to assess how a team will react is to give them a scenario and ask how they would solve the problem (this is a backdoor mechanism to teach resolution techniques).  Teams with a good capability for conflict resolution will tend to be more cohesive and struggle less with roles.  
  4. Impactful Goals.  Work that the team believes is important both to the organization and team members is motivating.  Motivation provides teams with a well of energy that can be invested in delivering value, resolving conflict, playing the roles that are needed and working together. The simplest way to know whether a team believes the goal they are pursuing is impactful is to ask and then to listen to the emotion in the answer. If there is no emotion, the team does not perceive what they are doing as important.

The four most critical drivers of Agile team dynamics can be assessed by observing and talking with the team.  The right dynamics will unlock a team’s potential; however most can’t get there without a help.  Coaching based on interacting and observing the team is a very powerful tool to give teams the tools needed to become more effective.  When beginning an Agile effort, spend the time and effort needed to tune every team to the four critical factors of team dynamics so they have the best start possible.


Categories: Process Management

Improving Stability with Private C/C++ Symbol Restrictions in Android N

Android Developers Blog - Tue, 06/21/2016 - 21:33

Posted by Dimitry Ivanov & Elliott Hughes, Software Engineers

As documented in the Android N behavioral changes, to protect Android users and apps from unforeseen crashes, Android N will restrict which libraries your C/C++ code can link against at runtime. As a result, if your app uses any private symbols from platform libraries, you will need to update it to either use the public NDK APIs or to include its own copy of those libraries. Some libraries are public: the Native Development Kit (NDK) exposes libandroid, libc, libcamera2ndk, libdl, libGLES, libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++, libvulkan, and libz as part of the NDK API. Other libraries are private, and Android N only allows access to them for platform HALs, system daemons, and the like. If you aren’t sure whether your app uses private libraries, you can immediately check it for warnings on the N Developer Preview.

We’re making this change because it’s painful for users when their apps stop working after a platform update. Whether they blame the app developer or the platform, everybody loses. Users should have a consistent app experience across updates, and developers shouldn’t have to make emergency app updates to handle platform changes. For that reason, we recommend against using private C/C++ symbols. Private symbols aren’t tested as part of the Compatibility Test Suite (CTS) that all Android devices must pass. They may not exist, or they may behave differently. This makes apps that use them more likely to fail on specific devices, or on future releases --- as many developers found when Android 6.0 Marshmallow switched from OpenSSL to BoringSSL.

You may be surprised that there’s no STL in the list of NDK libraries. The three STL implementations included in the NDK -- the LLVM libc++, the GNU STL, and libstlport -- are intended to be bundled with your app, either by statically linking into your library, or by inclusion as a separate shared library. In the past, some developers have assumed that they didn’t need to package the library because the OS itself had a copy. This assumption is incorrect: a particular STL implementation may disappear (as was the case with stlport, which was removed in Marshmallow), may never have been available (as is the case with the GNU STL), or it may change in ABI incompatible ways (as is the case with the LLVM libc++).

In order to reduce the user impact of this transition, we’ve identified a set of libraries that see significant use from Google Play’s most-installed apps, and that are feasible for us to support in the short term (including libandroid_runtime.so, libcutils.so, libcrypto.so, and libssl.so). For legacy code in N, we will temporarily support these libraries in order to give you more time to transition. Note that we don't intend to continue this support in any future Android platform release, so if you see a warning that means your code will not work in a future release -- please fix it now!

Table 1. What to expect if your app is linking against private native libraries.

Libraries App's targetSdkVersion Runtime access via dynamic linker Impact, N Developer Preview Impact, Final N Release Impact, future platform version NDK Public Any Accessible Private (graylist) <=23 Temporarily accessible Warning / Toast Warning Error >=24 Restricted Error Error Error Private (all other)> Any Restricted Error Error Error

What behavior will I see?

Please test your app during the N Previews.

  • N Preview behavior
    • All public NDK libraries ( libandroid, libc, libcamera2ndk, libdl, libGLES, libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++, libvulkan, and libz), plus libraries that are part of your app are accessible.
    • For all other libraries you’ll see a warning in logcat and a toast on the display. This will happen only if your app’s targetSdkVersion is less than N. If you change your manifest to target N, loading will fail: Java’s System.loadLibrary will throw, and C/C++’s dlopen(3) will return NULL.

  • N Final Release behavior
    • All NDK libraries ( libandroid, libc, libcamera2ndk, libdl, libGLES, libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++, libvulkan, and libz), plus libraries that are part of your app are accessible.
    • For the temporarily accessible libraries (such as libandroid_runtime.so, libcutils.so, libcrypto.so, and libssl.so), you’ll see a warning in logcat for all API levels before N, but loading will fail if you update your app so that its targetSdkVersion is N or later.
    • Attempts to load any other libraries will fail in the final release of Android N, even if your app is targeting a pre-N platform version.
    • Future platform behavior
      • In O, all access to the temporarily accessible libraries will be removed. As a result, you should plan to update your app regardless of your targetSdkVersion prior to O. If you believe there is missing functionality from the NDK API that will make it impossible for you to transition off a temporarily accessible library, please file a bug here.
What do the errors look like?

Here’s some example logcat output from an app that hasn’t bumped its target SDK version (and so the restriction isn’t fully enforced because this is only the developer preview):

03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so" ("/system/lib/libandroid_runtime.so") needed or dlopened by "/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible for the namespace "classloader-namespace" - the access is temporarily granted as a workaround for http://b/26394120

This is telling you that your library “libapplib.so” refers to the library “libandroid_runtime.so”, which is a private library.

When Android N ships, or if you set your target SDK version to N now, you’ll see something like this if you try to use System.loadLibrary from Java:

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so" ("/system/lib/libcutils.so") needed or dlopened by "/system/lib/libnativeloader.so" is not accessible for the namespace "classloader-namespace" at java.lang.Runtime.loadLibrary0(Runtime.java:977) at java.lang.System.loadLibrary(System.java:1602)

If you’re using dlopen(3) from C/C++ you’ll get a NULL return and dlerror(3) will return the same “dlopen failed...” string as shown above.

For more information about how to check if your app is using private symbols, see the FAQ on developer.android.com.

Categories: Programming

Grow your business on Google Play with help from the new Playbook for Developers app

Android Developers Blog - Tue, 06/21/2016 - 18:47

Posted by Dom Elliott, the Google Play team

Today, the Playbook for Developers mobile app is now generally available for Android devices. The app helps you stay up-to-date with the features and best practices to grow your business on Google Play. Thanks to all our beta testers over the last six weeks whose feedback helped us tweak and refine the app in preparation for launch.

Here’s how you read and watch content in the Playbook for Developers app:

  • Choose topics relating to your business interests to personalize My Playbook with curated articles and videos from Google and experts across the web.
  • Explore the in-depth guide to Google’s developer products, with articles grouped by what you’re trying to do: develop, launch, engage, grow, and earn.
  • Take actions on items – complete, share, save, or dismiss them – and read your Saved articles later, including offline if they’re written in the app. A data connection will be needed to read articles and videos from across the web.

The app supports Android 5.0 and above. We will be adding and updating content in the app to help you stay up-to-date and grow your business. Get the Playbook for Developers app today and then give us your feedback. The app is also available in the following languages: Bahasa Indonesia, Deutsch, español (Latinoamérica), le français, português do Brasil, tiếng Việt, русский язы́к, 한국어, 中文 (简体), 中文 (繁體), and 日本語.

This is the second app we’ve released for Google Play developers. Get the Google Play Developer Console app to review your app's performance statistics and financial data, get notified about your app's status and publishing changes, and read and reply to user reviews on the go.

Categories: Programming

Incentives and Deterrents for Starting Daily Scrums On Time

Mike Cohn's Blog - Tue, 06/21/2016 - 15:00

I recently emailed everyone who subscribes to my weekly tips a list of suggestions for ways to motivate team members to arrive on time to the daily scrum. For example, many teams have a rule that if you arrive late, you put a dollar in a jar as punishment for being late. Ideally the collected money is donated to a charity at the end of a project or after it reaches a certain amount.

I included a number of other techniques I’ve seen Scrum Masters use. Many were similar to paying a dollar in that they were punishments for being late. Wow, did I get called out for that. The general argument was that a Scrum Master should use an incentive for being on time rather than a punishment for being late.

That’s a really good point. But I have to say that in the vast majority of teams I’ve seen, they use a punishment rather than an incentive. Many of the punishments involve at least the potential for embarrassing the offender--sing a song, do a pushup, tell a joke, etc.

I’ve thought about why this is. It may be because it’s more natural (for many of us?) to harass the one rule-breaker than reward everyone else. Or maybe it’s because embarrassing the late arriver by making that person sing (for example) is more fun for everyone else.

Incentives Rather than Punishments

I do think, though, that it’s a great suggestion that we look for incentives rather than punishments. Besides, punishment may be too strong of a term. I was told by a couple of people that deterrent might be the better term.

In fact, Rob Dull pointed out an underlying benefit to using a deterrent, saying, “It's sooo healthy for people to be able to be silly/awkward in front of their teammates.”

Others considered the entire idea “stupid,” as one email I received succinctly put it. While others pointed out that the only real fix is to tap into an intrinsic motivation to get latecomers to arrive on time.

Isaias Fritsch took that type of approach by preparing a 30-minute presentation for the team on the importance of the daily scrum. He said that after that presentation, the team decided to come up with some changes to their daily scrum approach. The result of this has been that “the daily scrum is now way more interesting to everyone because relevant information is shared and everyone understands its importance/why we are doing it.”

Ted Morris Dawson had an interesting take on the punishment vs. incentive idea. One technique he has used was if all team members are on time for all daily scrums, then it’s the Scrum Master who does the embarrassing thing like sing, tell a joke or so on. Yikes!

So with the idea that we can help teams overcome the problem through either deterrents or incentives, I’ve split the suggestions I was emailed into lists of each.

Deterrents
  • Read a tongue-twister to the team (“Seventy-seven benevolent elephants” or “Scum-sucking scrum teams scrounge scrumptious scraps.”)
  • Dance alone without music for five seconds. Rob Dull reported, “It's quick, amusing for everyone, and it's a healthy encouragement of vulnerability.”
  • Bring coffee or a snack for the team the next day. Be careful--a few people emailed about gaining weight from this one! :)
  • Have a “tardy board” as Nadine Sullivan called it that tracks late arrivals or absences. Add rules like everyone is allowed one late arrival during some period. But after reaching some number of late arrivals or absences, the person has to bring something in such as a snack for the team.
  • Toss a beach ball, stuffed animal or some other item to the person who is to speak next. Throw, don’t toss, it at any late arrivers.
  • Buy the team an afternoon snack or tea.
  • Present a 30-minute knowledge sharing session on a topic. This was pointed out as being particularly helpful in team building.
  • Facilitate the next review or retrospective.
  • Facilitate the next daily scrum, meaning everyone is waiting for tomorrow’s meeting to start if today’s late arriver is late again.
  • Be the team’s “slave for a day” by doing things like getting snacks, soda and coffee for anyone who needed anything from the kitchen.
  • Take detailed, precise notes for the meeting.
  • Solve a tricky math problem on the board.
  • Buy a book for the office library. How about one one my books? :)
  • Close the door. A late arriver has to open it to enter, which focuses attention on the person.
  • Take on a short (perhaps 15-minute) administrative task the team needs done.
  • Simply put an indicator to each person’s name on a wall to show how frequently each team member was late.
Incentives
  • Reward the first people to arrive with small bits of chocolate.
  • Collect a dollar or two for being late, but when the money is donated to a charity, donate it in the name of the person who arrived first at the meeting most often. Since charitable contributions are tax deductible in many countries, this gives incentives for being early and for not being late. Or as Michel Biron pointed out, it was both “carrot and stick.”
  • Give everyone who was prompt for each daily scrum a reward like a two-hour lunch or permission to come in late and leave early one day.
  • Everyone who was on time for each daily scrum goes to a movie during the day, one day during the next sprint.
  • Establish a policy of “if one of us is late, we’re all late,” and then provide a significant team reward to everyone if everyone is on time. One person told me he did this, but extended it to include being on time for all meetings. He knew that it would be hard to do, so he needed a significant motivation and they agreed on a nice lunch paid for by the company. As a consolation prize, if team members were only on time 90 percent of the time, everyone would receive a chocolate bar.

    I was told, “The result even surprised me. The team completely shifting their behavior. I was seeing team members loading up the digital agile board and setting up the conference connection for the remote team members minutes in advance of the standup. The team was holding each other accountable by friendly shoulder taps to make sure they all make it on time. I even observed a team member running across the building to grab someone out of a meeting to make sure she also makes it on time as well.”
  • Ice cream if everyone is on time every time.
  • A photo of the team holding a sign saying: “We did it!”
  • Start the meeting 15 minutes before everyone wants to go to lunch. Viktor Buzga reports that the company cafeteria in his company gets very crowded at 11:30 when it opens. Arrive at 11:30 and there’s no wait for lunch. Arrive two minutes later and there’s a 10-minute wait. So he starts daily scrums at 11:15. If the team finishes in 10-12 minutes, they’re perfectly timed for lunch. If not ...

So, there are many ways you can go about this. And, as I said in my emailed weekly tip, I love getting the chance to learn from all of you. I definitely learned some good techniques from this. Also, I’ve learned that I really should think more about incentives rather than deterrents.

Whatever you choose to do, you really need to make sure the entire team buys into it. The last thing you want is for someone to go to human resources complaining that you’re making him do a pushup for every minute he arrives late to a meeting.

But, for a team on which being late is a problem, these approaches can help address the problem. A common thread in many replies I received was that many of these incentives and deterrents work especially well because the entire team starts holding each other accountable. This is a huge benefit over just a Scrum Master holding people accountable.

What Do You Think?

What’s missing? What other techniques have you tried to encourage people to be on time for daily scrums? Please share your thoughts in the comments below.

Agile Hiring, Load Testing & Goal Management in Methods & Tools Summer 2016 issue

From the Editor of Methods & Tools - Tue, 06/21/2016 - 08:02
Methods & Tools has published its Summer 2016 issue that discusses hiring for agility, load testing scripts errors, managing with goals on every level and Behavior-Driven Development (BDD) with the open source Turnip tool. Methods & Tools is a free e-magazine for software developers, testers and project managers. * Hiring for Agility – Mindset Matters […]

How to Keep flowtype Running and Report Errors on Save

Xebia Blog - Tue, 06/21/2016 - 08:00
We use flow from Facebook to run type checking on our codebase. When you run ‘flow status’ it starts a flow server in the background and keeps it running. That way after the first run the results of each next run are almost instant. The only thing currently lacking is a watch mode, but there

Control, Stability, Short Term, Long Term all needed for Success

Herding Cats - Glen Alleman - Tue, 06/21/2016 - 02:27
Single Track

When riding a single track like this one behind our neighborhood, I came to an understand of the tradeoffs between stability and control. In our conference sessions, we speak about how the Wright Brothers learned this concept as well.

Nationals Here's another trail being ridden by our son at Nationals in 2013. who's massively better than I will ever be. But same tradeoff between stability and control is needed to be ranked 33rd Cross Country and 23rd Short Track at DII in the nation, with team taking 2nd overall.

In both cases, nationally ranked and rank amaetur, control of bike is the key. Stability is a relative term, depending on speed, terrain, skill, risk taking tolerance,  experience, technical equipment, and other intangible factors.

We speak at conference where program planning and controls is the topic. Starting 2 years ago, our foundation for speaking about managing in the presence of  uncertanty is the Wright Brothers.

Most earlier experimenters in powered flight focused only on one or two of the primary problems - (a) A set of lifting surfaces, or wings, (b) A method of balancing and controlling the aircraft, and (c) A means of propulsion -  and did not consider the final design from the outset. The Wrights recognized that each of these areas had to be successfully addressed to build a working airplane. They believed that the aerodynamic and propulsion problems would be comparatively easier to solve, so they first concentrated on how to maintain balance and control.

Many believed that air currents were too swift and unpredictable for human reflexes. Therefore, an aircraft had to be inherently stable for the pilot to be able to maintain control. Because of the Wrights’ extensive experience with the bicycle—a highly unstable but controllable machine (just like the mountain bike)—they saw no reason why an airplane could not be unstable yet controllable as well.

The notion of Control is missed used in software development projects. Misused and misunderstood. Control inside the upper and lower control bounds is a critical success factor. What are those upper and lower control bounds? Good question. They have to be estimated in the start. They become cleared as the project progresses. They have to be adjusted as new information emerges.

In projects, the question for Stability is a false quest. All project work is uncertain. Stability is short lived. New inputs arrive every day. Just like new inputs arrive while riding down the flat trail for cruising around the open space in the neighborhood or more so on the bumpy high speed trail of collegiate racing.

Even if the trail is defined in from of you, the small disruptions and many times big distributions input your control of the bike. The key is Control over Stability. Staying in control will get you across the finish line, down the trail, and home again to ride another day.

Skills of Maintaining Control on the Mountain Bike and the Project

Starting from our house there is a nice loop Left Hand Trail, that is easy, has a few climbs, and a few descents, uncrowded, and provides a nice view of the small hills before the real mountains start . Combine that with the Eagle Trail, Sage Trail, and North Rim Trail and it's a nice 7 mile loop

  1. Short term feedback - what's happening right in front of me? What do I need to do NOW to maintain stability, to survive for the next 10 feet on the trail 
    • On projects, short term feedback is for the next day or week.
    • What's coming due?
    • A Plan of the Week or even a Plan of the Day is  very useful.
  2. Long term feedback - I see things coming on the trail. A big drop. A huge climb. What am I going to do to prepare for both? Do I have a plan of action to get through these?
    • On projects, I need to see this coming before I am Overcome By Events (OBE). The term OBE is used often in our domain. It says, they didn't see it coming. They didn't have a plan to respond to emerging events.
    • The naive term in agile of respond to emerging requirements means you have to have a plan to meet that emerging requirement. If you don't, just like on the bike, you're going to end  up on the side to the trail, landing on a cactus  or worse a snake where we live.
  3. Corrective actions - what corrective actions am I capable of performing? On the bike, I must know my limits. Can I power through the steep climb? Maybe if it's short. No likley if it's 1/2 mile at 18% grade.
    • On projects knowing the limits of the team is a critical success factor.
    • Who can work the problem with the most rapid response? Who's got skills and experience needed to power through till we get back in control
  4. Alternative choices - as the trial unfolds in front of me, choices present themselves. Some are optional, some are mandatory alternatives. Other riders coming up the trail have to be addressed. If their coming up hill and I'm going down hill, they have the right-of-way. I can easily start again going down hill. Stopping and starting again going up hill is a real pain. Obstacles on the trail have to be dealt with. In the spring branches hang in th trail from the trees and bushes. Many have sharp leaves or thorns, riding through them is painful.
    • On project having alternatives is also mandatory. 
    • Nothing ever goes right as planned. Having an alternative ready to go, means when trouble arrives, there is no delay in making a choice to take another path.
  5. Estimate what's right in front of you - the trail is rough, bumpy, rutted, off camber, muddy, thorny, and many times some animal runs across my path - rabbitt, prairie dog, a snake. A quick estimate is needed to decide what to do. Keep going, speed up, slow down, stop? All depends on the situation.
    1. Estimating on projects is part of the close loop control system.
    2. Both project controls and business control depend on making estimates in the presence of uncertanty about future outcomes.
    3. These estimates keep the project Green, just like estimates on the bike keep me rubber side down.
  6. Estimates of needed for solutions coming up the trail - with short term estimating there are a limited number of choices, bounded by the physical terrain. For longer term choices, there are more options. Do I turn left at the next opportunity, go over the mesa, then back down to rejoin the trial at the parking lot of the hiking trailhead? 
    • For projects a longer view of what's coming is needed.
    • Points of integration or incorporation need to be in the Plan.
    • Alternative Points of Incorporation (APOI) are needed as well.
    • Many time these APOI are part of the master plan, since external facilities may be booked, resources become scarce, technology changes. 
    • A  Plan B is needed as part of the normal process
  7. Estimates of needed resources - food, water, spare equipment are part of the normal riding gear. For really big rides, Bear Spray is common, since we live in Bear Country. Energy resources must be managed. Knowing how fast you can go, when is the next resting spot, next shady spot?
    • The resource plan for the project is needed no matter the method used to develop the project.
    • What skills, how many of those skills, the availability of those skills? 
  8. Estimates to complete - rarely do we go out without some plan of when we'll be back. This means some estimate of when we'll be back. Telling wife's we're going up to Hygiene and we'll be back in 2 hours is always good protocol. 
    • On projects knowing something about when you plan to finish is part of managing the project.
    • Anyone working on a project that doesn't have some type of deadline is working on a de minimis project - it's too small for anyone to care about when you'll be down.
    • Same for the budget
    • Same for the needed technical performance.
  9. A Plan B and even a Plan C - planning in depth is a good idea when riding anywhere. The longer the ride, the steeper the terrain, the higher the exposure, means having more plans to deal with the emerging situations
    • Without a plan, you're driving in the dark with the lights off.
    • What ever comes up is likely to be a surprise.
    • While surprises are nice for birthday parties, surprises 25 miles out from home, with a 25 mile return can turn unpleasant real quick.
    • Planning in depth is always a good idea.
    • Knowing the Value at Risk defines the magnitude and detail of the plan. If the impact is minimal and can be handled with a few changes, no problem. If the impact is major, having a detailed plan when it occurs is the basis of success
    • Risk Management is How Adults Manage Projects Tim Lister should never be forgotten
  10. Knowledge of capacity for workhow big is a big ride? Good question. When we have friends ask hey want to go for a ride, I have to make sure I have the capacity for work. Our neighborhood has many cyclist. A Silver Medalist rider. A semi-pro road rider. A former pro road rider. A semi-pro mountain biker all the way down to casual riders like me and our group. Know what the ride will demand and what I'm capable of doing is a starting point. Along the way reassessing both those informs decisions about routes, pace, and overall strategy to get home in one piece
    • On projects, if we don't our capacity for work, we can't make informed estimates if we can get to the end in one piece.
    • If we bite off more than we can chew, then we're going to be late and over budget before we start.
    • Know our capacity for work comes from past performance.
    • But it also means estimating what we can do, knowing that past performance, and he future demands for work.
Related articles Late Start = Late Finish Eyes Wide Shut - A View of No Estimates All The World's A Random Process Project Risk Management, PMBOK, DoD PMBOK and Edmund Conrow's Book Architecture -Center ERP Systems in the Manufacturing Domain Staying on Plan Means Closed Loop Control Strategy is Not the Same as Operational Effectiveness Estimating Processes in Support of Economic Analysis Qualitative Risk Management and Quantitative Risk Management
Categories: Project Management

Quick Summary of Estimating Advice

Herding Cats - Glen Alleman - Mon, 06/20/2016 - 23:23

There's lots of misinformation going around again in the #NoEstimates community

  • We can't estimate things we've never done before - this is simply not true. There is not much that hasn't been done before in some form. If you truly haven't done the work before, you're probably not the right person to be estimating for those wanting to pay you. 
  • Estimates are guesses, because we don't know that the future is - this is a fundamental error, either of commision or omission) on how estimates are made.
  • Just deliver often in small chunk and we won't need to estimate - this of course ignores the need to produce an Estimate To Complete and an Estimate At Completion.
  • Estimates are a waste, we should be coding to generate value for the customerthe customer has a fiduciary need to know how much it will cost to get that value and when that value will be delivered. This is core business. If there is no need to know estimated cost and schedule, the project is likely a de minimis effort, or the customer has enough money to burn to not care about how much and when.
  • Deadlines kill innovation and reduce quality - this is only true of your a really bad planner. All project work is probabilistic. This probabilistic (and statistical) behaviour mandates a plan to manage in the presence of uncertainty. Bout reducible and irreducible uncertainties have specific handling plans. Either margins to protect from the naturally occurring  variances or specific buy down activities to protect against probabilistic occurrences of undesirable outcomes. 

Here's the starting point to clarify and debunk those concepts

  • How To Estimate Almost Any Software Deliverable in 90 Seconds - this the starting point for learning how to estimate for all software projects. Is it a bigger than a breadbox, or Twenty Questions approach. It's actually a Binary Search approach, that will get you an 85% confidence number in 90- seconds or less. No more excuses for not estimating anything, including things you know nothing about - assuming you are a developer with any experience in the domain. If you have no experience in the domain, then you shouldn't be estimating to begin with - go find someone who is.

Here's some more details, once it's been confirmed you have domain experience

  • How Do You Estimate Work That's Never Been Done Before? - This is a common lament in the #Noestimates community. We've never done this before, so how can we possibly estimate how long it will take? Lot's of ways - Reference Classes, Parametric models. Monte Carlo models of activity networks.
  • Let's Stop Guessing and Learn How to Estimate - estimates are NOT guesses. Estimate - it is an approximation of some value for some purpose, even if the data is incomplete, uncertain, or even unstable. Typically the estimate is derived from a statistical source of data - either observed or referenced in some way.
  • How  to Estimate if you really want to (Updated) - the key here is if you want to. There is NO reason to not estimate. Estimates are need to make decisions in presence of uncertainty. 
  • How to Estimate Almost Anything if You Really Want To  - this starts with what's the coastline of England problem and uses a similar red herring about a hike down the coast of California.

In the end it's simple. Anyone speaking about the difficulties or the waste of estimating is likely on the spend side of the software development equation. Those on the pay side know (or should know) they needed estimates. They can get the estimates from those most qualified to provide them - the developes. Or they can just make them up. Probably better to have a bottom up estimate.

Related articles Humpty Dumpty and #NoEstimates Want To Learn How To Estimate? Let's Stop Guessing and Start Estimating
Categories: Project Management

Notifications in Android N

Android Developers Blog - Mon, 06/20/2016 - 20:10

Posted by Ian Lake, Developer Advocate

Android notifications are often a make-or-break interaction between your Android app and users. To provide a better user experience, notifications on Android N have received a visual refresh, improved support for custom views, and expanded functionality in the forms of Direct Reply, a new MessagingStyle, and bundled notifications.

Same notification, new look

The first and most obvious change is that the default look and feel of notifications has significantly changed. Many of the fields that were spread around the notifications have been collapsed into a new header row with your app’s icon and name anchoring the notification. This change ensured that the title, text, and large icon are given the most amount of space possible and, as a result, notifications are generally slightly larger now and easier to read.


Given the single header row, it is more important than ever that the information there is useful. When you target Android N, by default the time will be hidden - if you have a time critical notification such as a messaging app, you can re-enable it with setShowWhen(true). In addition, the subtext now supersedes the role of content info and number: number is never shown on Android N devices and only if you target a previous version of Android and don’t include a subtext will content info appear. In all cases, ensure that the subtext is relevant and useful - don’t add an account email address as your subtext if the user only has one account, for example.

Notification actions have also received a redesign and are now in a visually separate bar below the notification.


You’ll note that the icons are not present in the new notifications; instead more room is provided for the labels themselves in the constrained space of the notification shade. However, the notification action icons are still required and continue to be used on older versions of Android and on devices such as Android Wear.

If you’ve been building your notification with NotificationCompat.Builder and the standard styles available to you there, you’ll get the new look and feel by default with no code changes required. Better Support for Custom Views

If you’re instead building your notification from custom RemoteViews, adapting to any new style has been challenging. With the new header, expanding behavior, actions, and large icon positioning as separate elements from the main text+title of the notification, we’ve introduced a new DecoratedCustomViewStyle and DecoratedMediaCustomViewStyle to provide all of these elements, allowing you to focus only on the content portion with the new setCustomContentView() method.


This also ensures that future look and feel changes should be significantly easier to adapt to as these styles will be updated alongside the platform with no code changes needed on the app side.

Direct Reply

While notification actions have already been able to launch an Activity or do background work with a Service or BroadcastReceiver, Direct Reply allows you to build an action that directly receives text input inline with the notification actions.


Direct Reply uses the same RemoteInput API - originally introduced for Android Wear - to mark an Action as being able to directly receive input from the user.

The RemoteInput itself contains information like the key which will be used to later retrieve the input and the hint text which is displayed before the user starts typing.

// Where should direct replies be put in the intent bundle (can be any string)
private static final String KEY_TEXT_REPLY = "key_text_reply";

// Create the RemoteInput specifying this key
String replyLabel = getString(R.string.reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
        .setLabel(replyLabel)
        .build();


Once you’ve constructed the RemoteInput, it can be attached to your Action via the aptly named addRemoteInput() method. You might consider also calling setAllowGeneratedReplies(true) to enable Android Wear 2.0 to generate Smart Reply choices when available and make it easier for users to quickly respond.

// Add to your action, enabling Direct Reply for it
NotificationCompat.Action action =
    new NotificationCompat.Action.Builder(R.drawable.reply, replyLabel, pendingIntent)
        .addRemoteInput(remoteInput)
        .setAllowGeneratedReplies(true)
        .build();


Keep in mind that the pendingIntent being passed into your Action should be an Activity on Marshmallow and lower devices that don’t support Direct Reply (as you’ll want to dismiss the lock screen, start an Activity, and focus the input field to have the user type their reply) and should be a Service (if you need to do work on a separate thread) or BroadcastReceiver (which runs on the UI thread) on Android N devices so as the process the text input in the background even from the lock screen. (There is a separate user control to enable/disable Direct Reply from a locked device in the system settings.)

Extracting the text input in your Service/BroadcastReceiver is then possible with the help of the RemoteInput.getResultsFromIntent() method:

private CharSequence getMessageText(Intent intent) {
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    }
    return null;
 }


After you’ve processed the text, you must update the notification. This is the trigger which hides the Direct Reply UI and should be used as a technique to confirm to the user that their reply was received and processed correctly.

For most templates, this should involve using the new setRemoteInputHistory() method which appends the reply to the bottom of the notification. Additional replies should be appended to the history until the main content is updated (such as the other person replying).


However, if you’re building a messaging app and expect back and forth conversations, you should use MessagingStyle and append the additional message to it.

MessagingStyle

We’ve optimized the experience for displaying an ongoing conversation and using Direct Reply with the new MessagingStyle.


This style provides built-in formatting for multiple messages added via the addMessage() method. Each message supports passing in the text itself, a timestamp, and the sender of the message (making it easy to support group conversations).

builder.setStyle(new NotificationCompat.MessagingStyle("Me")
    .setConversationTitle("Team lunch")
    .addMessage("Hi", timestampMillis1, null) // Pass in null for user.
    .addMessage("What's up?", timestampMillis2, "Coworker")
    .addMessage("Not much", timestampMillis3, null)
    .addMessage("How about lunch?", timestampMillis4, "Coworker"));


You’ll note that this style has first-class support for specifically denoting messages from the user and filling in their name (in this case with “Me”) and setting an optional conversation title. While this can be done manually with a BigTextStyle, by using this style Android Wear 2.0 users will get immediate inline responses without kicking them out of the expanded notification view, making for a seamless experience without needing to build a full Wear app.

Bundled Notifications

Once you’ve built a great notification by using the new visual designs, Direct Reply, MessagingStyle, and all of our previous best practices, it is important to think about the overall notification experience, particularly if you post multiple notifications (say, one per ongoing conversation or per new email thread).


Bundled notifications offer the best of both worlds: a single summary notification for when users are looking at other notifications or want to act on all notifications simultaneously and the ability to expand the group to act on individual notifications (including using actions and Direct Reply).

If you’ve built stacking notifications for Android Wear, the API used here is exactly the same. Simply add setGroup() to each individual notification to bundle those notifications together. You’re not limited to one group, so bundle notifications appropriately. For an email app, you might consider one bundle per account for instance.

It is important to also create a summary notification. This summary notification, denoted by setGroupSummary(true), is the only notification that appears on Marshmallow and lower devices and should (you guessed it) summarize all of the individual notifications. This is an opportune time to use the InboxStyle, although using it is not a requirement. On Android N and higher devices, some information (such as the subtext, content intent, and delete intent) is extracted from the summary notification to produce the collapsed notification for the bundled notifications so you should continue to generate a summary notification on all API levels.

To improve the overall user experience on Android N devices, posting 4 or more notifications without a group will cause those notifications to be automatically bundled.

N is for Notifications

Notifications on Android have been a constant area of progressive enhancement. From the single tap targets of the Gingerbread era to expandable notifications, actions, MediaStyle, and now features such as Direct Reply and bundled notifications, notifications play an important part of the overall user experience on Android.

With many new tools to use (and NotificationCompat to help with backward compatibility), I’m excited to see how you use them to #BuildBetterApps

Follow the Android Development Patterns Collection for more!

Categories: Programming