We recently posted an update to the Appstore SDK here.
This update introduces two material changes. These are:
Please download the latest SDK to get the latest UNITY and Adobe plug-ins and remove the old plug-ins.
Setting up your Kindle Fire device for testing and debugging is a simplified process thanks to Android Debug Bridge (ADB) support. Since questions around ADB driver support have come up on Stack Overflow and our developer forums I thought it would be beneficial to walk through the setup process.
Note – this post was updated on April 16th, 2014 to reflect changes in the Amazon Android SDK addon.
First, ensure your development computer has at least one package of Kindle Fire system images installed. This is critical because the package includes the vendor identification needed for ADB to recognize any of the physical Kindle Fire tablets. This is done through the following steps:
For complete information about setting up your development computer and installing the SDK packages, see Setting Up Your Development Environment.
If you installed a previous version of the Kindle Fire USB driver then take the following steps to remove the previous USB device driver and force re-installation of the driver.
Next, we need to turn on ADB support on our actual Kindle Fire device. Follow these steps:
As a security precaution, you should set Enable ADB to Off when you are not trying to connect to the Kindle Fire tablet to your development computer.
First, ensure you have enabled ADB on the Kindle first as described above. For the USB driver to install correctly, Windows must recognize the device as Android Composite ADB Interface during installation. If ADB is not enabled, Windows instead recognizes the device as Portable Devices.
Do the following to install the Kindle Fire USB driver:
Next, do the following to detect your Kindle Fire tablet through ADB:
adb kill-server adb start-server adb devices |
If the serial number does not appear after running adb devices, do the following:
android update adb |
adb kill-server adb start-server adb devices |
If your Kindle Fire device still does not show up you may need to reboot your development machine and then try again.
Perform the following steps if your development computer runs OS X:
./android update adb |
4. In the terminal shell, navigate to your Android SDK platform-tools directory.
5. Run the following commands and confirm that the serial number for your Kindle Fire tablet appears in the list of devices.
If your Kindle Fire device does not show up in the list of devices you may need to reboot your development machine and then try again.
You should now be able to fully test with your Kindle Fire device over the Android Debug Bridge. For additional information on enabling ADB for Kindle Fire Devices, see Setting Up Your Kindle Fire Tablet for Testing.
-Dave (@TheDaveDev)
Last week, I wrote to tell you about the new Dolby SDK that makes it easy for you to optimize the sound on the device to match the different kinds of audio you use in the course of your app. This week, we have some feedback from a developer who has implemented the Dolby Plug-In for their app on Kindle Fire.
Luxurious Animals is a game developer in New York. They wrote the casual game Lux Ahoy!, a netmagazine.com Top-10 game. Before working with Dolby Digital Pro, they didn’t consider audio to be a key component. However after using the Dolby Plug-in, Luxurious Animals had this to say: “The API created a much richer and more immersive experience, making the game feel more exciting and absorbing. It really took our game to the next level.”
Overall, Luxurious Animals found the Dolby Plug-in to be easy to work with and required no changes to the overall workflow:
“Adding the Dolby magic to our app was as easy as linking a JAR file with our project and calling Dolby-specific methods from our app. We used the Game audio profile inside the API, which creates a ‘live’ space to best bring out the effect of fast-moving objects in the audio. The API also offers Music, Movie and Voice profile options. We had Dolby capabilities in the game up and running in less than 15 minutes. The API package comes with a Javadocs and a quick-start guide along with a sample application showing how Dolby APIs should be invoked.
Today, we have a fun casual game that not only has great-looking graphics, but also a rich soundtrack that pulls users in and holds their attention. We are confident these enhancements have increased the overall experience for our customers on the Kindle Fire HD.”
I’m thrilled that Luxurious Animals has been able to improve the customer experience for relatively little effort; it speaks well to the smart API design by the Dolby development team.
To learn more about the Dolby Digital Plus SDK, please read the previous blog post on the topic here, or get the SDK directly from Dolby here.
Amazon allows you to distribute your web apps and mobile-optimized HTML5 websites to millions of Amazon Appstore customers in nearly 200 countries across the globe. With Amazon’s In-App Purchasing API for JavaScript you can increase revenue by enabling compelling monetization strategies. This includes a "freemium" model for your app where the app itself is free but you charge a premium for advanced services or functionality. Your web app can offer customers in app currency, subscriptions and entitlements all through the secure Amazon checkout process.
The first step in implementing In-App Purchasing in your web apps is to download the Amazon Mobile App SDK, then you will submit a new web app to the portal and then finally add a reference to the Amazon Web API libraries in your html.
The latest versions of the Amazon Web API libraries are hosted by Amazon for you. The current urls can always be found in the LATEST_URLS.txt file located in the Amazon Mobile App SDK folder.
<!DOCTYPE html>
<html>
<head>
<title>Button Tester</title>
<!-- Use of this sample code involves calling jQuery from Google
Hosted Libraries and is subject to the terms located here:
https://developers.google.com/speed/libraries/terms
-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
<script src="https://amazon-web-app-resources.s3.amazonaws.com/v0/latest/Amazon-Web-App-API.min.js" type="text/javascript"></script>
<script src="https://amazon-web-app-resources.s3.amazonaws.com/v0/latest/Amazon-Web-App-API-tester.min.js" type="text/javascript"></script>
<script src="js/buttonclicker.js" type="text/javascript"></script>
<link rel="stylesheet" href="buttons.css"/>
</head>
Once you have referenced these JavaScript files you will have everything you need to access the Amazon In-App Purchasing API from your web app.
Before you can make any In-App Purchase calls you need to have a catalog of SKUs set for your web app to use. You can add SKUs to your web app’s catalog by opening the Developer Console, selecting Apps & Services, choosing the web app submission you want to add SKUs to and then clicking on the In-App Items link, which will take you to the list of SKUs currently offered in your web app.
There are three types of SKUs you can offer to your customers.
· Consumables – This type of purchase is available only on the device it was purchased on. Some consumable examples include in-game currency or an extra power up in a game.
· Entitlements – This is content that requires access rights such as unlocking additional game levels or offering specific magazine issues. Entitlements do not expire, are tied to a customer’s Amazon account and are available on any device they access the content from.
· Subscriptions – These are entitlements that are bound by a period of time which auto-renews at the end of the period and is tied to the customer’s Amazon account. Subscriptions are available on any device a customer accesses the content from. You are allowed to have multiple subscriptions for purchase within your app.
Simply click on the type of SKU you would like to add and you will be taken to a new screen where you can provide information about the SKU. For example, if I wanted to offer an Entitlement purchase for my World of Warcraft Realm Status app to track a single realm I would click Add an Entitlement and then enter a Title and SKU.
Next you will need to enter pricing information for your new SKU. In this case, I want to sell a Track Single Realm for $1.00. Amazon gives you the option of setting your own list price for each marketplace or it can match the prices based on your entered base price.
You can also enter a detailed description, along with keywords for the Entitlement. Descriptions can be provided in multiple languages and if no translations are given the default English description will be used.
You also need to provide images of the item for users along with the image you want displayed upon a successful purchase.
Once you have completed this, click Save, and then Submit In-App Item. You will be taken back to our In-App Items screen with the new SKU now listed. In the upper right corner will be a button to download a JSON Data file.
This JSON file will include a list of our SKUs that will be used by the SDK Tester Tool when we want to simulate a purchase in our development environment.
The SDK Tester Tool is included in the Amazon AVD Launcher emulators or it can be installed on a device via the APK included in the Amazon Mobile App SDK under the /Android/InAppPurchasing/tools.
The Button Clicker example includes a similar JSON file that covers all of the purchasable item types.
The JavaScript In-App Purchasing API is designed to encapsulate the complexity behind the purchase process while providing a fully featured API. While building your app, it is important to understand which parts of the purchase flow the app must implement, and which parts are handled by the Amazon Services library.
Note: In order to protect customers, we also require that you serve the page of your app that uses In-App Purchasing over SSL/HTTPS. For more information, please refer to the Making Your Web App Safe documentation
Below is a simplified chart explaining responsibilities during the purchase flow.
In-App Purchasing API for JavaScript is comprised of three elements:
The process workflow between your JavaScript calls and the Amazon Services JavaScript library looks something like this:
You can deliver static content stored locally or dynamic content that is updated over time for customers. For more details about the Purchase Process workflow and the types of deliverable content you refer to the Understanding In-App Purchasing for JavaScript API documentation here.
Now that you understand the process flow, have referenced the proper JavaScript libraries and have created a list of SKUs (or local JSON file) it’s time to call out to the Amazon Services in your own JavaScript.
Every call you initiate via the Amazon Services JavaScript Libraries results in a response received by the corresponding response handler specified in registerObserver(). Each of these responses makes use of a response object and includes the following:
There are also purchase handlers, similar to the In-App Purchasing API for Android that have already been implemented for you inside the Amazon Services JavaScript files. They include the following:
Implementation of the Amazon Services JavaScript library is as follows:
For example, the Button-Clicker example starts off by calling an initialize() function which will set up an IAP observer using amzn_w.IAP.registerObserver() and then checks the response object to see if the web app is in debug mode. If it is an alert box is generated telling the user the app is in development mode. If not it will check for updated Purchases.
Finally, the function sets up handlers for Purchase Response and Purchase Updates Response objects.
// Setup function initialize() { loadPageState(); amzn_wa.enableApiTester(amzn_wa_tester); refreshPageState(); // Setup button press handlers $("#theButton").click(function() { buttonPressed(); }); $("#redButton").click(function() { redButtonPressed(); }); $("#greenButton").click(function() { greenButtonPressed(); }); $("#blueButton").click(function() { blueButtonPressed(); }); // Ensure we can call the IAP API if (amzn_wa.IAP == null) { console.log("Amazon In-App-Purchasing only works with Apps from the Appstore"); } else { // Registers the appropriate callback functions amzn_wa.IAP.registerObserver({ // Called the the IAP API is available 'onSdkAvailable': function(resp) { if (resp.isSandboxMode) { // In a production application this should trigger either // shutting down IAP functionality or redirecting to some // page explaining that you should purchase this application // from the Amazon Appstore. // // Not checking can leave your application in a state that // is vulnerable to attacks. See the supplied documention // for additional information. alert("Running in test mode"); } // You should call getPurchaseUpdates to get any purchases // that could have been made in a previous run. amzn_wa.IAP.getPurchaseUpdates(state.lastPurchaseCheckTime != null ? state.lastPurchaseCheckTime : amzn_wa.IAP.Offset.BEGINNING); }, // Called as response to getUserId 'onGetUserIdResponse': function(resp) {}, // Called as response to getItemData 'onItemDataResponse': function(data) {}, // Called as response to puchaseItem 'onPurchaseResponse': function(data) { onPurchaseResponse(data); }, // Called as response to getPurchaseUpdates 'onPurchaseUpdatesResponse': function(resp) { onPurchaseUpdatesResponse(resp); } }); } } $(function() { initialize(); });
Once initialization is done you can make purchase calls by passing in your SKU title. The example code here is making a call to purchase the more “sample.clicks” SKU.
function buyClicks() { if (amzn_wa.IAP == null) { alert("You are out of clicks, however Amazon In-App-Purchasing works only with Apps from the Appstore."); } else if (confirm("Buy more clicks?")) { amzn_wa.IAP.purchaseItem("sample.clicks"); }
The purchaseItem function will return a response object you need to handle and check for success or failure.
// purchaseItem will cause a purchase response with one receipt function onPurchaseResponse(e) { if (e.purchaseRequestStatus == amzn_wa.IAP.PurchaseStatus.SUCCESSFUL) { handleReceipt(e.receipt); } else if (e.purchaseRequestStatus == amzn_wa.IAP.PurchaseStatus.ALREADY_ENTITLED) { // Somehow we are out of sync with the server, let's refresh from the // beginning of time. amzn_wa.IAP.getPurchaseUpdates(amzn_wa.IAP.Offset.BEGINNING) } refreshPageState(); }
If it gets back a status of PurchaseStatus.SUCCESSFUL it will handle the receipt returned in the response object like so:
// purchaseItem will cause a purchase response with one receipt function onPurchaseResponse(e) { if (e.purchaseRequestStatus == amzn_wa.IAP.PurchaseStatus.SUCCESSFUL) { handleReceipt(e.receipt); } else if (e.purchaseRequestStatus == amzn_wa.IAP.PurchaseStatus.ALREADY_ENTITLED) { // Somehow we are out of sync with the server, let's refresh from the // beginning of time. amzn_wa.IAP.getPurchaseUpdates(amzn_wa.IAP.Offset.BEGINNING) } refreshPageState(); }
In this Button-Clicker example we are setting a Boolean value to true based on a successful purchase. In a real web app you would want to save the purchase receipt to local storage or back to your own cloud storage so you can verify purchase receipts in the future.
If you are running in the development Sandbox Mode we mentioned above calls to the Amazon Services will go through the local SDK Tester App instead of to the Amazon Cloud.
This allows you to simulate purchasing SKUs in your web app without having to spend any actual currency. You have the option to test a purchase inside the browser itself using the included Amazon Service JavaScript Libraries.
In this scenario you need to ensure your JSON file holding the SKUs is located in the same folder as you web app. If you want to test the In-App Purchase on a device you can do so using the SDK Tester tool and a JSON file that has been copied to the SD Storage.
For a complete video walkthrough of the purchase process and SDK Tester tool you can watch the following screencast on our Youtube Channel.
By utilizing the Amazon In-App Purchasing API for JavaScript you are able to quickly implement and test purchases through your existing web app. Customers can take advantage of in app items, subscriptions and entitlements you might offer all through the secure Amazon checkout process.
Be sure to check out our HTML5 Web App materials on the developer portal to get started today!
-Dave (TheDaveDev)
![]() |
This post discusses how Android apps can use Amazon Web Services (AWS) to send e-mail without additional infrastructure. The sample code presented here uses Amazon Simple Email Service to record feedback from users but this same method could be used in the following scenarios:
Amazon Simple Email Service (Amazon SES) is a highly scalable and cost-effective bulk and transactional email-sending service for businesses and developers. Amazon SES eliminates the complexity and expense of building an in-house e-mail solution or licensing, installing, and operating a third-party e-mail service.
This post shows a sample for the Android platform. The complete sample code and project files are included in the AWS SDK for Android. A link to the SDK is available at the end of this post.
To use the AWS SDK for Android, you will need AWS credentials, that is, an Access Key ID and Secret Access Key. If you haven't already signed up for Amazon Web Services, you will need to do that first to get your credentials. You can sign up for AWS here. After you sign up, you can retrieve your credentials at this page.
The sample application described here demonstrates how Android apps can record feedback from their users through Amazon SES. It requires that you already have a verified e-mail address; this address will be used as both the sender and recipient of the message, so it is not necessary to get production access to Amazon SES before using this sample application. You can verify an e-mail address on the AWS console and read more about verification and production access in the Amazon SES Getting Started Guide. Amazon SES can also be used to create other types of e-mails not shown here.
Making requests to Amazon SES requires creating a client for the service. The code below shows how to create a client on both the iOS and Android platforms.
AWSCredentials credentials = new BasicAWSCredentials( PropertyLoader.getInstance().getAccessKey(), PropertyLoader.getInstance().getSecretKey() );AmazonSimpleEmailServiceClient sesClient = new AmazonSimpleEmailServiceClient( credentials ); |
SES will accept both regular and raw e-mails. Our application makes use of the regular method, meaning we do not have to construct our own headers. Regular e-mails require a source, destination (list of to, cc, and bcc addresses) and a message, which itself comprises a body and subject. The code below shows how to create the various parts of the email on both the iOS and Android platforms.
String subjectText = "Feedback from " + nameField.getText();Content subjectContent = new Content(subjectText); String bodyText = "Rating: " + ratingBar.getRating() + "\nComments\n" + commentsField.getText();Body messageBody = new Body(new Content(bodyText)); Message feedbackMessage = new Message(subjectContent,messageBody); String email = PropertyLoader.getInstance().getVerifiedEmail();Destination destination = new Destination().withToAddresses(email); |
Once we've constructed our e-mail components, it simply becomes a matter of creating a SendEmailRequest
and passing this to the SES client we created earlier. The code below shows how to create a SendEmailRequest
and send it with Amazon SES on both the iOS and Android platforms.
SendEmailRequest request = new SendEmailRequest(email,destination,feedbackMessage);SendEmailResult result = clientManager.ses().sendEmail(request); |
A sample application that includes this code is provided in the AWS SDK for Android. The download link can be found on the following pages:
For more information about using AWS credentials with mobile applications see the following article:
Please feel free to ask questions or provide comments in the Mobile Development Forum.
January 26, 2012
Yosuke Matsuda
Amazon DynamoDB is a fast, highly scalable, highly available, cost-effective, non-relational database service. Amazon DynamoDB removes traditional scalability limitations on data storage while maintaining low latency and predictable performance. The sample mobile application described here demonstrates how to store user preferences in Amazon DynamoDB. Because more and more people are using multiple mobile devices, connecting these devices to the cloud, and storing user preferences in the cloud, enables developers to provide a more uniform cross-device experience for their users.
This article shows sample code for the Android platform. The complete sample code and project files are included in the AWS SDK for Android. Links to the SDK are available at the end of this article.
To use the sample app, you'll need to deploy a token vending machine (TVM). A TVM is a cloud-based application that manages AWS credentials for users of mobile applications. To deploy the TVM, you'll first need to obtain your own AWS credentials: an Access Key ID and Secret Key.
If you haven't already signed up for Amazon Web Services (AWS), you will need to do that first to get your AWS credentials. You can sign up for AWS here. After you sign up, you can retrieve your credentials at this page. The credentials will be used to set up the TVM to authenticate users of AWS mobile applications. Sample Java web applications are available here: Anonymous TVM and Identity TVM (this sample uses Anonymous TVM).
In Amazon DynamoDB, a database is a collection of tables. A table is a collection of items, and each item is a collection of attributes. For our app, we create a single table to store our list of users and their preferences. Each item in the table represents an individual user. Each item has multiple attributes, which include the user's name and their preferences. Each item also has a hash key—in this case, userNo
—which is the primary key for the table.
The app demonstrates how to add and remove users, and modify and retrieve their preference data. The app also demonstrates how to create and delete Amazon DynamoDB tables.
In order to create an Amazon DynamoDB client, we must first register the mobile device with the token vending machine (TVM). For this sample, we use the Anonymous TVM to register the device. Then we store the UID and key returned by the TVM on the device.
RegisterDeviceRequest registerDeviceRequest = new RegisterDeviceRequest(this.endpoint, this.useSSL, uid, key);ResponseHandler handler = new ResponseHandler();response = this.processRequest(registerDeviceRequest, handler);if (response.requestWasSuccessful()) { AmazonSharedPreferencesWrapper.registerDeviceId(this.sharedPreferences, uid, key);} |
The following code demonstrates how to request that the TVM generate temporary credentials, and how to store the returned credentials on the device.
Request getTokenRequest = new GetTokenRequest(this.endpoint, this.useSSL, uid, key);ResponseHandler handler = new GetTokenResponseHandler(key);GetTokenResponse getTokenResponse = (GetTokenResponse) this.processRequest(getTokenRequest, handler);if (getTokenResponse.requestWasSuccessful()) { AmazonSharedPreferencesWrapper.storeCredentialsInSharedPreferences( this.sharedPreferences, getTokenResponse.getAccessKey(), getTokenResponse.getSecretKey(), getTokenResponse.getSecurityToken(), getTokenResponse.getExpirationDate());} |
To make service requests to Amazon DynamoDB, you need to instantiate an Amazon DynamoDB client. The code below shows how to create an Amazon DynamoDB client for Android using the stored temporary credentials from the TVM.
AWSCredentials credentials = AmazonSharedPreferencesWrapper .getCredentialsFromSharedPreferences(this.sharedPreferences);AmazonDynamoDBClient ddb = new AmazonDynamoDBClient(credentials); |
Each user's preferences are stored as items in an Amazon DynamoDB table. The following code creates that table using the client we created above. Every Amazon DynamoDB table require a hash key. In this sample, we use userNo
as the hash key for the table.
AmazonDynamoDBClient ddb = UserPreferenceDemoActivity.clientManager.ddb();KeySchemaElement kse = new KeySchemaElement() .withAttributeName("userNo") .withAttributeType(ScalarAttributeType.N);KeySchema ks = new KeySchema().withHashKeyElement(kse);ProvisionedThroughput pt = new ProvisionedThroughput().withReadCapacityUnits(10l).withWriteCapacityUnits(5l);CreateTableRequest request = new CreateTableRequest() .withTableName(PropertyLoader.getInstance().getTestTableName()) .withKeySchema(ks) .withProvisionedThroughput(pt);ddb.createTable(request); |
Before we can move to the next step (creating users), we must wait until the status of the tables is ACTIVE. To retrieve the status of the table, we use a describe table request. This request returns information about the table such as the name of the table, item count, creation date and time, and its status.
AmazonDynamoDBClient ddb = UserPreferenceDemoActivity.clientManager.ddb();DescribeTableRequest request = new DescribeTableRequest() .withTableName(PropertyLoader.getInstance().getTestTableName());DescribeTableResult result = ddb.describeTable(request);String status = result.getTable().getTableStatus(); |
For each user, we'll create an item in the table. An item is a collection of attribute/value pairs. For each item, we'll have three attributes: userNo
, firstName
, and lastName
. These are added to a put item request in order to create the item.
HashMap<String, AttributeValue> item = new HashMap<String, AttributeValue>();AttributeValue userNo = new AttributeValue().withN(String.valueOf(i));item.put("userNo", userNo);AttributeValue firstName = new AttributeValue().withS(Constants.getRandomName());item.put("firstName", firstName);AttributeValue lastName = new AttributeValue().withS(Constants.getRandomName());item.put("lastName", lastName);PutItemRequest request = new PutItemRequest().withTableName( PropertyLoader.getInstance().getTestTableName()).withItem(item);ddb.putItem(request); |
To remove a user from the list simply means deleting the corresponding item from the table. We specify the item we wish to delete using the hash key for the item.
AmazonDynamoDBClient ddb = UserPreferenceDemoActivity.clientManager.ddb();Key primaryKey = new Key().withHashKeyElement(targetValue);DeleteItemRequest request = new DeleteItemRequest().withTableName( PropertyLoader.getInstance().getTestTableName()).withKey(primaryKey);ddb.deleteItem(request); |
We can retrieve a collection of users with a scan request. A scan request simply scans the table and returns the results in an undetermined order. Scan is an expensive operation and should be used with care to avoid disrupting your higher priority production traffic on the table. See the Amazon DynamoDB developer guide for more recommendations for safely using the Scan operation.
AmazonDynamoDBClient ddb = UserPreferenceDemoActivity.clientManager.ddb();ScanRequest request = new ScanRequest();request.setTableName(PropertyLoader.getInstance().getTestTableName());ScanResult result = ddb.scan(request);ArrayList<HashMap<String, AttributeValue>> users = (ArrayList<HashMap<String, AttributeValue>>) result.getItems(); |
Knowing a user's userNo
, the hash key of the table, it is easy to find the item for the user. This next snippet shows how to get all the attributes for an item using the hash key.
AmazonDynamoDBClient ddb = UserPreferenceDemoActivity.clientManager.ddb();AttributeValue userNoAttr = new AttributeValue().withN(String.valueOf(userNo));Key primaryKey = new Key().withHashKeyElement(userNoAttr);GetItemRequest request = new GetItemRequest().withTableName( PropertyLoader.getInstance().getTestTableName()).withKey(primaryKey);GetItemResult result = ddb.getItem(request);HashMap<String, AttributeValue> userPreferences = (HashMap<String, AttributeValue>) result.getItem(); |
The hash key also makes it easy to update an attribute for an item.
AmazonDynamoDBClient ddb = UserPreferenceDemoActivity.clientManager.ddb();AttributeValue av = new AttributeValue().withS(value);AttributeValueUpdate avu = new AttributeValueUpdate().withValue(av).withAction(AttributeAction.PUT);Key primaryKey = new Key().withHashKeyElement(targetValue);HashMap<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();updates.put(key, avu);UpdateItemRequest request = new UpdateItemRequest() .withTableName(PropertyLoader.getInstance().getTestTableName()) .withKey(primaryKey).withAttributeUpdates(updates);ddb.updateItem(request); |
The easiest way to remove all the user preference data is to delete the Amazon DynamoDB table. The following code shows how:
AmazonDynamoDBClient ddb = UserPreferenceDemoActivity.clientManager.ddb();DeleteTableRequest request = new DeleteTableRequest() .withTableName(PropertyLoader.getInstance().getTestTableName());ddb.deleteTable(request); |
The code in this article demonstrates how to use Amazon DynamoDB as a storage device for your mobile application. You can find more information about Amazon DynamoDB here.
Sample apps that include the code from this article are provided with the AWS SDK for Android. You can download the SDK using the following link:
For more information about using AWS credentials with mobile applications see the following article:
Authenticating Users of AWS Mobile Applications with a Token Vending Machine
Please feel free to ask questions or provide comments in the Mobile Development Forum.
At last week’s CES, it was hard to ignore the fact that many technology pundits are considering 2011 as the year of the tablet. And although Apple should be thanked for resurrecting interest in tablets in 2010, 2011 will see a record breaking surge in the number of vendors bringing new tablets to market. Sean Dubravac, Chief Economist and Director of Research, Consumer Electronics Association, predicted, “While many firms are touting product launches within the tablet sphere for the fourth quarter of 2010, the real action will occur a few weeks after the end of the quarter at CES.” The next few weeks will be telling for the future of the tablet and so far it’s looking quite bright.
The good news for you, the Android developer, is that many of these tablets will be sporting Android OS and, with the recent announcement of the Amazon Appstore Developer Portal, you have a convenient way of offering your apps to both tablet and smartphone users. We’re not mandating that you optimize your apps for tablets as well as smartphones, but it’s definitely something you should consider.
The expected surge in the number of tablets on the market and the number of Android devices a single user will own brings forth new opportunities and challenges. The opportunities are clear—more devices mean more users, more hardware features and more APIs to take advantage of. These new tablets will continue to feature larger screens and supported resolution levels, ample amounts of disk space and extremely fast processer speeds that are not far behind that of a typical laptop. An important thing to remember as a developer is that customers may be using your app across tablets and smartphones – no longer just one or the other.
A quick comparison of the best selling smartphones and tablets on Amazon.com shows that tablets boast 50-100% more screen real-estate and 50% more disk space. Furthermore, many of the tablets demonstrated at CES also feature dual-core CPUs. These differences make it more important than ever for developers to be aware of the device capabilities and limitations. With Amazon.com’s convenient 1-Click purchase and digital locker features, customers will be able to buy your apps and run it on any of their Android devices. Unfortunately, the growth in devices will present one of the biggest challenges for you—you want to continue to build and extend your killer apps and offer it to the tens of millions of Amazon.com customers, but you also want to keep your customers happy by setting expectations on how and where the apps can be run.
The Android SDK requires that each application contain a file called AndroidManifest.xml within the apk. This is where you can let the system know what your app needs at a minimum to run and what resources and services it will use. For instance, if you are building a word processor app that is designed to only run on a tablet, you will want to set the android:largeScreens attribute to “true” on the <supports-screens> property, while explicitly setting the small and normal screen flags to false. If you don’t declare this requirement for your app, then the Android system will assume it works on all screen sizes.
On the other hand, if you are building a game that looks great on any phone or tablet, then you can declare this in the xml file by including the following settings:
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true" />
One thing to be aware of, however, is that once you declare support for all screen sizes, you will want to check the DisplayMetrics settings at runtime to make important display decisions in your code. This information can be used to make performance optimizations, such as displaying low to medium resolution images on small devices and high resolution images on large screens—a great way to avoid creating multiple versions of your app.
Apps that depend on hardware resources, such as GPS, Wi-Fi or Bluetooth capabilities, can define these requirements by appropriately setting the <uses-features> option.
Furthermore, with last month’s announcement of the Gingerbread release, there are now 6 flavors of Android OS in use. If the trend over the past two years continues, you can expect one more major release (3.0, Honeycomb) and another minor release to be announced before 2012. With major features being added in every new platform version, such as improved copy-and-paste and faster text input processing in Gingerbread, you will want to take advantage of these capabilities and also ensure your apps only run under their supported environment. The manifest provides a way to enforce dependencies on specific SDK features by using the <uses-sdk> flag.
Customer satisfaction is a key driver behind Amazon.com’s success. As you develop and offer your application to Amazon.com’s customers, following these Android development best practices guidelines is a great start towards achieving similar success.