Halloween Costume ideas 2015

Digital archives contain as usually understood by professional archivists and historians.

Latest Post
2009 accessibility Aconcagua Administration Adventure Racing Adventure Travel Adventurists Advice Afghanistan Africa Alaska Alberto Contador Aleutian Islands Alex Honnold Alps Amazon Amherst Amherst Destinations Amherst Hikes Andes Android 1.5 Android 1.6 Android 2.0 Android 2.1 Android 2.2 Android 2.3 Android 2.3.3 Android 3.0 Android 3.2 Android 4.0 Android Design Android Developer Challenge Android Developer Phone Android Market Animals Animation and Graphics Annapurna Announcements Antarctic App Components App Resources Apps Archeology Arctic Arctic Ocean Argentina Art Asia Atacama Desert Atlantic Ocean August Australia Authentication Autumn Aviation Backpacking Backyard Nature Badwater Ultra Baffin Island Baltic Sea BASE Jumping Beach Belchertown Belchertown Destinations Belchertown Hikes Berkshires Best Practices Bhutan Blogging Tips Blogs Book Review Boots Boston Botswana Brazil Broad Peak California Camping Canada Canyoneering Carstensz Pyramid Catatan Puspitasari Central America Central Massachusetts Checkpoint Tracker Children Chile China Cho Oyu Cinta Wanita Circumnavigation Clay Climate Change Climbing Clothing Code Day Colorado Colrain Congo River Connecticut Connectivity Conservation Area Contests Cool Stuff Craft Cycling Dashboard Dave Cornthwaite Death Valley Debugging Denali Developer Console Developer Days Developer Labs Developer profiles Dhaulagiri Dinosaurs Discovery Channel Dolomites Earth Day Easter Island Easthampton Ed Viesturs Educational Eiger El Capitan Endurance Sports Environmental Erving Europe Events Everest Expedition Exploration Explorers Club Fair Fairy House Farm Film Festival Finland Fireworks Fish Hatchery Fitz Roy Food Fourth of July France Free Games Gasherbrum Gaya Hidup Wanita Gear General Adventure Gestures Giro d'Italia Gobi Desert Google I/O Google Play Google Play services Goshen GPS Granby Grand Canyon Greater Boston Greenland Grossology Exhibit Guidelines Hadley Hadley 350th Half Dome Hang Gliding Hawaii Health Hikes Under One Mile Hiking Himalaya History Holyoke Honduras Horse How-to Hubungan Hunting Ice Cream IME impossible2Possible Independence Day India Indoor info Info Seminar Input methods Intents Internet Interview io2010 Italy Japan JNI John Muir Trail Jordan July June Jungfrau K2 K7 Kalahari Kangchenjunga Karakoram Kayaking Kilimanjaro Lake Michigan Lance Armstrong Layout Leadville 100 Leverett Lhotse Libraries Lintas Peristiwa Location Location and Sensors London Long Riders Ludlow Maine Makalu Manaslu Maple Massachusetts Matterhorn Media and Camera Mendon Meru Peak Mexico Mini Golf Mississippi River Missouri River Mongolia Monson Mont Blanc Motivasi Mount Elbrus Mount Everest Mount Rainier Mountain Biking Mountain View Mountaineering Movies Mt. Shasta Munich Museums Music Nameless Tower Namibia Nanga Parbat NASA National Geographic Nature Navigation NDK Nepal New Hampshire New Zealand Newburyport North America North Pole Northampton Northfield Norway Novelet Nuptse Nusantara Nutrition Ocean Okavango Delta Olympics Open source OpenGL ES Optimization Oregon Orizaba Outdoor Outdoor Retailer Outside Magazine Pacific Ocean Packs Paddling Pakistan Palmer Panduan SEO Parade Paragliding Patagonia Pelham Peru Petting Zoo Photography Playground Plum Island Poland Pool Pottery Pumpkins Quabbin Reservoir Quality Quick Search Box Rafting Rahasia Wanita Ray Zahab Reggio Emilia Research Resources Review Road Rally Rowing Roz Savage Running Sailing Sample code Sandbox School Science Scuba Diving SDK updates Sensors September Seven Summits Shelburne Falls Shisha Pangma Shutesbury Silk Road Site News Skateboarding skiing Skydiving Slacklining Sleeping Bags Snowboarding Solstice South Africa South America South Deerfield South Georgia South Hadley South Natick South Pacific South Pole Southern Ocean Space Speech Input Springfield Stand Up Paddling Storytime Strawberries Sturbridge Summer Summer Camp Summit Sunderland Survival Sutton Swimming Switzerland Tanzania Technology Tel Aviv Tents Testing Teva Mountain Games Text and Input Text-to-Speech Thrifty Tibet Torres Del Paine Touch Tour d'Afrique Tour de France Tour Divide Tower Trail Running Train Trango Towers TransRockies Travel Trekking Triathlon Turkey Turner's Falls Tutorial Ueli Steck Ultra Running Ultramarathon UMass United States USA Pro Cycling Challenge User Interface Utah Vancouver Vermont Video Wadi Rum Wakhan Wanita dan Bisnis Water Websites Western Massachusetts Westhampton Widgets Wildlife Williamstown Wingsuits Winter Wisconsin Worcester World Championship Wyoming Yemen Yosemite Zoo

We are pleased to announce that a new open source sample application—called AndroidGlobalTime — has been added to the apps-for-android project.





It's a 3D world clock developed by an engineer at Google and may serve as an illustrative example of how to use the OpenGL ES APIs in your Android applications.



Just a quick word on how to use AndroidGlobalTime. When you launch it, you'll see a spinning globe showing day and night regions. Pressing the space bar will overlay an analog clock with the time corresponding to location you're currently examining. The arrow keys allow you to spin the Earth and traverse through different time-zones while the clock is displayed. Pressing the center key in the emulator toggles between a 3D and 2D view of the earth. Pressing the L key will turn the city lights on or off. You can also zoom-out by pressing 2 and zoom-in by pressing 8.

Hope you find this helpful!

It's been a busy few weeks here as we've wrapped up the first round of the Android Developer Challenge. We'd like to share a couple pieces of information with you:

  • The full list of judges is now available. It was fun to work with such a diverse group of judges from different companies all around the world.
  • A slide deck of the Android Developer Challenge prize recipients is also available. The deck includes descriptions and screenshots of the 46 recipients who consented to sharing their information and is a great way to get a feel for the quality of apps submitted.

The prize recipients' entries were just the tip of the iceberg in terms of great applications submitted, and we'd like to thank and congratulate everyone who entered the challenge. We look forward to seeing all of the application in the hands of consumers with Android devices.

Well, the submission deadline for the first Android Developer Challenge has come and gone, the apps are in, the judges are finished, and the waiting is over. We got a lot of great submissions, and I can tell you personally that the competition was fierce. I didn't see all 1,788 submissions, but I saw quite a lot of them, and I uttered more than one wail of despair as some of my favorite submissions didn't quite make the cut, by razor-thin margins in some cases. But, the judges have spoken.


Speaking of the judges...we'll soon publish a list of who the judges are, but I know many of our developers are still curious: what were all those judges doing? Well, the short answer is that they were judging applications using a custom laptop configuration that we provided. But we thought some people might be interested in the "long" answer, so we put together this blog post. If you're not interested in the gory details of the judging, you can stop here; but if you are interested, read on!


How We Got Started


Making the Challenge fair was by far our primary goal. We knew we had to do whatever we could to make sure that the judges' scores are based solely on their review of the application. We automated as much as possible, to make it easy for judges to focus on judging, and not on administrivia or complicated setup.


The first thing we realized was that we were going to have way more submissions than any single judge could look at. No one could review all 1,788 submissions in a reasonable amount of time. On the other hand, we definitely needed more than one judge reviewing each submission. Our goal was to have each submission reviewed by four different judges, with a minimum of three.


The big question was then: how many judges would we need?


For 1,788 submissions, a panel of 4 judges per application meant that we needed a whopping 7,152 reviews to be performed. Since our judges would have to be crazy to agree to do more than 75 reviews, we needed at least 95 judges. In the end we recruited around 125, including backup judges.


Making Order out of Chaos


The next thing we realized was that judges need to be able to actually review the submissions. Since the judges came from our Open Handset Alliance partners and many are not engineers, we knew that we couldn't send instructions like "run the M5-RC15 emulator, open a terminal window, and run the command adb push geodb /data/misc/location—and don't forget the --sdcard option!" They'd think we were quoting Star Wars.


Besides that, we also knew that once we gave the judges their assignments, what they did was out of our hands. We couldn't control how the judges review the applications, but we could certainly make it as easy as possible for the judges to do a thorough review.


So, we built a program in wxPython that automates judging. This application launches a clean emulator for each submission, supports emulator features like SD card images and mock location providers, and allows judges to launch multiple emulators and simulate calls and SMS messages for applications which need that functionality. We asked our friendly neighborhood Google Tech Stop for 140 laptops, installed Ubuntu Linux and our software on one, and then cloned that installation for use on all the others. We then had a huge shipping party, where we imaged, boxed, and shipped 115 or so laptops in one day.


An important side effect of these custom laptops is that they are all identical. This means that each judge's experience of the submissions was the same, which eliminated the risk of one judge rating an app poorly just because it ran slowly on his personal computer.


Managing All that Data


Once we sent 100+ laptops all over the world, we needed a way to get the data back. Another goal was to eliminate as many sources of human error as possible. With 7,152 reviews to complete, and 4 categories per review, that's 28,608 scores to keep track of. Mistakes would be bound to happen, so filing paperwork or transcribing scores by hand from one file to another was out of the question.


Our solution was the Google Data web API for accessing things like Google Spreadsheets and Google Base. Here's how it worked.


  • We wrote a Python program to randomly assign applications to judges for review.
  • Using the Spreadsheets API, that program generated a Google Spreadsheet for each judge, pre-filled with that judge's assigned submissions and space to enter scores.
  • The program installed on the laptops also used the Spreadsheets API to fetch a given judge's assignments.
  • When the judge scores a submission, those scores were posted back into the spreadsheet.
  • After the judging period concluded, a separate program walks over all the judges' spreadsheets, computing the final scores.

This approach had two great things about it: first, it didn't require any new server infrastructure to make it work. Second, our "database" had a built-in rich "admin" UI for managing the data — namely, Google Spreadsheets itself. If any of our judges ran into problems or needed help, we could simply open that spreadsheet in our browser and review or fix problems.


This approach worked quite well, and I'd bet that the judges didn't even know the Spreadsheets API was being used, unless they actively poked around.


Tying Up the Loose Ends


Of course, our work wasn't done once we retrieved all the submission scores. We couldn't just average up the scores, you see. First, judges could recuse themselves from scoring specific submissions; perhaps they were assigned an application similar to one their own company is working on, or perhaps they realized they knew one of the authors. Second, despite our best efforts there was a chance that some judges might have a problem — for instance, if one judge had a poor network connection but reviewed an application that requires the network, then that judge might have scored the application unfairly poorly.


Here are the major outlier scenarios that we were concerned about:

  • Cases where judges recused themselves.
  • Submissions where one judge reported a problem with the application, but all the other judges reported good scores. (It seems odd for only one judge to have a problem.)
  • Cases where one judge's scores were an outlier compared to the other judges' scores.

For the first two cases, we simply discarded the outlying data points, if we had enough. For instance, if three judges reported good scores and one recused herself, we simply dropped that fourth score. If dropping the conflicting score would have brought the application below three reviews, we sent it back for review by a new judge to bring it up to our minimum number of judges per application.


The third case is more subtle. Just because a judge rated an application differently than others doesn't mean that that review is invalid, so we can't simply discard outliers. Instead, we took the highest and lowest scores in each category and gave them half weight. The effect is to bring the average scores a bit closer to the median scores, which helps minimize the impact of unusually high or low scores. This process was applied to all submissions (not just "suspicious" scores) since it has a minimal effect on submissions that don't have a large outlier.


We actually ran the whole process above twice: first we ran it to choose a first cut of the top 100 submissions from the original 1,788, and we then sent those 100 to a second group of judges for selection of the final 50. (Actually, the "top 100" were really "top 119", since we added a few more submissions to accommodate scoring ties in the first round.)


Wrapping Up


Now you know what we've been spending all our time on, and what's been keeping us up at night (sometimes literally)! Throughout, our key objectives were to keep the process fair, let the judges focus on judging, and give applications the benefit of the doubt in cases of scoring outliers.


What's next? Well, the 50 submissions that were awarded a prize now begin the refinement process for their Round 2 submissions, which will award the final, larger prizes to the top 20 applications. I also hope that the developers of the other great apps that didn't receive prizes will consider the second Android Developer Challenge, which should begin later this year.


To everyone, I'd also like to say thanks for participating, and congratulations on your hard work!

As you may have heard, the results from Android Developer Challenge Part 1, Round 1 were announced to all the participants late last week. We're still working on pulling together a more extensive listing for each application that made it into the top 50, but in the spirit of releasing early and often, here's a list containing the name of the application and its author(s):

  • AndroidScan - Jeffrey Sharkey

  • Beetaun - Sergey Gritsyuk and Dmitri Shipilov

  • BioWallet - Jose Luis Huertas Fernandez

  • BreadCrumbz - Amos Yoffe

  • CallACab - Konrad Huebner and Henning Boeger

  • City Slikkers - PoroCity Media and Virtual Logic Systems

  • Commandro - Alex Pisarev, Andrey Tapekha

  • Cooking Capsules - Mary Ann Cotter and Muthuselvam Ramadoss

  • Diggin - Daniel Johansson, Aramis Waernbaum, Andreas Hedin

  • Dyno - Virachat Boondharigaputra

  • e-ventr - Michael Zitzelsberger

  • Eco2go - Taneem Talukdar, Gary Pong, Jeff Kao and Robert Lam

  • Em-Radar - Jack Kwok

  • fingerprint - Robert Mickle

  • FreeFamilyWatch - Navee Technologies LLC

  • goCart - Rylan Barnes

  • GolfPlay - Inizziativa Networks

  • gWalk - Prof. Dr.-Ing. Klaus ten Hagen, Christian Klinger, Marko Modsching, Rene Scholze

  • HandWx - Weathertop Consulting LLC

  • IMEasy - Yan Shi

  • Jigsaw - Mikhail Ksenzov

  • JOYity - Zelfi AG

  • LifeAware - Gregory Moore, Aaron L. Obrien, Jawad Akhtar

  • Locale - Clare Bayley, Christina Wright, Jasper Lin, Carter Jernigan

  • LReady Emergency Manager - Chris Hulls, Dilpreet Singh, Luis Carvalho, Phuong Nguyen

  • Marvin - Pontier Laurent

  • Mobeedo - Sengaro GmbH

  • Multiple Facets Instant Messenger - Virgil Dobjanschi

  • MyCloset - Mamoru Tokashiki

  • PedNav - RouteMe2 Technologies Inc.

  • Phonebook 2.0 - Voxmobili

  • PicSay - Eric Wijngaard

  • PiggyBack - Christophe Petit and Sebastien Petit

  • Pocket Journey - Anthony Stevens and Rosie Pongracz

  • Rayfarla - Stephen Oldmeadow

  • Safety Net - Michael DeJadon

  • SocialMonster - Ben Siu-Lung Hui and Tommy Ng

  • SplashPlay

  • Sustain- Keeping Your Social Network Alive - Niraj Swami

  • SynchroSpot - Shaun Terry

  • Talkplay - Sung Suh Park

  • Teradesk - José Augusto Athayde Ferrarini

  • The Weather Channel for Android - The Weather Channel Interactive Inc.

  • TuneWiki - TuneWiki Inc.

  • Wikitude-the Mobile Travel Guide - Philipp Breuss

  • Writing Pad - ShapeWriter Inc

Those of you following along carefully at home (or who bothered to read this far) will notice that there's only 46 in this list. 4 winners opted to continue their efforts in secret and so while we congratulate them too, we can't list them here.

Regardless, congratulations to all those who made it this far!

The last few weeks were both extremely intense and rewarding. Based on feedback from the judges, it was apparent that large number of applications were compelling, innovative and well implemented. The quality of these entries clearly reflects the creativity and hard work that developers have invested in building their apps.

In addition to developers' participation and contributions, over 100 industry judges around the world spent weeks reviewing these submissions. I want to thank all the developers and judges who have worked incredibly hard over the last few months, making the Android Developer Challenge such a success.

Many of the top submissions took advantage of the geo and social networking capabilities of Android. These applications allow friends to share their personal experiences and favorite content such as vacations, photos, shows, music, cooking recipes, restaurants, and much more as they relate to certain locales. I've also seen applications that connect people during emergency situations and others that allow users to share information on how they can reduce their carbon footprint. One developer even turned a real city block into a playing field where gamers can role-play and chase after villains.

Furthermore, some of these applications provide rich interactive experiences by combining web services and mash-ups to bring together data that's on the web with data that's on the mobile device. One application combined weather, pollen and allergy information in the context of a map that is relevant to a user's location.

Though many applications use a traditional "download" model for data, many also enable users to publish content, such as photos or even voice memos, for others to use on other mobile devices or the web.

This is just a brief snapshot of the many impressive applications I've seen. The 50 highest scoring applications will receive $25,000 each and go on to compete in the final round. We plan to publish a list of these applications as soon as we receive the developers' consent. The real winners, however, are the consumers who will benefit from the work of these talented developers.

I'm thrilled to share the news that developers from over 70 countries submitted 1,788 entries to the Android Developer Challenge!

Here are a few facts that I thought were interesting. When we announced the Android Developer Challenge back in January, developers started submitting entries right away but it wasn't until the April 14 deadline approached that the flood really began. The rate of submissions spiked in the wee hours of Tuesday morning, reaching as high as 170+ submissions per hour.

What I find truly amazing is how global the interest in the challenge has been. Developers from the United States submitted one-third of the total applications while the rest came from countries such as Germany, Japan, China, India, Canada, France, UK, and many others. The entries are also very diverse representing many application areas, from games to social-networking applications, to utilities, to productivity and developer tools, and many more. On behalf of the Open Handset Alliance, I want to thank everyone who has submitted entries to the challenge. We look forward to reviewing all of them.

Now that the applications are in, over 100 judges will soon receive judging packets and laptops that we've preloaded with all the submissions, for a consistent, fair environment to judge the submissions. The majority of the judges are from member companies of the Open Handset Alliance, in addition to non-alliance mobile industry experts who have all graciously volunteered their time. I'd like to thank these judges too for all the time they will be putting into this.

In May, we'll be informing the 50 Semi-finalists who will be awarded $25,000 each. Until then, the team and I will have our hands full.

We have received a few inquiries regarding the judges who will be evaluating entries to the Android Developer Challenge (ADC). All Entries will be judged by a panel of experts in the fields of mobile devices, cellular telecommunications, software development, and/or technology innovation ("Judges"). Google will select the Judges from the member organizations of the Open Handset Alliance, Google and/or mobile experts.

As a reminder, the deadline for the Android Developer Challenge is April 14, 2008. We're really looking forward to seeing what you've created so make sure you submit in time. Good luck!

Spring is on the way, and temperatures are rising. We're no exception, and things are starting to heat up over here in Android-land, too.


The Android Developer Challenge deadline is approaching quickly. Wow, that's strange to me. On one hand, we've come so far that the first announcement back on November 12 seems like a prior geologic era, but on the other hand it seems like the Challenge just started! But it's been five months, so it's time to finish your code, polish your UI, and submit your application. Remember to submit by midnight on April 14th, PST (GMT-8).


But after the Challenge, what's next? Well, on the 28th and 29th of May we have Google I/O. This is the biggest Google developer event of the year, and you can bet that the Androids will be there in numbers.


Here are the sessions we've prepared on Android.

  • Android 101: Building an Application
  • Anatomy & Physiology of an Android
  • Dalvik Internals
  • Inside the Android Application Framework
  • Building Great UIs with Android
  • Internationalizing Android Applications
  • Location, Location, Location
  • Mobile Mashups
For more details on these sessions, visit the Google I/O site. Please do, in fact—I'm really excited by some of these because we're going to go into a level of detail that we haven't before. Ever wanted to hear the tech lead on Dalvik talk about Dalvik? Ever wanted an exhaustive review of the i18n/resource system? Then don't miss this event.


Besides the technical sessions, there will be a Fireside Chat with as many members of the Android team as we can rustle up, and an Android section in the demo and coding area. (Personally, I'm looking forward to that the most: it's shaping up to be a code festival of mammoth proportions.) If you need a break from Android, there are also tons of sessions on other developer technologies from Google, too.


We intend this to be the premier developer event for Android, this year. If you only go to one Android event, we humbly suggest that you consider this one. Early-bird registration ends TODAY (April 4th), so be sure to sign up soon.


I'll see you there!

Originally by Sung Hu Kim, Product Marketing Manager for Android, Google mobile team


As some of you may have heard, Wireless Week has chosen the Open Handset Alliance and Android for its Emerging Technology Award, noting that "Android's potential promises openness and innovation, perhaps changing not only the mobile Internet but the Internet itself."


We at Google would like to congratulate all the members of the Open Handset Alliance and the fantastic Android developer community for this well deserved recognition. Android's growing momentum is the result of an amazing effort and collaboration among many different people.

Coincidentally, this week marks five months since the Open Handset Alliance and Android first went public. A lot has happened in this short period of time. Among the things of note:
  • We released an early look at the Android software development kit (SDK), allowing anyone to learn and start creating apps for the platform.
  • Feedback from developers has contributed to numerous fixes, improvements, new tools, and major updates to the SDK, the latest version of which you can find here.
  • Google announced the Android Developer Challenge, which will provide $10 million in total awards for the best Android apps—and the first phase has nearly wrapped up. (Be sure to get your submissions in by April 14!)
  • Several companies gave the first working demonstrations of Android in February.

These have been an exciting first 5 months, and we look forward to making the coming months even better.

In the last article, we talked about using Linkify to turn wiki words (those that match a regular expression we defined) into a content: URI and defining a path to data that matched a note belonging to that wiki word. As an example, a matching word like ToDoList would be turned into a content: URI like content://com.google.android.wikinotes.db.wikinotes/wikinotes/ToDoList and then acted upon using the VIEW action from the Linkify class.



This article will examine how the Android operating system takes this combination of VIEW action and content: URI and finds the correct activity to fire in order to do something with the data. It will also explain how the other default links created by Linkify, like web URLs and telephone numbers, also result in the correct activity to handle that data type being fired. Finally, this article will start to examine the custom ContentProvider that has been created to handle WikiNotes data. The full description of the ContentProvider and what it does will span a couple more articles as well, because there is a lot to cover.



The Linkify-calls-intent Workflow


At a high level, the steps for Linkify to invoke an intent and for the resulting activity (if any) to handle it looks like this:




  1. Linkify is invoked on a TextView to turn matching text patterns into Intent links.

  2. Linkify takes over monitoring for those Intent links being selected by the user.

  3. When the user selects a link, Linkify calls the VIEW action using the content: URI associated with the link.

  4. Android takes the content: URI that represents the data, and looks for a ContentProvider registered in the system that matches the URI.

  5. If a match is found, Android queries the ContentProvider using the URI, and asks what MIME type the data that will be returned from the URI is.

  6. Android then looks for an activity registered in the system with an intent-filter that matches both the VIEW action, and the MIME type for the data represented by the content: URI.

  7. Assuming a match is found, Linkify then invokes the intent for the URI, at which point the activity takes over, and is handed the content: URI.

  8. The activity can then use the URI to retrieve the data and act on it.



If this sounds complicated, it really is a simpler process than it sounds, and it is quite lightweight as well. Perhaps a more understandable statement about how it works might be:



Linkify is used to turn matching text into hot-links. When the user selects a hot-link, Android takes the data locator represented by the hot-link and looks for a data handler for that data locator. If it finds one, it asks for what type of data is returned for that locator. It then looks for something registered with the system that handles that type of data for the VIEW action, and starts it, including the data locator in the request.



The real key here is the MIME type. MIME stands for Multipurpose Internet Mail Extensions - a standard for sending attachments over email. The MIME type (which is the part Android uses) is a way of describing certain kinds of data. That type is then used to look for an Activity that can do something with that data type. In this way, ContentProviders and Activities (or other IntentReceivers) are decoupled, meaning that a given Content URI might have a different ContentProvider to handle it, but could still use the same MIME type meaning that the same activity could be called upon to handle the resulting data.



Linkify on a Wiki Word



Using the above workflow, let's take a look at exactly how the process works in WikiNotes for Android:



First, Linkify is used to turn text matching the wiki word regular expression into a link that provides a Content URI for that wiki word, for example content://com.google.android.wikinotes.db.wikinotes/wikinotes/ToDoList.



When the user clicks on the wiki word link, Linkify invokes the VIEW action on the Content URI. At this point, the Android system takes over getting the Intent request to the correct activity.



Next, Android looks for a ContentProvider that has been registered with the system to handle URIs matching our Content URI format.



In our case, we have a definition inside our application in the AndroidManifest.xml file that reads:



<provider name="com.google.android.wikinotes.db.WikiNotesProvider" 
android:authorities="com.google.android.wikinotes.db.wikinotes" />


This establishes that we have a ContentProvider defined in our application that provides the "root authority": com.google.android.wikinotes.db.wikinotes. This is the first part of the Content URI that we create for a wiki word link. Root Authority is just another way of thinking about a descriptor that is registered with Android to allow requests for certain URLs to be routed to the correct class.



So, the whole definition is that a class called com.google.android.wikinotes.db.WikiNotesProvider is registered with the system as able to handle the com.google.android.wikinotes.db.wikinotes root authority (i.e. URIs starting with that identifier).



From here, Android takes the rest of the URI and present it to that ContentProvider. If you look at the WikiNotesProvider class and scroll to the very bottom - the static block there, you can see the pattern definitions to match the rest of the URL.



In particular, take a look at the two lines:



URI_MATCHER.addURI(WikiNote.WIKINOTES_AUTHORITY, "wikinotes", NOTES);
URI_MATCHER.addURI(WikiNote.WIKINOTES_AUTHORITY, "wikinotes/*", NOTE_NAME);


These are the definitions of URIs that our ContentProvider recognizes and can handle. The first recognizes a full URI of content://com.google.android.wikinotes.db.wikinotes/wikinotes and associates that with a constant called NOTES. This is used elsewhere in the ContentProvider to provide a list of all of the wiki notes in the database when the URI is requested.



The second line uses a wildcard - '*' - to match a request of the form that Linkify will create, e.g. content://com.google.android.wikinotes.db.wikinotes/wikinotes/ToDoList. In this example, the * matches the ToDoList part of the URI and is available to the handler of the request, so that it can fish out the matching note for ToDoList and return it as the data. This also associates that match with a constant called NOTE_NAME, which again is used as an identifier elsewhere in the ContentProvider.



The other matches in this static block are related to forms of searching that have been implemented in the WikiNotes for Android application, and will be covered in later articles. Likewise, how the data is obtained from this matching pattern will be the subject of the next article.



For right now we are concerned with the MIME type for the URI. This is defined in the getType() method also in the WikiNotesProvider class (about half way through the file). Take a quick look at this. The key parts for now are:



case NOTES:
return "vnd.android.cursor.dir/vnd.google.wikinote";


and

case NOTE_NAME:
return "vnd.android.cursor.item/vnd.google.wikinote";


These are the same constant names we defined in our pattern matchers. In the first case, that of the all notes URI, the MIME type returned is vnd.android.cursor.dir/vnd.google.wikinote which is like saying an Android list (dir) of Google wiki notes (the vnd bit is MIME speak for "vendor specific definition"). Likewise, in the case of a NOTE_NAME match, the MIME type returned is vnd.android.cursor.item/vnd.google.wikinote which is like saying an Android item of Google wiki notes.



Note that if you define your own MIME data types like this, the vnd.android.cursor.dir and vnd.android.cursor.item categories should be retained, since they have meaning to the Android system, but the actual item types should be changed to reflect your particular data type.



So far Android has been able to find a ContentProvider that handles the Content URI supplied by the Linkify Intent call, and has queried the ContentProvider to find out the MIME types for that URI. The final step is to find an activity that can handle the VIEW action for that MIME type. Take a look in the the AndroidManifest.xml file again. Inside the WikiNotes activity definition, you will see:



<intent-filter>
<action name="android.intent.action.VIEW"/>
<category name="android.intent.category.DEFAULT"/>
<category name="android.intent.category.BROWSABLE"/>
<data mimetype="vnd.android.cursor.item/vnd.google.wikinote"/>
</intent-filter>


This is the correct combination of matches for the VIEW action on a WikiNote type that is requested from the LINKIFY class. The DEFAULT category indicates that the WikiNotes activity should be treated as a default handler (a primary choice) for this kind of data, and the BROWSABLE category means it can be invoked from a "browser", in this case the marked-up Linkified text.



Using this information, Android can match up the VIEW action request for the WikiNotes data type with the WikiNotes activity, and can then use the WikiNotes activity to handle the request.



Why do it like this?



It's quite a trip through the system, and there is a lot to absorb here, but this is one of the main reasons I wanted to write WikiNotes in the first place. If you follow and understand the steps here, you'll have a good grasp of the whole Intents mechanism in Android, and how it helps loosely coupled activities cooperate to get things done.



In this case, we could have found another way to detect wiki words based on a regular expression, and maybe written our own handler to intercept clicks within the TextView and dig out the right data and display it. This would seem to accomplish the same functionality just as easily as using intents, so what is the advantage to using the full Intents mechanism?



In fact there are several advantages:



The most obvious is that because we are using the standard Intent based approach, we are not limited to just linking and navigating to other wiki notes. We get similar behavior to a number of other data types as well. For example, a telephone number or web URL in a wiki note will be marked up by Linkify, and using this same mechanism (VIEW action on the linked data type) the browser or dialer activities will be automatically fired.



It also means that each operation on a wiki note can be treated as a separate life cycle by our activity. We are not dealing with swapping data in and out of an existing activity - each activity works on a particular wiki note and that's all you have to worry about.



Another advantage is that we now have a public activity to handle VIEW actions in WikiNotes no matter where the request comes from. Another application could request to view a wiki note (perhaps without even knowing what kind of data it is) and our activity could start up and handle it.



The backstack is automatically maintained for you too. As you forward navigate through WikiNotes, Android maintains the history of notes visited, and so when you hit the back button you go back to the last note you were on. All this is free because we rely on the Android intents mechanism.



Finally, if you run WikiNotes for Android and then start DDMS to take a look at the Activity threads in the WikiNotes application while it is running, you can see that despite what you might think, letting Android manage the navigation is very efficient. Create a few linked notes, as many links deep as you like, and then follow them. If you follow links hundreds of notes deep, you will still only see a handful of WikiNotes activities. Android is managing the activities, closing the older ones as necessary and using the life cycle to swap data in and out.



Next Time



This was a long article, but necessarily so. It demonstrates the importance of the Intents mechanism and to reinforce the notion that it should be used whenever possible for forward navigation, even within a single application. Illustrating this is one of the primary reasons I wrote WikiNotes for Android in the first place.



In the next article we will look deeper into the ContentProvider and examine how it turns a Content URI into a row (or several rows) of data that can be used by an activity.

MKRdezign

Contact Form

Name

Email *

Message *

Powered by Blogger.
Javascript DisablePlease Enable Javascript To See All Widget