Appstore Blogs

Appstore Blogs

Want the latest?

appstore topics

Recent Posts

Archive

July 08, 2012

Amazon Mobile App Distribution Program

With the launch of the Amazon Mobile App Distribution Portal for international distribution, we'd like to talk about how to get your Android apps ready for an international audience.

Localization is the process of making your app display appropriate resources depending on the device's default locale and language. "Appropriate Resources" can include more than text. Depending on your app, you may also want to change:

  • Number and date formatting
  • Currency formatting
  • Colors and layout styles
  • Input methods

Localization is a big topic, so we'll focus on those resources that impact customers the most: text, images, and currency.

Each Android device has a default locale which consists of a region and language, which you can query programmatically. Fortunately, this is seldom necessary. Since Android is designed to be used on a variety of platforms, it looks for resources that are appropriate for the current execution environment. For example, you may already provide different bitmaps or backgrounds for your app based on the device's pixel density. As long as the resources are in the right directory (e.g., drawable-hdpi), Android will select the best resource for the job.

Localization works the same way – by putting your resources in the correct folder, Android will find the right one at runtime, without you having to write additional code. The simplest example is one you are probably familiar with: /res/values/strings.xml. The strings.xml file is designed to hold your user-viewable strings in such a way that they can be used by reference. Here is a sample definition in strings.xml:

 <?xml version="1.0" encoding="utf-8"?>

<resources>

  <string name="hello">Hello!</string>

</resources>

The string resource named "hello" can be referenced in your source code by calling:

String helloText = getString(R.id.hello);

And in other XML files (such as layout or the manifest) by referencing:

<application android:label="@string/hello" >

Now suppose you want to provide a better user experience for new customers who speak French or German. Simply create a new version of strings.xml for each language, and put them in their own "values" directory. The format is: values-xx-rYY, where 'xx' is the ISO-639 language code, and 'YY' is the ISO-3166-1 region code.

/res

      /values     (default directory, make sure all references are present)

      /values-fr  (contains French language strings, region not used)

      /values-de  (contains German language strings, region not used)

When Android looks for a string reference, it will try to match a resource that is specific to a region and language, then by language, then in the default directory (values). It is extremely important to make sure all of your string references are in the default directory.

If Android fails to find a reference after searching the default directory, your program will force close!


Once the references are defined in the defaults, your language-specific files can define the strings you want to localize in that language. For example, some language speakers are comfortable with a mix of English and their native tongue, while others speakers expect a full translation.

Not all UI presentation is done using strings, and many apps have menus, price lists, or instructions written as bitmaps or other graphical data. Fortunately, the same dynamic resource handling we just saw with strings applies to resources in the drawable folders as well.

/res

      /drawable

      /drawable-fr      (contains German language strings, region not used)

      /drawable-de      (contains German language strings, region not used)

If you already have several drawable directories with resources based on pixel density, you can further extend the structure to accommodate language. The resource directory name modifiers (locale, pixel density, screen size, screen orientation, etc.) can be chained together:

      /drawable-fr-ldpi

      /drawable-fr-mdpi

If you find yourself reusing drawable assets (putting duplicate copies of bitmaps in several folders, for example), Android provides a way to "link" a reference to a binary using an XML file in the drawable directory.

Suppose you want the resource named "background" in the Great Britain locale to point to a resource in the default drawable directory. Save the following file as "/drawable-en-rGB/background.xml":

<?xml version="1.0" encoding="utf-8"?>

        <bitmap xmlns:android="http://schemas.android.com/apk/res/android"

        android:src="@drawable/background_common" />

Any reference to "background" that resolved to that directory (drawable-en-GB) would automatically use the resource: /drawable/background_common.

Lastly, we'll look at an example where we display the price of our IAP items in local format. The most important elements are the currency symbol, and the decimal divider:

€19,95                   // in some European locales

$19.95                   // in North America

Let's say your app uses the IAP API to fetch a price for an item from the regional store. The API will give you a price that you can parse to a float. Wouldn't it be nice to have an object that takes care of the number formatting for you? As it turns out, Android provides a NumberFormat object for this purpose.

To get the formatted String, make the following calls:

NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.getDefault());

       String formattedPrice = nf.format(19.99f);

This is formatting only, and does not do currency value conversion. If you decide to use a locale other than the default, make sure you define it using both language and region (e.g., en_US, or fr_FR). Otherwise you won't get the correct formatting. For example, there are many countries using French as their primary language and have different currencies.

As mentioned before, localization is a deep topic – we've barely scratched the surface. Check back for additional tips to improve the customer experience as you distribute your apps around the world.

June 28, 2012

Amazon Mobile App Distribution Program

 Jeff Hines, Kindle Fire test team, and Chirag Mehta, a2z Developer Center Inc., an Amazon.com company, are our bloggers for this post.

This fourth post in our Top 10 App Optimizations for Kindle Fire series involves optimizations that allow for successful installation on Kindle Fire.

While all too common, installation failures are easily preventable. Rather than by coding errors, installation failures result from a misunderstanding of the device software, features, and capabilities. This post contains helpful optimizations that address prominent issues preventing installation on Kindle Fire.

What version of the Android platform does Kindle Fire utilize?

When developing an app exclusively for Kindle Fire, ensure that your app is developed using the correct Software Development Kit (SDK) version. Many apps fail to install because they were developed to operate within a different version of the Android SDK platform.

If your app requires a different SDK version than what is used by Kindle Fire, then you will see an error similar to the following:

“…Could not parse package (at Binary XML file line #11): Requires newer sdk version #13 (current version is #10)”

To properly optimize your app for Kindle Fire, you should specifically target Android 2.3.4 - API Level 10.

If you have designed your app to install on Kindle Fire and multiple devices running other versions of the Android SDK, simply adjust the minimum Android Program Interface (API) Level within your manifest:

<uses-sdk android:minSdkVersion="10"
          android:targetSdkVersion="13" />

Be aware that you can set the maximum API value by utilizing android:maxSdkVersion=”X”. However, we do not recommend blocking installation on future versions of the Android SDK, as all newer versions of the platform are backwards compatible.

If you intend to have your app exclusive to Kindle Fire, then you may simply equalize the minimum and target values:

<uses-sdk android:minSdkVersion="10"
          android:targetSdkVersion="10" />

 

For more information on declaring API values within your manifest, visit http://developer.android.com/guide/topics/manifest/uses-sdk-element.html

Kindle Fire and Google Mobile Services (GMS)

If you have packaged your app using Google Mobile Services (GMS) such as the Google Maps library, then your app will not install on Kindle Fire. Unlike some other Android devices, GMS are not present on Kindle Fire.

When trying to install an app that requires GMS, you may encounter the following error:

“…requires unavailable shared library com.google.android.maps; failing!”

While the Google Maps library is not present on the Kindle Fire, you may still connect to Google Maps via Wi-Fi. Otherwise, if your app must have offline mapping, then we recommend developing your app to utilize an alternative mapping service. 

If your app is fully functional without GMS support, we recommend disabling the service entirely by removing the line of code from the manifest that links to the library.

Depending on your app’s functionality, you may also need to modify your mapping features to gracefully degrade (e.g., with an error message such as “This feature is not currently available on this device”). If you plan to implement an alternate mapping service in an updated version, then you might use a message such as, “This feature is not currently available at this time.”

Be aware that if your app also uses in-app purchasing technology powered by Google Mobile Services, this functionality will not work on Kindle Fire. Amazon now directly offers an alternative In-App Purchasing API that allows easy access to purchasable digital content and subscriptions. Please refer to our In-App Purchasing section of the Developer FAQ for more information.

Continue to check back in for our next post in this series which will cover optimizations that target graphical performance on Kindle Fire.

June 27, 2012

Amazon Mobile App Distribution Program

Brett Taylor, Principal Product Manager, Amazon Web Services, and David Lane, Principal of Business Development, Amazon Kindle, are our guest bloggers for this post.

With its unique “split browser” architecture, the Amazon Silk web browser builds upon the power and capabilities of the Amazon Web Services (AWS) cloud to fundamentally rethink the level of performance and functionality that a browser can provide. Since the Kindle Fire launched, in late 2011, Silk has consistently been one of the most popular device applications. As web traffic originating from Silk continues to grow, many site owners have asked for guidance on how to ensure a great customer experience in our browser.

This post lists a few of the more common questions we’ve received from site owners and the prescriptive guidance that we’ve shared with them. If you have additional questions that we haven’t addressed, we encourage you to submit them here. We’ll continue to monitor your inquiries and post updates as needed.

 

1.       What is the Amazon Silk user agent string?

Amazon Silk will supply one of two user agent strings in the request headers. The first is referred to as the “desktop” user agent. This user agent string indicates that the browser is requesting the standard desktop version of the page.

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/[browser version]) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=[true or false]

The second user agent is referred to as the “mobile” user agent. This user agent string indicates that the browser is requesting the mobile view of the web page.

Mozilla/5.0 (Linux; U; Android Android version; Silk/[browser version]) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 Silk-Accelerated=[true or false]

The browser version section of the user agent string will change with each new version of the Amazon Silk browser.

The Silk-Accelerated parameter will be set to either true or false. If it is set to “false,” the request is being made directly to origin (i.e., it has not been routed through the Amazon Silk EC2 backend). If this parameter is set to “true,” the request may be routed through the Amazon Silk EC2 backend.

2.       What is the client’s IP address?

In cases where the Silk-Accelerated parameter is set to “false,” the source IP address of the request can be obtained as it normally would be on any HTTP request.

However, in cases where the Silk-Accelerated parameter is set to “true,” the source IP address of the request will be the IP address of the Amazon Silk EC2 backend server. In this case the source IP address of the end client is supplied in the x-forwarded-for request header.

Please be aware that each request from a single end user may be routed through different EC2 servers. In other words a web site may receive a series of requests from different source IP addresses but with the same x-forwarded-for header.

Additionally, a single Amazon Silk EC2 backend server will support multiple end users. This means that a web site may see requests with the same source IP address but different x-forwarded-for headers.

 

3.       Does Amazon Silk support the Adobe Flash plug-in?

Version 10.3 of the Adobe Flash plug-in comes preinstalled on the Amazon Silk browser. In the most recent version of Amazon Silk (v 1.0.13.81) the Adobe Flash plug-in was disabled by default. Users can enable the plug-in by selecting the “Enable Flash” option in the browser settings menu.

Amazon Silk version numbers where Flash was enabled by default contain a hyphen. Version numbers with no hyphen have Flash disabled by default.

Web developers who wish to present Flash content to Amazon Silk users should check whether the Flash plug-in is enabled. If it is, Flash content can be safely presented to the user. If Flash is not enabled, the web developer should either present alternate content to the user (much like they would to iPad users) or present a message asking the user to enable the Flash plug-in in the settings menu.

Given Adobe’s announcement that it will discontinue support for the Flash plug-in on mobile devices, we are recommending that site owners transition to HTML5 video. Below are a set of steps to help solve for this issue going forward:

As part of website optimizations for Kindle devices and the Silk Browser, we are recommending a set of steps to help solve for non-Flash video playback.

  • Ideally, your site would detect whether or not Flash is available on the device
  • As a fallback, you can look for the Silk user agent (details above)
    • When Silk is detected, use an HMTL5 video playback element rather than Flash video
  • If HMTL5 video is not available, suppress the “Download the latest Flash player message” as this intent is unavailable to Silk customers on Kindle LCD devices

4.       How can web developers optimize site performance for Amazon Silk users?

There are several techniques web developers can use to optimize the performance of their web sites for Amazon Silk users.

Caching on the Amazon Silk EC2 backend is one of the primary mechanisms Silk uses to accelerate page loading. Silk’s backend will only cache page elements that are explicitly marked as cacheable by the web developer. Web developers can assure that their web sites are optimized to take advantage of this caching by explicitly setting at least one of the following HTTP cache-control headers: max-age, expires, and public. The longer the time-to-live for a cacheable element the more benefit Silk users will receive.

Another important consideration in web page design is to explicitly set the height and width attributes on any elements used in the page (e.g., images). The Amazon Silk EC2 backend will optimize the delivery of the page elements using the height and width. This optimization will improve page latency for the user and minimize bandwidth usage.

For additional, more general, information on the Amazon Silk web browser, visit the Amazon Silk FAQs.

June 19, 2012

Amazon Mobile App Distribution Program

We’re pleased to announce that you can now submit apps for distribution in the United Kingdom, Germany, France, Italy, and Spain, using the Amazon Mobile App Distribution Portal. We’ll begin distributing apps in these countries later this summer (and we have more countries planned in the near future). 

The Amazon Appstore in the U.S. has had a very successful year with millions of customers discovering and downloading apps and games. We continue to welcome new developers onto our platform, and since launch, we’ve grown to tens of thousands of apps—with more coming every day. Our recently launched In-App Purchasing API is already helping developers like Mobile Deluxe, G5 Entertainment, and Social Gaming Network delight their customers and generate significant revenue. Amazon now offers developers the opportunity to experience similar success with app sales outside the U.S.

Now is a great time for new developers to sign up and become familiar with the program. You have the ability to select the countries where you would like your apps to be sold and set your list prices by marketplace. If you are already participating in the program, your apps will automatically be made available for sale internationally by default. And you can easily change international availability for your apps via the Distribution Portal if your apps should not be sold in select countries. Developers allowing Amazon to sell apps internationally are responsible for ensuring their apps comply with all applicable export and import restrictions and the laws of the countries in which the apps are sold.

Though Amazon will not require apps to support multiple languages, we encourage you to consider localizing your apps with language translations and to think of creative ways to deliver great experiences to your international customers. Just as in the U.S., if you sell apps in the U.K., Germany, France, Italy, and Spain, you will benefit from Amazon’s trusted 1-Click purchasing as well as the easy-to-integrate In-App Purchasing API.

Today we are also announcing two changes to the Amazon Mobile App Distribution agreement. First, building on the success of the April In-App Purchasing Service launch, and to simplify our global terms, Amazon will be aligning the revenue share for paid apps with that for in-app products sold using Amazon’s In-App Purchasing Service. Starting July 1, you will earn 70% of list price on each paid app sale. This is a change from the prior terms under which you earned either 70% of the app’s sales price or 20% of list price (whichever was greater). To put it differently, starting in July, you’ll receive 70% of the list price for all sales, regardless of whether you monetize your apps up front (paid apps) or downstream (using our In-App Purchasing Service).  

Second, we will be adapting the terms of the distribution agreement to provide more flexibility around timing for app submissions. You will now control which apps you will make available to Amazon customers, and when, as well as the countries in which your apps may be sold. As a reminder, it’s your responsibility to ensure your list prices do not exceed the lowest prices at which your apps and in-app products are sold in similar stores. To review the full agreement, including the two changes described above, please follow this link.

If you don’t already have a developer account, it’s easy to join and we’ve waived the annual fee for 2012  it’s free to register for a developer account. Sign up now, and start submitting your apps for international distribution later this summer!

We’re pleased to announce that you can now submit apps for distribution in the United Kingdom, Germany, France, Italy, and Spain using the Amazon Mobile App Distribution Portal.  We’ll begin distributing apps in these countries later this summer (and we have more countries planned in the near future).   

 

June 17, 2012

Amazon Mobile App Distribution Program

Guest author Simon Newstead, CEO of Frenzoo, discusses designing games for monetization. In it he uses examples from Frenzoo's Style Me Girl, the first 3D fashion game on mobile. Simon can be reached at simon@frenzoo.com.


A Numbers Game


Our debut game Style Me Girl gained impressive downloads in its first two weeks, reaching the #1 position in the Amazon game charts. Whilst the downloads and rankings were nice, what made us really happy was the monetization, with Kindle Fire performing particularly well.


Style_Me_Girl_icon
 


Mechanics


To look at what drives monetization it's always helpful to look at the core game mechanics:

Mechanics


In our case with Style Me Girl, the primary is a fashion puzzle mechanic where the player must dress a series of models for different Photoshoots, each with a unique fashion genre. The game uses a proprietary judging algorithm to determine scores, taking into account the items used, the fashion genre as well as the attractiveness of the photo taken. Passing the level unlocks the next level (model and fashion genre), progressing the story. Story evolves with new levels added dynamically from the cloud each week.

The secondary is a casual "catch the falling item" mini-game called Style Catch. Style Catch escalates in difficulty and provides and increasing payout of coins, used for shopping.

A freemium game, Style Me Girl has a hard currency Cash (purchased via IAP) and soft currency Coins, earned in Photoshoots and Style Catch.


5 Tips for Monetization


1. Incorporate a storyline

No matter the game type, if your game has levels, story serves up more motivation for players to progress through them. Players are emotional beings, and we are all compelled to be drawn into a good story. In our case, the game could have functioned just fine without a story line. However we saw from player feedback a deep engagement with the protagonist and goals in the story arcs. Given how little engineering resource is often needed on story, the ROI to include it is usually pretty compelling.

2. Replayability and collectibles

One thing that drives many paying users of Style Me Girl is successfully completing all levels with perfect 3 star results. Why? Of course completionism plays a part but the main one is being able to win rare "signature edition" items. These cannot be bought in the shop and a sign of success is sporting an outfit featuring 1 or more signature editions. It's always good to make room for replayability and collectibles can play well in that.
 
3. Energy and speed up

It's a cliche but it's true - impatient players are paying players. Energy regeneration through paid items is a proven way to open up the purse strings. We saw that in Style Me Girl and cash purchase, even though Style Catch itself is just a game to let you earn the soft currency. Strange but it works.

4. Aesthetics and functionality

Whilst studies show that pure aesthetic items don't monetize as well as time saving and functional virtual goods, if you can combine them together that can work extra well. In our case the cash items bought in the shop are attractive fashions, which lets users both look good and play good. Combinations are always good. Think the success of Toms, based on looking good and feeling good about it. Or owning the latest Macbook Air, a style statement as well as solid productivity tool.

5. A/B testing

Like eating enough fiber, it may not be a glamorous part of game design but it certainly is necessary to get the most out of your game. We implement A/B testing in the major parts related to the in-game economy - coins earning rate, starting currency values, purchase conversion rate etc. We don't go to the point of A/B testing individual item prices yet though, but that's the direction. Running tests has helped us increase monetization while not affecting retention (not always the case), and it's something we're going to dive into even further.


Conclusion


These tips are certainly not rocket science and not the first time they have been used in games.That said, keeping these fundamentals in mind when designing your next game ensures you're getting biggest bang for your development buck. And that makes everyone happy.

June 11, 2012

Amazon Mobile App Distribution Program

Jeff Hines, Kindle Fire test team, and Chirag Mehta, a2z Developer Center Inc., an Amazon.com company, are our bloggers for this post.

This third post in our Top 10 App Optimizations for Kindle Fire series features actionable measures you can take when optimizing an app to correctly handle hibernation on Kindle Fire.

Your app must account for hibernation on Kindle Fire—whether the hibernation is user initiated or occurs after the screen times out. Similar to the Quick Settings optimization, hibernation optimization requires a proper handling of the onPause() and onResume() methods.

Not all apps react similarly when hibernated, as the expected behavior is dependent on the nature of the app. We have identified frequent hibernation issues and the solutions to correct them.

What is hibernation and what is the expected behavior?

When initiated, hibernation on Kindle Fire acts as a battery saver after a screen timeout or when a user taps the device’s power button. During hibernation, any active network connections are disabled by default. To return from hibernation, users are presented with the lock screen and must slide to resume.

Upon hibernation, the expected behavior for most apps is to enter a paused state, using the onPause() method, and then to restore app state upon return by using the onResume() method. Of course, apps that are static in nature and rely on user interaction to change state can simply run in the background during hibernation.  

In general, apps running in the background are expected to cease all background sound. However, some apps should continue to emit audio if this is their core functionality—such as music players or alarms.

My app requires an always on, active network connection. How do I ensure users stay connected during hibernation?

As mentioned earlier, network connections are disabled by default during hibernation as an additional measure to save battery life on Kindle Fire. Upon leaving hibernation, any previously connected network connection will be restored.

If your app requires an always-on, active network connection, then you can ensure that users remain connected during hibernation by using the following sample code:

try {
            final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            final WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
            final ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            final State wifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();

            // Log the current WiFi state.
            Log.i(LOG_TAG, getString(R.string.lock_service_status_current_state) + " " + wifi.toString());
           
            // Acquire the reference to the wake lock.
            m_wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getString(R.string.lock_service_wake_lock_name));
           
            // Ensure that the wake lock is reference counted.
            m_wakeLock.setReferenceCounted(true);
           
            // Acquire a wake lock to keep the CPU running.
            if (!m_wakeLock.isHeld()) {
                m_wakeLock.acquire();
            }

            // Acquire a WiFi lock to keep the WiFi radio awake.
            m_wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL, getString(R.string.lock_service_wifi_lock_name));

            // Ensure that the WiFi lock is reference counted.
            m_wifiLock.setReferenceCounted(true);

            if (!m_wifiLock.isHeld()) {
                m_wifiLock.acquire();
            }

            // Perform the business logic.
            performBusinessLogic();
        } catch (final IOException e) {
            Log.e(LOG_TAG, e.getMessage());
            sendStatusMessage(e.getMessage());
        } finally {
            // Release the locks.
            if (m_wakeLock != null && m_wakeLock.isHeld()) {
                m_wakeLock.release();
            }

            if (m_wifiLock != null && m_wifiLock.isHeld()) {
                m_wifiLock.release();
            }

            // Log the status.
            final java.text.DateFormat dateFormat = DateFormat.getTimeFormat(this);
            final Date date = new Date();
            Log.i(LOG_TAG, getString(R.string.lock_service_status_release) + " " + dateFormat.format(date));
        }
    }


What can I do to ensure my app reacts correctly to device hibernation?

Apps that do not appropriately handle hibernation on Kindle Fire exhibit similar behavior to apps not optimized for Kindle Fire’s Quick Settings. When mishandling hibernation, apps may exhibit the following behavior:

  • Apps may force close or crash
  • App’s state or user save data may become lost or reset
  • App’s videos may become interrupted or reset entirely
  • Apps may enter an unrecoverable state upon return from hibernation
  • Apps may continue to run in the background during hibernation—losing the user state

Much like our previous entries in the series, correctly implementing the onPause() and onResume() methods are key to resolving any negative behavior in association with hibernation. When hibernation is enacted, the onPause() method will be called during your app’s current activity. When returning to your app after the power button is tapped and the lock screen is slid, the onResume() method is called. To ensure that your app returns to its previous state before hibernation occurred, your app should save state in the onPause() method and reload the state in the onResume() method.

If your app plays audio clips using the MediaPlayer object, be sure to call pause() within the onPause() method, and start() in the onResume() method in your app.  This will ensure audio clips do not continue to play when the device hibernates.

For a technical perspective of the onPause() and onResume() methods, review our code segments included in part one of our Top 10 Optimizations for Kindle Fire series. To find more information about these and other methods, you may also find it helpful to visit: http://developer.android.com/reference/android/app/Activity.html

Check back for our next optimization post in which we will discuss ways to ensure your app installs successfully on Kindle Fire.

June 08, 2012

Amazon Mobile App Distribution Program

Over six weeks after launching the Amazon In-App Purchasing API for general availability, we connected with Jeff Spears, VP of Marketing & Sales, and Sean Thompson, VP of Production, Mobile Deluxe, to chat about their company’s experience with IAP on Amazon. Headquartered in Santa Monica, Calif., Mobile Deluxe is an innovator and publisher of social mobile apps and provides free-to-play casual games that emphasize premium quality and fun game play. Mobile Deluxe titles include Big Win Slots, Solitaire Deluxe, and Big Win Blackjack. 

What motivated Mobile Deluxe to integrate with Amazon’s In-App Purchasing solution?

"Mobile Deluxe is bullish on Amazon’s foray into the app space given its expertise in merchandising, coupled with the ease of 1-Click purchase. As an organization, we made the shift from pay-to-download to free-to-play in April 2010, and our free revenues eclipsed paid revenues by July of 2011. As an industry, freemium revenues are forecasted to reach $5B in 2016, driven by smart phone adoption and user comfort with the IAP model. As a publisher we like  the freemium model since it eliminates the barrier of entry into our game, and it allows players to enjoy our products regardless of their style of play. You can either “earn” currency through game play, or purchase currency at your discretion to accelerate your game as you see fit. While we support both styles of play, from a business perspective we aren’t capping potential earnings in the latter example."

What is your monetization strategy?

"Big Win Slots monetizes through IAP, whereas Solitaire Deluxe and Big Win Blackjack use a hybrid monetization model that uses IAP and Ads. For Solitaire Deluxe, the majority of our revenue is derived from advertising, allowing our customers to play for free, unlimited. This has led to outstanding engagement and retention, and our average play time for users is in excess of 30 minutes. For Big Win Slots and Big Win Blackjack, we felt the natural progression of currency in casino apps made great sense. IAP allows us better control over our revenue stream versus fluctuating advertising CPM’s in an ad-based product, and it allows for flexibility in merchandising opportunities such as in-game sales events."

How has your experience with Amazon’s IAP solution compared to that on other platforms?

"When making an apples-to-apples comparison in May to competitive app stores, Amazon is our #1 monetizing channel in terms of $/DAU. I’m sure you’re aware of the Flurry release stating “revenue from Amazon’s Appstore is now at 89% of iTunes App Store revenue” here. We find that our Amazon $ per Daily Active User exceeds the average on other top storefronts where our apps are distributed by 87%. This speaks to the frictionless 1-Click option and Amazon’s merchandising prowess which drove “Big Win Slots” to the #1 spot in the “Casino” category."

How did you find integrating the Amazon SDK and IAP API?

 "Integration was exactly what we expected. We started from a baseline of already having integrated Google Checkout, so it was very easy to extend our existing functionality to include Amazon IAP. Amazon’s online resources were excellent. The “In-App Purchasing for Users of Google Billing” document was the perfect guide to help us get Amazon IAP integrated quickly. The API Reference was also helpful. Without question, this has been an ROI-positive experience for us. The total integration cost was about what we make in one day with Big Win Slots now."

Are there any tips you have to help other developers smoothly integrate the SDK?

"We recommend developers be forward looking when integrating any billing SDK. If at all possible, create an abstracted billing interface layer between your app(s) and the billing SDK. That will allow you to implement additional billing SDKs without having to make changes deep inside your project code. That means it is an easy tweak to add both Google and Amazon IAP solutions."

June 05, 2012

Amazon Mobile App Distribution Program

<p>The beta launch of Test Drive last week on select Android devices has many developers wondering, how does it work? Jeff Bar, Amazon Web Services Technical Evangelist, has taken the time to walk through the technology behind Test Drive on the AWS blog. Test Drive is hosted on Amazon Elastic Cloud Compute (EC2). The Amazon Appstore team can therefore easily add additional capacity whenever needed and where it makes the most sense with respect to the incoming traffic. We encourage you to check out <a href="http://aws.typepad.com/aws/2012/06/behind-the-scenes-of-the-amazon-test-drive.html">Jeff’s full post on the Amazon Web Services blog</a>.</p>

June 03, 2012

Amazon Mobile App Distribution Program

Aaron Rubenson, Director, Amazon Appstore, spoke at Open Mobile Summit in London about app monetization last week.  You can listen to the recording of the panel, App monetization: From Killer App to Killer Business, where panelists covered topics like: 

  • Monetization: What's working today and why – from app sales, freemium, virtual goods, subscription, advertising and commerce?
  • How big is the app market opportunity?
  • How can app publishers build sustainable businesses? Which business models have longevity?
  • New tools: Analytics, engagement, recommendation and discovery

 

Learn more about the panelists by reading their bios on the Open Mobile Summit website.

Moderator:


    Speakers:


    Or listen to all available recordings from Open Mobile Summit here.

    May 24, 2012

    Amazon Mobile App Distribution Program

    Jeff Hines, Kindle Fire test team, and Chirag Mehta, Michael Siwapinyoyos, and Steve Johnson, a2z Developer Center Inc., an Amazon.com company, are our bloggers for this post.

    The second post in our optimization series discusses optimizing your app’s layout for Kindle Fire and accounting for the soft key bar.

    In addition to the Settings bar that we mentioned in our previous post, Kindle Fire also has a soft key bar that is present at all times. Rather than physical buttons, Kindle Fire uses soft keys to display the standard Android buttons (i.e., Home, Back, Menu, and Search).

    Optimizing your app for the soft-key bar provides a more positive customer experience. In this post, we present optimizations and sample code to address frequently asked questions and common issues you may encounter when developing your app for Kindle Fire.

    How do I optimize my app’s layout for Kindle Fire?

    When developing exclusively for Kindle Fire, please ensure that your app is optimized for the following specifications:

    • A “Large” 7” screen size
    • A Medium Density (mdpi) screen with an abstracted LCD density of 160
    • 600 pixel width by 1024 pixel height in portrait mode

    Note that the Kindle Fire will reserve 20 pixels to display the soft key bar, as stated previously; therefore, the true pixel height, including the soft key bar, is 1004 pixels in portrait mode.

    Apps optimized for Kindle Fire should take advantage of the large screen size. Your app should scale its interactive elements accordingly. This provides the best possible customer experience.

    Use these screen specifications even if your app is not optimized exclusively for Kindle Fire. A best practice is to create resources specifically for large screen devices with medium density displays (mdpi).  

    To scale a background image, specify taking as much space as available within the layout element, using the following code snippet:

    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaleType="fitXY"
    android:src="@drawable/yourbackground"
    />

    Use the Bitmap.createBitmap() method with caution. While it can scale resources to fit the screen, it can also take additional computing cycles and require a lot of additional memory.

    Please note that Android does have a built-in resource selection algorithm that will attempt to match declared resources with the characteristics of the device that your app is being displayed on. More detail regarding multiple Android screen support can be found here: http://developer.android.com/guide/practices/screens_support.html.

    How should my app handle rotation on the Kindle Fire?

    While not specifically about your app’s layout, errors with orientation changes are frequently encountered. Rotating a device from landscape to portrait (or vice versa) without the appropriate optimizations can result in the following issues:

    • Your app force closing
    • Crashing or returning users back to the carousel on Kindle Fire
    • App state or user save becoming lost or reset

    A screen orientation change will always fire the onCreate() event, destroying and recreating the activity. If you do not take this into account, you could run the risk of a negative user experience.

    To properly handle a screen rotation and avoid the issues outlined above, you can follow these best practices:

    • Name the views in your activity using the android:id attribute. When there is an orientation change in your activity, Android will persist the state of a named view and restore it once the activity is recreated. When an activity is destroyed, the state is saved only for named views.
    • The onSaveInstanceState() method is fired when an activity is destroyed. You can override this method to save your app state. Once the orientation change is complete, and your activity’s onCreate() method is called, onRestoreInstanceState() is automatically called. This method can be overridden to restore you app state. This mechanism relies on simple data structures to be used; i.e., state information needs to be structured in a Bundle object.
    • If your app needs to save a complex data structure, then you can use the onRetainNonConfigurationInstance() event. This event returns an arbitrary Object event, so you can persist as complex a data structure as is necessary for your app. Call getLastNonConfigurationInstance() inside your onCreate() method to retrieve your activity state, but remember to cast the class properly.

    Although not the best solution for all apps, preventing orientation change will allow you to avoid these issues entirely. To lock your app to a specific orientation, include the following entry in your manifest file.

    android:screenOrientation="portrait|landscape"

    How can I effectively use the soft key bar?

    The soft key bar enables simple, quick, and efficient navigation from within your app and all other aspects of the device.

    The soft key bar has two positions: maximized and minimized. When minimized, the soft key bar takes up 20 pixels and displaces your content. When maximized it takes up 60 pixels; 20 pixels displace your content and 40 pixels sit on top of your content.

    How should my app interact with Kindle Fire’s soft key bar?

    To be compatible with Kindle Fire, apps must account for and interact with the soft key bar. The soft key bar contains four different soft keys:

    • Home
    • Back
    • Menu
    • Search

    Using the Home Soft Key

    Kindle Fire uses these keys to display the standard Android device buttons. Apps must appropriately use the Home soft key to allow quick navigation to and from the Kindle Fire carousel.

    By default the Home soft key returns users to the Kindle Fire carousel. When the home key is pressed, the current activity’s onPause() method will be called before the user is presented with the carousel. When your app is re-launched, the onResume() method will be called. In order to ensure that the app returns to its previous state, your app should save state in the onPause() method and reload the state in the onResume() method.

    For more information about the onPause() and onResume() methods, please see our previous blog post in the Top 10 Optimizations for Kindle Fire series.

    Using the Back Soft Key

    The Back soft key's default action is to call finish() on the current activity and then resume the previous activity on the stack (as managed by the OS).

    If your app has launched several activities and you want the Back soft key to return the user to the previous activity, then you don't need to do anything—this is the default behavior. If the user is already at the main activity of your app, the Back soft key will call finish() on the activity and exit your app.

    A typical solution to prevent premature exiting of the app is to override the Back soft key functionality on your app's main activity to trigger a confirmation dialog. Override the function of the Back soft key in an Activity by including the following code in the Activity class:

    @Override

    public void onBackPressed() {

       // do something when the back button is pressed

       return;

    }

    Stay tuned for our next series post, as we tackle device hibernation!

    May 21, 2012

    Amazon Mobile App Distribution Program

    Test Drive is an innovation that removes the friction for customers to try new apps and games.

     

     Jerry Heinz, general manager of Test Drive, is our guest blogger for this post.

     

    Test_drive_merge

    Over a year ago we launched Test Drive on Amazon.com, allowing customers to instantly try apps from their computer web browser.  Similar to customer reviews, product descriptions, screenshots and videos, which help customers make purchase decisions on products across Amazon.com, Test Drive is an innovation that helps customers learn about new apps.  The more we remove friction for customers who want to try apps, the more apps they will try. Those customers are more likely to find apps they are excited to download.   In this way, Test Drive helps customers understand the value of premium apps and helps drive downloads of freemium apps.  Since Test Drive launched, it has been enabled on over 16,000 apps.

    Today we begin the beta rollout of Test Drive on Android phones.   Now customers can instantly try apps on their phone -- where a majority of app purchases take place -- without downloading or installing anything. 

    What do you need to do?

     

    Nothing -- no effort is required on the part of developers to be included in Test Drive.  When you submit apps and app updates we automatically test these apps for Test Drive and we strive to make all apps available for Test Drive. Today we have enabled over 5,000 apps for Test Drive on Android phones and are adding more all of the time.   

    Test Drive currently supports apps that utilize the touch screen and accelerometer inputs.  Apps that require Java Native Interface (JNI), keyboard, multi-touch, microphone, camera, gyroscope, near-field communication or GPS are not currently enabled for Test Drive.  As Test Drive adds these features, apps will be automatically re-tested for inclusion.    If you have questions about Test Drive for your app, you can contact us by emailing us at testdrive-inquiries@amazon.com.

    How do customers Test Drive your app?

     

    Customers click the “Test Drive” button on an app product page and in seconds, they can use their phone’s touch screen and accelerometer to control the app, simulating the experience of the app running on their phone.  Test Drive provides customers with the experience of running an app for the first time, as if it were freshly installed.  Customers can purchase or download the app at any point during the Test Drive experience.   

    The Test Drive beta is available for free to customers who update to the latest release of Amazon Appstore for Android on their phone (version 2.6.53 or higher).  Initially, Test Drive will be available on select phone models but over the coming months, we will roll it out to many more.  When new phone models are supported, the Test Drive button will automatically appear on apps that are enabled for Test Drive. 

    How does Test Drive work? 

    Amazon brings the Test Drive experience to Amazon.com and Android phones using the massive server fleet that comprises the Amazon Elastic Compute Cloud (EC2), a web service that provides on-demand compute capacity in the cloud for developers.  When customers click the Test Drive button, we launch a copy of the app on EC2. As customers interact with the app, we send those inputs over the phone’s WiFi Internet connection to the app running on Amazon EC2.  Our servers then send the video and audio output from the app back to the customer’s computer or phone. All this happens in real time, allowing customers to explore the features of the app as if it were running locally on their mobile device.

    May 10, 2012

    Amazon Mobile App Distribution Program

    Jeff Hines, Kindle Fire test team, and Chirag Mehta, Manager, a2z Developer Center Inc., an Amazon.com company, are our bloggers for this post. 

     

    This post is the first in a series detailing the top 10 optimizations to improve your app on Kindle Fire. These posts are designed to provide you with solutions, sample code, and the opportunity to address common issues that can arise as you optimize your app for Kindle Fire.

     

    The first topic in this series reviews one of the most frequently asked questions when developing on Kindle Fire: “My app is not optimized to interact with Kindle Fire Quick Settings, what can I do to provide a better customer experience?”

     

    What do the Quick Settings do?

     

    The Quick Settings feature is unique to the device and provides Kindle Fire owners with a host of easily accessible options, including Volume, Brightness, Wi-Fi, and more. The image below shows the Quick Settings feature and its location on the device. Like the soft key bar, the Quick Settings feature is visible at all times, including when your app is running. When optimizing for Kindle Fire, your app should account for users accessing the Quick Settings bar at any time while your app is running.

      Part_I_edit
     

    How should your app interact with Quick Settings?

     

    Invoking the Quick Settings feature should not affect the app or its current state. Some apps, like most games, should simply pause. Other apps that are more static in nature, and rely on user interaction to change state, can simply run in the background.

     

    How should apps not optimized for Quick Settings behave?

     

    If your app is not optimized for Kindle Fire and does not take into account a user interacting with the Quick Settings bar, the following scenarios could result:

     

    • Your app could force close or become unresponsive
    • Your app’s state or user save data may become lost or reset
    • Your app’s video or audio may become reset or interrupted
    • Your app may enter an unrecoverable state such as perpetual loading or black screen
    • Your app continues to actively run and does not enter a paused state

     

    How do I optimize for Quick Settings?

     

    The following code snippets (based on a set of sample apps) show you how you can optimize your app for the Quick Settings feature.

     

    This sample code shows how your app could pause if a user invokes the Quick Settings. The code saves the label position on screen, and save the score. The onPause() call is highly recommended, as it ensures your app saves its state.

     

    protected void pause() {

     

                       final Editor editor = m_state.edit();

    editor.putLong("xMove", m_xMove);

    editor.putLong("yMove", m_yMove);

    editor.putLong("xPos", m_xPos);

    editor.putLong("yPos", m_yPos);

    editor.putLong("score", m_score);

    editor.commit();

     

     // Stop the animation thread.

     if (m_animationThread != null) {

         m_animationThread.setRunning(false);

         m_animationThread = null;

        }

    }

     

    This sample code shows how your app could resume after a user leaves the Quick Settings.  The code initializes a label, determines its position on screen, and displays the score.  The onResume() call is highly recommended, as it ensures your app resumes its state.

     

    protected void resume() {

     

    m_paint = new Paint();

    m_random = new Random();

    m_state = m_context.getSharedPreferences("UserState", Context.MODE_PRIVATE);

    m_xMove = m_state.getLong("xMove", DEFAULT_X_MOVEMENT);

    m_yMove = m_state.getLong("yMove", DEFAULT_Y_MOVEMENT);

     // Set initial position of the score to the center of the screen.

    m_xPos = m_state.getLong("xPos", this.getWidth() / 2);

    m_yPos = m_state.getLong("yPos", this.getHeight() / 2);

    m_score = m_state.getLong("score", DEFAULT_SCORE);

     

     // Start the thread if it has been previously stopped. 

    if (m_animationThread == null) {

    m_animationThread = new AnimationThread(getHolder(), this);

    m_animationThread.setRunning(true);

    m_animationThread.start();

    }

    }

     

     

    Many games having actively running animations and it’s essential to pause and retain animation state when a user invokes the Quick Settings.

     

    public class PausingAnimationSampleActivity extends Activity {

     

      /** Reference to the content view, used to pause and resume the animation */

      private AnimationPanel m_panel;

     

      /** {@inheritDoc} */

      @Override

      public void onCreate(final Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

     

        m_panel = new AnimationPanel(this);

        setContentView(m_panel);

      }

     

      /** {@inheritDoc} */

      @Override

      protected void onStart() {

        super.onStart();

      }

     

    If your app pauses its animations sequences using the sample above, you can resume the animation sequence using the sample code below.

       

      @Override

      protected void onPause() {

        super.onPause();

        m_panel.pause();

      }

     

      /** Restore the user's state when returning to the application */

      @Override

      protected void onResume() {

        super.onResume();

        m_panel.resume();

      }

     

      /** {@inheritDoc} */

      @Override

      protected void onStop() {

        super.onStop();

      }

     

    }

     

     

    See the Amazon App Developer FAQ if you have more questions.

     

    This is only the first of ten optimizations in our new series, so be sure to check back for our next post on layout and the soft key bar!

    Top 10 App Optimizations for Kindle Fire – Part I

    This post is the first in a series detailing the top 10 optimizations to improve your app on Kindle Fire. These posts are designed to provide you with solutions, sample code, and the opportunity to address common issues that can arise as you optimize your app for Kindle Fire.

    The first topic in this series reviews one of the most frequently asked questions when developing on Kindle Fire: “My app is not optimized to interact with Kindle Fire Quick Settings, what can I do to provide a better customer experience?”

    What do the Quick Settings do?

     

    The Quick Settings feature is unique to the device and provides Kindle Fire owners with a host of easily accessible options, including Volume, Brightness, Wi-Fi, and more. The image below shows the Quick Settings feature and its location on the device. Like the soft key bar, the Quick Settings feature is visible at all times, including when your app is running. When optimizing for Kindle Fire, your app should account for users accessing the Quick Settings bar at any time while your app is running. 

     

     

     

     

     

    How should your app interact with Quick Settings?

     

    Invoking the Quick Settings feature should not affect the app or its current state. Some apps, like most games, should simply pause. Other apps that are more static in nature, and rely on user interaction to change state, can simply run in the background. 

    How should apps not optimized for Quick Settings behave?

     

    If your app is not optimized for Kindle Fire and does not take into account a user interacting with the Quick Settings bar, the following scenarios could result:

     

    ·         Your app could force close or become unresponsive 

    ·         Your app’s state or user save data may become lost or reset

    ·         Your app’s video or audio may become reset or interrupted

    ·         Your app may enter an unrecoverable state such as perpetual loading or black screen

    ·         Your app continues to actively run and does not enter a paused state

     

    How do I optimize for Quick Settings?

     

    The following code snippets (based on a set of sample apps) show you how you can optimize your app for the Quick Settings feature.

    This sample code shows how your app could pause if a user invokes the Quick Settings. The code saves the label position on screen, and save the score. The onPause() call is highly recommended, as it ensures your app saves its state.

     

    protected void pause() {

     

                       final Editor editor = m_state.edit();

    editor.putLong("xMove", m_xMove);

    editor.putLong("yMove", m_yMove);

    editor.putLong("xPos", m_xPos);

    editor.putLong("yPos", m_yPos);

    editor.putLong("score", m_score);

    editor.commit();

     

     // Stop the animation thread.

     if (m_animationThread != null) {

         m_animationThread.setRunning(false);

         m_animationThread = null;

        }

    }

     

    This sample code shows how your app could resume after a user leaves the Quick Settings.  The code initializes a label, determines its position on screen, and displays the score.  The onResume() call is highly recommended, as it ensures your app resumes its state.

     

    protected void resume() {

     

    m_paint = new Paint();

    m_random = new Random();

    m_state = m_context.getSharedPreferences("UserState", Context.MODE_PRIVATE);

    m_xMove = m_state.getLong("xMove", DEFAULT_X_MOVEMENT);

    m_yMove = m_state.getLong("yMove", DEFAULT_Y_MOVEMENT);

     // Set initial position of the score to the center of the screen.

    m_xPos = m_state.getLong("xPos", this.getWidth() / 2);

    m_yPos = m_state.getLong("yPos", this.getHeight() / 2);

    m_score = m_state.getLong("score", DEFAULT_SCORE);

     

     // Start the thread if it has been previously stopped. 

    if (m_animationThread == null) {

    m_animationThread = new AnimationThread(getHolder(), this);

    m_animationThread.setRunning(true);

    m_animationThread.start();

    }

    }

     

     

    Many games having actively running animations and it’s essential to pause and retain animation state when a user invokes the Quick Settings.

     

    public class PausingAnimationSampleActivity extends Activity {

     

      /** Reference to the content view, used to pause and resume the animation */

      private AnimationPanel m_panel;

     

      /** {@inheritDoc} */

      @Override

      public void onCreate(final Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

     

        m_panel = new AnimationPanel(this);

        setContentView(m_panel);

      }

     

      /** {@inheritDoc} */

      @Override

      protected void onStart() {

        super.onStart();

      }

     

    If your app pauses its animations sequences using the sample above, you can resume the animation sequence using the sample code below.

       

      @Override

      protected void onPause() {

        super.onPause();

        m_panel.pause();

      }

     

      /** Restore the user's state when returning to the application */

      @Override

      protected void onResume() {

        super.onResume();

        m_panel.resume();

      }

     

      /** {@inheritDoc} */

      @Override

      protected void onStop() {

        super.onStop();

      }

     

    }

     

     

    This post is the first in a series detailing the top 10 optimizations to improve your app on Kindle Fire. These posts are designed to provide you with solutions, sample code, and the opportunity to address common issues that can arise as you optimize your app for Kindle Fire.

    The first topic in this series reviews one of the most frequently asked questions when developing on Kindle Fire: “My app is not optimized to interact with Kindle Fire Quick Settings, what can I do to provide a better customer experience?”

    What do the Quick Settings do?

     

    The Quick Settings feature is unique to the device and provides Kindle Fire owners with a host of easily accessible options, including Volume, Brightness, Wi-Fi, and more. The image below shows the Quick Settings feature and its location on the device. Like the soft key bar, the Quick Settings feature is visible at all times, including when your app is running. When optimizing for Kindle Fire, your app should account for users accessing the Quick Settings bar at any time while your app is running.

    See the Amazon App Developer FAQ if you have more questions.

     

    This is only the first of ten optimizations in our new series, so be sure to check back for our next post on layout and the soft key bar!

    May 01, 2012

    Amazon Mobile App Distribution Program

    Steve Johnson (Solutions Architect, a2z Developer Center Inc., an Amazon.com company), is our blogger for this post. 

    Amazon's in-app purchasing (IAP) solution includes the Receipt Verification System, or RVS. RVS is an optional step in the IAP purchase flow that allows you to ensure that a Receipt originated from Amazon, and that the information in the Receipt is accurate.

    The purpose of RVS is out-of-band verification. "Out-of-band" simply means "an alternate way" to verify purchase information, instead of depending solely on the communication between your app and the Amazon Appstore for Android. RVS is handy if:

    • You want to ensure the Receipt you're using is valid
    • You want to verify entitlement to content before delivering it from your server
    • You want to see if a subscription is valid and fulfill content accordingly

    In order to use RVS, you need the Purchase Token and User ID from the purchase receipt.

    What is a Receipt?

    Before we talk about validating a Receipt, we should explain what it is. A Receipt represents the in-app purchase of an item (SKU) by a particular user. The information inside a Receipt will tell you what was purchased, and in the case of subscriptions, when the subscription term began.

    The Receipt also contains a string called the Purchase Token (returned from Receipt.getToken()). The Token is an opaque digest of information about the purchase. It is possible for a purchase transaction to have more than one Purchase Token representation, so they should not be used as transaction IDs. Here is what one looks like:

    2:FlrXSsmgOBKXoBbf6BtIrBtmbZLNr92LrRNGQ==:qsy5n5MMZM4u-LlDrqGp5Q==

    As you can see, it's not very useful on its own. In fact, it’s only purpose in life is to be validated by RVS—the value is intentionally opaque so that it can only be processed by the RVS service.

    What is a User ID?

    Before you can use RVS with a Purchase Token, you also need to retrieve the User ID of the user that made the purchase. This is done via the GetUserIdResponse.getUserId() call via the Purchasing Observer. The User ID uniquely identifies the currently logged-in user for your app. It is needed in conjunction with the Purchase Token to verify a transaction.

    Now let's see how it works.

    Let's say a customer purchases an issue of a magazine as an in-app purchase from the Amazon Appstore. The Amazon Appstore concludes the transaction by calling your app's PurchaseObserver with a PurchaseResponse. For a successful purchase, the PurchaseResponse contains a Receipt Object (otherwise PurchaseResponse.getReceipt() returns null).

    To validate a Receipt, we need to complete the following process:

    1. Your app receives a Receipt from the Amazon Appstore
    2. Your app sends the Receipt's Purchase Token and purchaser's User ID to your Verification Server
    3. Your Verification Server sends that information along with your Developer Shared Secret to the Amazon Receipt Verification Server

    The Amazon Receipt Verification Server decodes the token and returns an RVS response in JSON format. Your Verification Server processes the response, and takes the appropriate action (delivers content, sends results to app, etc.).

    Step 3 mentions the Developer Shared Secret. Each developer account in the Amazon Appstore has its own "shared secret". This value should be hosted and protected on your Verification Server. By adding this value to your request, the Amazon Receipt Verification Server can identify the request as having originated from your server (for this reason, you never want to embed the shared secret's value in your apps, or call RVS directly from your app). Find your Developer Shared Secret on the Developer Portal: https://developer.amazon.com/sdk/shared-key.html

    The request to the Amazon Receipt Verification Server is in the form of a URL:

    https://appstore-sdk.amazon.com/version/2.0/verify/developer/<developerSecret>/user/<userId>/purchaseToken/<purchaseToken>

    The response to this request consists of the HTTP Response Value and a JSON file in the body of the response. There are several responses possible (including a result code for bad purchase token, bad user ID, or bad Developer Shared Secret). Each is explained in detail at https://developer.amazon.com/sdk/in-app-purchasing/documentation/rvs.html#API

    One response worth explaining here is HTTP 499, referred to as "Expired Token". Tokens don't actually expire. If you see this code, it means that the certificate Amazon used to encrypt the token is no longer in use. Although RVS will no longer process these tokens, there is an RVS API that will issue you a new one. In response to this code, your Verification server should send the token to the "renew" service, which will give you a new token with valid credentials.

    The response from the renew service will contain the new, valid token. It is important to note that the new token represents the same information (the same purchase) as the old one. If you are storing tokens on your own server, you should replace the old one, and continue using it as normal.

    How to use RVS Information

    RVS is a simple service. If you provide a purchase token with the correct data, the service will tell you about the purchase it represents. If you provide inconsistent or invalid data, it will do its best to tell you what went wrong. Now that you have this information, what should you do with it?

    It is Amazon's goal to provide you and your customers a convenient, hassle-free purchase experience. Once the Amazon Appstore (and RVS) have validated a purchase, it is up to you as the developer to continue that positive experience for your customers.

    If you use RVS to validate every purchase, you should consider the impact to your customers if the RVS verification chain is interrupted by network outages or device service interruptions. If that occurs, you have several options: "fail open" and deliver content regardless, "fail closed" and deny entitlement, or a more sophisticated approach that temporarily entitles content until verification is possible.

    This concludes the first part of our series on RVS—the next post will demonstrate how to determine if a Subscription is active, and proper use of the Purchase Updates Request.

    April 25, 2012

    Amazon Mobile App Distribution Program

    Providing a link directly to the Amazon Appstore for Android from within your app is an effective tool for promoting your apps. This type of link is referred to as a deep link and can be used for several purposes including:

    • Linking to the paid version of your app on the Amazon Appstore for Android
    • Linking to another one of your apps on the Amazon Appstore for Android
    • Linking customers to the Amazon Appstore for Android to write a review

    Getting Started

    The Amazon Appstore for Android will automatically pick up on specially formatted links through the use of Android Intents. These are referred to as "deep" links. You have two options for providing a deep link.

    Option 1: Link to the Amazon Retail Website

    This type of link will be picked up by the Amazon Appstore for Android as well as any installed browsers on the device. The base URL is as follows:

    http://www.amazon.com/gp/mas/dl/android?

    Option 2: Link directly to the Amazon Appstore for Android

    This specially formatted link is the preferred method and will directly open up the Amazon Appstore for Android. The base URL is as follows:

    amzn://apps/android?

     

    Link Configuration

    Both deep link formats accept parameters to tailor the link result.

    Parameter Description Amazon Client Example Amazon Retail Web Example
    s= Add a search term. Please note that you would have to use URL Encoding for special characters (e.g. spaces). amzn://apps/android?s=amazon%20mp3 http://www.amazon.com/gp/mas/dl/android?s=amazon%20mp3
    p= Link to the detail page for a specific package name. amzn://apps/android?p=com.amazon.mp3 http://www.amazon.com/gp/mas/dl/android?p=com.amazon.mp3
    asin= All apps in the catalog have a unique identifier known as an ASIN. Use this identifier to link directly to an app by its ASIN. The ASIN for an app can be found on its detail page. amzn://apps/android?asin=B004FRX0MY http://www.amazon.com/gp/mas/dl/android?asin=B004FRX0MY
    showAll=1 Show all apps by the developer of the app corresponding to the specified package name or ASIN (requires “p” or “asin” arg) amzn://apps/android?p=com.amazon.mp3&showAll=1 http://www.amazon.com/gp/mas/dl/android?p=com.amazon.mp3&showAll=1

     

    April 24, 2012

    alexbow

    Weeblets is a new app developer, producing and distributing family-oriented mobile apps based on licensed animated videos.  They launched their first app, VeggieTales Spotisode Collection, as an Amazon Appstore for Android exclusive in early March.  “We knew we’d have the best chance for a successful launch if our app, which melds VeggieTales videos with the Weeblets gaming experience, could be merchandised alongside other VeggieTales products, where the fans already were,” said Weeblets CEO Adam Somer.  “With the promotion Amazon provided us for the exclusive, which they over-delivered on, we knew that it was the best decision we could make.”

    Did the launch of your app perform to your expectations?


    Somer:  This was our first release, so we set our install targets based on research and the stories we’d heard from the many developers we’d talked to during our planning. The launch wildly exceeded our expectations.  Amazon made sure that parents who knew VeggieTales already--and parents who might not yet know, but would likely love VeggieTales--found our app.  We could have made the best app in the world and used the most popular cartoon ever and still failed if we couldn’t get it to the fans.  Discovery is a real problem for developers, and the Amazon exclusive took that problem away and allowed us to focus on the app experience.

      Blog-recommendations_border

    What do you feel are the benefits to selling your app in the Amazon Appstore for Android?


    Somer:  Our apps are based on well-known licensed animations. Amazon’s ability to merchandise alongside related products is very unique and a critical asset when trying to reach the people who already love the properties.   Amazon has a special category and Best Seller list for just for kids’ apps; also sells VeggieTales videos, books, music, and other merchandise; has millions of people looking to load up their new Kindle Fires, and the ability to target promotions to all of them. Most importantly though, Amazon had the willingness to work with us and bring forward all their unique merchandising tools in order to set up a great launch promotional program and put our app in front of a very large number of the right people.

    What’s next for Weeblets?


    Somer:  We’re looking forward to the next stage as we begin to offer new features and levels in the VeggieTales Spotisode Collection, begin to experiment with Amazon’s In-App Purchasing API and look for new ways to promote our apps with Amazon.

    Want the latest?

    appstore topics

    Recent Posts

    Archive