navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Developing Applications for Amazon Kindle Devices

Developing Applications for Amazon Kindle Devices

with Lee Brimelow

 


In this course, Lee Brimelow introduces the Kindle Store and explains how to take your existing applications and tailor them to the Kindle environment. Learn about the three key APIs unique to Kindle: In-App Purchasing for selling digital content and subscriptions, GameCircle for creating leaderboards and registering achievements, and Maps, which adds interactive maps to most Kindle Fire tablets.

The course also covers multiscreen development and testing with the Kindle Emulator, as well as actual deployment to the Kindle store.

show more

author
Lee Brimelow
subject
Developer, Mobile Apps, Games
software
Android , Kindle
level
Intermediate
duration
4h 31m
released
Mar 25, 2013

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:00 (MUSIC).
00:04 Welcome to Developing Applications for Amazon Kindle Devices.
00:09 My name is Lee Brimelow, and in this course, you will be learning all about
00:13 how to develop Android applications that take advantage of the various
00:17 Amazon-specific APIs that are available for Kindle devices.
00:23 You'll learn things like how to integrate in-app purchasing allowing your users to
00:28 seamlessly buy things directly inside your application.
00:33 Now, if you're interested in building games, I'll being covering how to add
00:37 global leaderboards and achievements. And I'll be covering the Amazon Maps API
00:42 allowing you to add location of where I'm mapping into your apps.
00:48 You'll learn how to adapt and optimize your application for the different Kindle
00:52 device models such as the Kindle Fire and the Kindle Fire HD.
00:58 Finally, I'll cover how to actually publish your applications to the Amazon
01:03 Appstore. So after finishing this course, you
01:07 should have an excellent understanding of how to develop applications for Amazon
01:11 Kindle Devices.
01:14
Collapse this transcript
What you should know
00:00 So before we actually get started with the course, let's go over the skills that
00:04 you should know before you try to tackle Kindle development.
00:09 Well as you may or may not know, all applications on Kindle devices are
00:13 Android applications. So obviously you need to have Android
00:18 development skills before you attempt this course.
00:22 In more specifically you should know how to use the Eclipse development
00:27 environment that Google provides to android developers, you should know how
00:31 to develop Android applications using Java.
00:36 Now there are other ways to develop android applications such as Adobe Air
00:40 and unity but in this course we using straight Java to create our applications.
00:49 Should also be familiar with the Android Developer tools and this includes things
00:53 like ADB, which allows you to actually to connect to devices, to side load
00:57 applications, things like that. And also about using virtual devices.
01:04 Better known as emulators, and signing and exporting applications.
01:10 Now, the actual publishing of applications is going to be unique to
01:13 Kindle devices because we're going to be going through the Amazon app store, as
01:18 opposed to the Google Play store. Now, if you don't have these skills, well
01:24 there's an excellent course here on lynda.com that I did called Android App
01:28 Development with Java Essential Training. So in this course you basically start
01:34 from scratch without having to have any knowledge about Android development, and
01:38 it teaches you all of the fundamentals. So, if you're not up to speed with
01:43 Android development, I would recommend doing this course first, before you try
01:48 to tackle Publishing to Kindle Devices.
01:53
Collapse this transcript
Using the exercise files
00:00 If you're a premium member of the Lynda.com Online Training Library or if
00:04 you're watching this on a DVD-ROM, then you have access to the exercise files for
00:08 this course. Now, I'll be keeping the exercise files
00:13 folder on the desktop for easy access, so let's just open it up so I can show you
00:16 what's inside. So I'm actually providing you an Android
00:22 project that we're going to be starting with, because remember, in this course,
00:26 we're going to learn about the Amazon-specific APIs that target the
00:29 Kindle devices. Now I've also provided the finished
00:34 project that you will have completed at the end of the course.
00:38 Now, in the assets folder, there is artwork and other.
00:42 Other just contains a couple of files that we're going to be using.
00:45 And this folder contains things like all of the artwork, icons, promotional images
00:51 that we're going to be uploading to the Amazon development portal.
00:56 It also contains multi-screen graphics, because the Kindle devices obviously come
01:01 in different sizes, different pixel densities, so I've also provided the
01:06 graphics for you to target those devices. Now, if you don't have access to the
01:12 exercise files for this course, then you can simply create your own assets as we
01:17 go along.
01:19
Collapse this transcript
1. Preparing for Development
Overview of the Amazon Appstore
00:00 So if you have a Kindle device? You don't have access to the regular
00:04 Google Android marketplace. So the place in which you download
00:08 applications, is from the Amazon Appstore.
00:12 And in this course, I'm going to be showing you how to create and publish
00:15 your application. To this app store, so that Kindle users
00:19 can use your applications. Now it is possible on a regular Android
00:24 device to come to the Amazon website and download the Amazon Appstore.
00:30 And your applications that are published here will most likely work just fine on
00:35 regular android devices as well but again in this course we're going to focus on
00:39 targeting Kindle devices. So here on the amazon.com website I'm
00:45 going to go to the left here to Appstore for Android and then go to Apps.
00:51 So users essentially have two options, they can come to the website, choose an
00:55 application and buy it, or actually go to the Appstore on their device.
01:01 But the Appstore here works just like most of the other app stores that are out
01:04 there. So I'm just going to scroll down, I can
01:07 see, what the top games are, top applications, I'm just going to click on
01:11 one here called Cut the Rope, which is a very popular game.
01:16 And I want to highlight a nice feature, it's this Test Drive Now button.
01:22 What it does is it launches an emulator, and it actually lets me, interact with
01:26 the application, to see if it's something that I want to buy.
01:30 (MUSIC) So you can see I can actually start playing this game here and, it's
01:34 just a good way to kind of preview the application.
01:39 Now not all applications have this Test Drive Now enabled.
01:44 So that's here on the website, so I could buy this, then go to my device and
01:48 download it and start using it. I just wanted to show you what it
01:52 actually looks like on a Kindle device, so this is a screenshot from my Kindle HD
01:57 7 inch. And it's just again, very similar to
02:01 other App stores, you can search, you can go through best sellers, new releases,
02:06 and you just click on an application. It will download, and then you can start
02:12 interacting with it.
02:13
Collapse this transcript
Overview of Kindle devices
00:00 So before you start developing for Kindle devices, it's important to have a good
00:04 understanding of what the different devices are that are available.
00:08 So I'm on the Amazon website again here. Now these two at the left, these are
00:13 actually eReaders and these have nothing to do with Android and you're not going
00:17 to be deploying your applications to these devices.
00:21 The other three are the latest generation of the Kindle tablets.
00:27 The first one at the right, this is the regular Kindle Fire.
00:31 This is actually the second generation of this tablet with much better specs.
00:37 Then there's a Kindle Fire HD, seven inch, and that's the device that I
00:40 personally own. And then there's an 8.9 inch Kindle Fire
00:46 HD. Now this one comes in two versions, the
00:50 main difference is one is 4G compatible and the other is just a Wi-Fi device.
00:57 So there was a first-generation Kindle Fire, but in this course we're going to
01:02 be targeting this latest generation of Kindle devices.
01:07 Now I'm going to go over to the developer portal because they have this nice chart
01:11 giving you all the specifications of the different devices.
01:16 There's a couple of important things that I want to highlight.
01:20 You know in Android development that oftentimes you need to create different
01:25 resources for different DPIs or LCD densities.
01:30 So here we can see the Kindle Fire Second Generation is an M DPI, the seven inch
01:35 and the 8.9 inch are H DPI devices, so that's an important thing to know.
01:42 And also, the resolutions of the different devices.
01:46 And then another important thing is which version of the Android operating system
01:51 are these devices based on. So we can see here that the newer line of
01:56 devices, that's the Kindle Fire 2nd generation, the seven inch, and two 8.9
02:02 inches, are all based on Android 4.0.3, which is Ice Cream Sandwich.
02:09 The original version of the Kindle Fire was built on top of Gingerbread, Android
02:15 2.3 Dot 3 but we're not going to be worrying about that device in this
02:20 course. So again if you want all of the details
02:26 about how these devices differ from one another this page on the developer portal
02:31 is definitely one of the best places to go to.
02:36
Collapse this transcript
Registering as an Amazon developer
00:00 So the first step in being able to publish applications to the Amazon App
00:05 Store, is to actually become a registered developer with Amazon.
00:11 So, if you come to developer.amazon.com, this basically showcases all of their
00:15 developer offerings. But we want to click on Mobile App
00:19 Distribution, and this will take you to the distribution portal.
00:25 And this portal is where you're going to be doing a lot of different stuff, this
00:29 is where there's some good documentation, tutorials, and it's also where you're
00:33 going to be creating and setting up your apps.
00:37 So we're going to create an account now, so I'm going to click this.
00:40 Now this is going to ask you for a sign in.
00:41 Now, I'm assuming most people out there have bought something on amazon.com
00:49 before. And this is the account that you can use
00:54 here, unless for some reason you wanted to create a different account.
01:00 So I'm just going to fill this in, this is just an email account I created for
01:05 the course, and I'll put in my password. And then it will send it off.
01:12 And now it's going to ask me for a bunch of different information to setup my
01:16 account. So it's already got my first name, last
01:21 name, email address, phone number, I'm just going to put in a fake one,
01:26 650-555-1212. Developer, name or company name.
01:32 Again, if you're an Indie developer, this could be just your name.
01:35 If you're actually a application development company, or game studio, then
01:39 you would put that name in here. So, I'm just an individual, so I'll put
01:45 that in. We can leave the description blank for
01:48 now. So I'm just going to put in a fake
01:53 address here, city, some city, California 94444.
02:02 Now this customer support email address, phone and website.
02:06 This is obviously something that you're going to want to do.
02:09 Assuming you want users of your application to be able to contact you and
02:12 give you feedback. So I'm going to click save and continue.
02:17 And then essentially, now it's going to take me to the next section, which is
02:21 where I essentially have to agree to this agreement.
02:26 Now you definitely want to read through this, and again, make sure that you want
02:30 to actually publish your applications under these terms.
02:35 I'm just going to come down and say accept and continue.
02:41 Now here's an important question is, do you plan to monetize apps?
02:45 And this could be either charging for for the apps, or giving the app away free,
02:48 but selling items inside of your application, which we're going to be
02:51 doing later in the course. So, I'm going to say yes to that, and now
02:57 it's going to ask me for my bank account information.
03:02 Now obviously I'm not going to be showing you that, so I'm going to go ahead, fill
03:06 this information in, click save and continue, and then we will continue form
03:10 that point. Okay, so I've just entered my bank
03:15 account information and submitted it. Now I did want to point out that the last
03:20 step, and this step, is going to be different based on what country you
03:24 actually live in. Obviously I'm in the US, so this is
03:28 giving me specific information relating to how I'm going to be able to accept
03:32 payment. So, again, this could be different based
03:37 on where you're actually developing from. So the next part of the process is this
03:42 tax identity interview. So after you go through this, you're
03:47 essentially going to have an IRS document that you can print out for your records.
03:53 Now again, in this section, there's going to be some personal information
03:56 that I can't show. So as soon as I'm done with that, we will
04:00 continue. Okay so I have completed that tax
04:04 interview and clicked Done, and essentially now I am a registered Amazon
04:08 developer. And it should bring you to this page
04:11 right here. And you'll know that you're successful if
04:15 you see the My Apps link here. This is where we're actually going to be
04:19 defining our applications. Now the last step is to simply download
04:25 the SDK. So I'm going to click on this SDK link,
04:28 and click Download SDK, and it's basically showing you the contents here,
04:33 and it should automatically start downloading.
04:38 Now, we're going to be working off of the desktop with all of our files, just to
04:43 make it easier. So, where ever this zip file actually has
04:48 downloaded for you, you're going to want to drag it onto the desktop, and unzip
04:52 that zip file onto the desktop. Okay, so it's finished downloading.
04:59 Now let me go to my desktop, and again, I'm just going to unzip this.
05:05 And again, if you're on Windows, the same process.
05:08 You want to download it, extract the folder inside to the Desktop.
05:13 So I'm just going to move that to my Trash.
05:15 Now I'm actually going to rename this folder Amazon_SDK.
05:20 And if we look in here, we can see that we have APIs for In App Purchasing, for
05:27 GameCircle, and also for Amazon Maps. So with that you are now set up to begin
05:35 doing development for Kindle devices.
05:40
Collapse this transcript
Setting up the Mac development environment
00:00 Okay, so the next step is to make sure that you have your Android development
00:04 environment properly set up to do Kindle development.
00:09 Now I'm assuming a lot of you may already have the Android SDK and the ADT
00:13 Developer tools but I'm going to go through this as if we're starting from
00:17 scratch. So I'm at developer.android.com I'm
00:22 going to click on Get The SDK. OK, now one of the things I have to give
00:28 credit to is Google has really improved the workflow.
00:33 It used to be that you used to have to get all these different tools and
00:36 download a clips and plug them all together.
00:39 Well now there's just a single SDK download called the ADT Bundle and that
00:44 includes all of the tools that you need to do Android development.
00:50 And you can see it should automatically detect your operating system.
00:54 Now there are some system requirements. Now since we're on Mac, you almost
01:00 definitely have the JDK installed. And if you want to check just going to go
01:06 over to the command line and say javac - version.
01:10 And you can see it there. So as long as javac actually returns
01:16 something then you're all set and as long as it's 1.6 So now if for some reason you
01:23 don't have a JDK on your system, you can get it just through software update.
01:33 And here you can see all the software that I need to install to update, but a
01:38 regular one is the Java Update, for OS X. So if you just come in here and make sure
01:44 you update your computer with the latest version of Java.
01:49 You'll have the JDK installed. OK.
01:53 So, what I'm going to do now is just to click download, and I'm going to agree to
01:57 the terms and conditions. Click download here, and it's about 365
02:03 megabytes, so this is going to take a while My download is going to go to my
02:08 desktop. If your Download folder is somewhere
02:13 else, just drag that ZIP file onto the desktop, and we'll continue once this is
02:17 finished downloading. Okay, that SDK is finished downloading,
02:24 and I have the ZIP file on my desktop So I'm just going to Double-click it, to
02:29 expand the contents to my desktop. Okay, so it's done unzipping, I'm
02:37 going to put the folder here, now I'm just going to move that to the trash.
02:43 And I'm going to rename this to android_sdk.
02:51 So we have our 2 sdk's now, both extracted to the desktop.
02:55 So, there's going to be some tools in the Android sdk that we're going to be using,
03:00 like ADB. It's helpful if you have the location of
03:04 these added to your bash profile, so when you're on the command line, you can be
03:09 anywhere to reference it. So I am going to go to the Terminal
03:15 window, so what you first want to do is to see if you have a bash profile filed
03:20 already, and in the user directory I am going to click open -e to open it and
03:25 text to edit and then .bash_profile. Now you can see that for me it already
03:33 exists. Now when I open it up essentially this
03:37 takes whatever is on the path currently and apens a certain strength to it.
03:42 And you can see I've already pre-filled mine with the correct location.
03:46 So I'm on the desktop to Android SDK, SDK and Platform tools.
03:51 So now if you don't already have a .bash_profile you can just create that
03:56 file new, you can actually just say touch and then actually, let me just create a
04:02 fake document so .bash_profile2, like that.
04:08 That essentially creates the file for you.
04:11 And then, you can use that same command I just showed you to edit the bash profile.
04:16 Alright, so I'm going to close the command like.
04:20 And let's go into that Android SDK folder.
04:22 Now, if you haven't used it in awhile, we have two folders.
04:27 One is the Eclipse tool. Then the other is the SDK.
04:31 Now it's important that these two folders stay side by side, because you know they
04:34 interact with each other, based on the fact that they're in the same directory,
04:38 so don't move one folder to a different directory.
04:42 So if we look in the SDK Is all the stuff that you're used to.
04:47 Again this is the folder that we added to our path so we can use ADB from anywhere.
04:52 So let's go into the Eclipse folder, and I'm going to launch up a clip.
04:58 Now you'll notice that this is actually a branded version of Eclipse now,
05:03 specifically for Android development. So again the workflow is a lot nicer than
05:09 it used to be. Okay, under select a workspace, I always
05:13 like to call mine Android, and this is where all your projects are going to be
05:17 saved, I'll use it as the default, click OK.
05:24 And then we'll let this launch up. You can see when it first launches up we
05:28 just have this Welcome page, that links to some tutorials and to some other
05:31 resources, which is actually pretty helpful, so definitely check that out.
05:37 But when we close it, we now have a fully working Android development environment.
05:43 So what we now want to do is to make sure we have the correct SDKs downloaded for
05:48 doing our Kindle development. So I'm going to go to the SDK Manager
05:53 here and this is going to start up. Now automatically you get the latest
05:59 version of the Android operating system, which is 4.2 but remember that the new
06:03 line of Kindle devices actually run on Ice Cream Sandwich.
06:08 So we want to make sure that we actually download that version of the Android
06:13 operating system, and that's 4.0.3 API level 15.
06:19 Now if we look inside of here, I'm not going to download everything in here,
06:22 just because it takes a long time. So I'm just going to choose the SDK
06:26 platform itself. Then the arm system image which is the
06:30 architecture that the Kindle devices use. Now if you've used the SDK manager
06:35 before, you may have remembered that there used to be the Kindle components
06:40 built into the SDK manager here, and they no longer are.
06:47 So in order for us to see those, we need to go to Tools > Manage Add-on Sites >
06:53 User-defined Sites > New, and now we need to give the URL to that add-on site.
07:03 So it's actually http://kindle-sdk -s3.amazonaws.com/addon.xml.
07:19 Now, I got this string from the developer portal.
07:24 So again, might want to grab it from there just so if there are any changes.
07:29 So once I've added that I'm going to click OK.
07:32 Click close. And immediately you'll see that the
07:36 Kindle Fire components are now in here. So I'm going to select those as well.
07:44 Now the other thing we want to do is to go down under Extras, and you can see
07:48 that we can download the Kindle Fire device definitions.
07:53 And this is going to help us when we're creating our emulators.
07:56 So we want to check that off. You don't need the Kindle Fire USB driver
08:01 if you're on the Mac platform and with those things selected, I'm now going to
08:06 install those six packages. Now, again, if you wanted to target the
08:13 1st generation Kindle device, you could download the 2.3.3 version of the Android
08:18 operating system, but again, we're not going to be targeting that device in this
08:23 course. So I'm going to click Install 6 Packages.
08:29 I'm just going to accept all of the licenses and click Install.
08:33 Now this can take quite a while to download, so I'm going to let it
08:37 download, and then we'll continue.
08:41
Collapse this transcript
Setting up the Windows development environment
00:00 Okay, now I want to make sure that we're all using a current and working Android
00:04 development environment. So if you go to
00:08 developer.android.com/sdk, you can download the latest ADT bundle.
00:15 And I have to give props to Google, because they made this whole thing a lot
00:17 more seamless. You have all of the development tools,
00:21 the SDK tools, all together in one package and it's a lot easier.
00:26 So you should automatically detect what operating system you are on that I want
00:31 you go down to system requirements because in order for clips to run you
00:35 need to have a JDK installed. The Java Development Kit, and this
00:41 doesn't automatically come on, at least as far as I know, on Windows machine at
00:45 all. And so if you haven't previously
00:49 installed the JDK, come down to this link, and you're going to click, and it's
00:54 going to take you to the Oracle website, where you can download the JDK.
01:01 Now, you don't want to download the newest version, which is JDK 7 just
01:06 because Eclipse is not yet compatible with that.
01:11 So we're going to go to previous releases, and then from here, we're
01:16 going to click on Java SE 6, and then this will allow us to download the
01:22 development kit and get the JDK 6. So I'm going to click on that.
01:32 So now you want to choose which version is best for your operating system.
01:36 Amazon recommends that even if you have a 64 bit machine, you should get the X86
01:41 version, so go ahead and do that. So you're just going to download this and
01:47 go through the installer, and then it will install JDK on to your system.
01:52 And, that's again required for Eclipse to operate properly, but we're also going to
01:57 be using some tools that come in the JDK later on in the course.
02:03 So I'm going to click download the SDK. It's going to ask me to agree to the
02:09 terms, and then choose the correct bit architecture for my platform, so minus 64
02:14 bit And now I'm going to click Download the SDK.
02:19 Now this is going to take quite a while to download, it's almost 400 megabytes.
02:23 So when it's finished, I want you to take the zip file, wherever your downloads go,
02:28 and bring that zip file onto the desktop, and then we'll continue from there.
02:35 Okay. So now I have the SDK downloaded, and I
02:37 have that zip file here on my desktop, So all I'm going to do is right click and
02:41 choose extract all. And it's going to ask me for a
02:46 destination for this. And I'm going to call the folder
02:51 Android_SDK and click Extract, and again this might be slightly different
02:58 depending on what operating system that your actually using.
03:06 Okay, so that's finished unzipping now and I can actually just move this into
03:14 recycle bin. Now actually just look inside of that
03:20 android SDK folder. So it contains another folder and inside
03:25 of that folder. We essentially have 2 folders, one is
03:29 eclipse, and that contains the actual development environment.
03:33 And then the other is the actual Android SDK itself.
03:37 So, what I'm going to do is to go into the eclipse folder, double click it to
03:41 launch it. And one of the things you'll notice this,
03:45 this is a branded version of Eclipse called Android Developer Tools, so again
03:50 it's much more of a slick kind of workflow than you might be used to.
03:56 And here again, if you haven't installed the JDK on your system, you may get an
04:00 error there telling you that you need to install a JDK.
04:07 So for our workspace, I was, usually just call mine Android, and again I'll say use
04:12 this as the default, and click Okay. And we'll let it launch up here.
04:20 And now it's launched, and you can see that the first thing That it pops up,
04:26 well it actually ask you here do you want to contribute usage statistics?
04:35 I'm going to say no. The first thing that launches up is this
04:39 new welcome screen. And it just provides some nice links to
04:42 tutorials to some of the tools. So that is definitely a nice thing to
04:46 have. Okay so now you have a working Android
04:50 development environment. But we're not finished with the setup
04:54 yet. So what I'm going to do is to come back
04:56 to the browser. We're also going to need Open SSL, later
05:00 on in the course when we're actually going to need to generate some hash keys
05:05 and MD5 fingerpritns, we're going to need the JDK which we already installed And
05:10 open ssl. So if you go to the Google code project
05:15 for open ssl for windows. And click on downloads.
05:20 And then you can just click on the latest version for your architecture.
05:25 So minus 64 bit. So I'm going to go ahead and download
05:31 that file. And once it's finished downloading, again
05:37 it's just a zip file, I am going to open that up and I am going to say Extract,
05:43 Extract all and I am going to save this to my desktop.
05:51 And I'm just going to call the folder open ssl, and click Extract.
05:58 Okay, so that's done. Minimize Chrome.
06:05 And you can see, we now have that open ssl folder.
06:08 Now we're going to be using tools from a bunch of different places on the command
06:12 line later. We're going to be using a tool from the
06:16 Open SSL, one from the Java JDK and also the Android tools like ADB.
06:22 So it's going to be helpful if we update our path so that we can use these tools
06:25 from wherever we are on the command line. So to do that in Windows, we right click
06:32 on computer, or my computer on your desktop.
06:37 Go to properties, advanced system settings, and then environment variables.
06:45 And then under system variables, you want to scroll down to your path And then
06:50 click edit. And essentially this is just a series of
06:54 paths to things that you can easily then use on the command line, so we need to
06:59 add some paths too this. So the first thing I'm going to do is to
07:05 go to that OpenSSL directory on the desktop, we want to add a path to the bin
07:10 directory, and I'm just going to copy that path here from the address bar And
07:15 after that last semicolon, paste that in, and then add a semicolon.
07:25 Now the next thing that I want to do is to add a path to the Android tools.
07:30 So I'm going to go to the desktop, Android SDK, inside of here, inside of
07:34 the SDK folder, and then I want a path to platform tools.
07:39 And this will give me access to things like ADB.
07:44 So I'm going to come here, and paste that in, add another semicolon.
07:49 Now the last thing we need to add a path to is our JDK directory, and this is,
07:53 what you installed earlier. So where ever that got installed to, for
07:59 me it's in Program files, it's going to be Java JDK and then bin and again we
08:05 want to copy this path. Now you notice here that there is a space
08:12 in this path and this will give us problems inside of this environment
08:16 variable. But what we can do is a little shorthand.
08:21 We just reduce program space files to. A shorter version like that and then a
08:26 tildae and and one. It will essentially make Windows figure
08:30 out for itself that this is program files.
08:33 So that's just a shortcut for doing things like this in the path.
08:37 So I'm going to click OK, OK, OK again We can close this and close that.
08:45 So I'm going to open up the command line and what I'm going to do is to just use
08:49 ADB devices to see if we can reach that, and if that work properly, we can do open
08:54 as a cell, and we can see it starts that program running.
09:00 I'll just type quit to get out of that. And then lastly, the JDK, we're going to
09:06 be using a tool a key tool, so let's just type that in.
09:10 And we can see it actually found that tool, because of that path.
09:16 So now it's going to be really easy for us to use all of these various tools,
09:20 from the command line. Okay, so let's go back into Eclipse.
09:25 What we need to do next is to make sure that we have the correct versions of the
09:29 Android operating system downloaded, for doing Kindle development.
09:35 So I'm going to go to the SDK manager, and this will allow us to see what we
09:39 have installed and also download other platforms.
09:45 So by default, it's going to download the latest version of the Android operating
09:49 system, which is 4.2. So we have that version.
09:52 But remember that, the new Kindle devices run on Ice Cream Sandwich, which is
09:59 actually Android 4.0.3 API level 15. So if we come inside of here, one of the
10:06 things you might notice, if you've done Android development before, is that there
10:11 used to be downloads in here for the Kindle devices, those components for
10:15 Kindle devices. Those are no longer actually in here by
10:20 default. So we're going to have to actually add
10:22 them ourselves. So if we go to Tools, Manage Add On
10:26 Sites, and then go to User Defined Sites, we can add in our own.
10:33 And basically, this is a URL that I got off of the Amazon developer site,
10:44 Kindle-sdk.s3.amazonaws.com/addon.XML. And this is essentially going to go out
10:56 and get all of those definitions so that we can actually download those
11:00 components. I'll click close.
11:04 And now you can see immediately that it's added those components here and it will
11:08 allow me to download them. So now, usually I would download
11:13 everything, the samples, the documentation, all of that stuff.
11:17 Just to make things quicker, I'm just going to get the SDK itself.
11:21 Then we need the ARM system image, because that's the architecture that the
11:25 Kindle devices run on, and then I'm going to get all of these Kinder Fire
11:29 components for each of the devices. Now if you wanted to do development for
11:37 the first generation Kindle Fire, you could download the Gingerbread STK, but
11:42 again, we're not going to be dealing with that in this course.
11:47 But come to the very bottom, under Extras, you'll see the Kindle Fire device
11:51 definitions and this is going to allow us to easily to make Emulators for the
11:54 different devices, so I definitely want that.
11:59 And I want the Kindle Fire USB driver which is going to allow me to easily
12:04 connect to my actual device using USP so I will check that off and now I am going
12:09 to click Install 8 Packages and we can just go ahead next(UNKNOWN) all of the
12:14 license stuff here And click install. So this is going to take a little while
12:25 to download, but as soon as it's finished we will continue on.
12:31 So now all of those packages have finished downloading.
12:35 Now what I'm going to do is just close the SDK manager and if you see this
12:39 little error about DBMS, that's nothing, don't worry about that.
12:43 I'm going to to launch up the Android Virtual Device Manager and this is
12:47 obviously the thing we use to create emulators and click on device definitions
12:52 and inside of here you should see those Kindle Fire device definitions.
13:00 And that will let you know that you've downloaded them correctly.
13:05 So you now have the correct SDK's. You have the actual kindle components you
13:09 need as well as the device definitions. In the next movie, we 're actually going
13:15 to be creating our kindle fire emulator.
13:18
Collapse this transcript
Installing the Amazon Mobile App SDK
00:00 So I wanted to quickly mention an additional tool, that's currently in
00:04 Beta, and it's the Amazon Mobile App SDK Eclipse plugin.
00:09 And this is just a simple plugin that makes it easier for you to import the
00:13 various libraries, which are just JAR files.
00:17 like in app purchasing, and Game Circle, and it will update your manifest file for
00:22 you. Some nice stuff in there.
00:24 I'm not actually going to be using this plugin during the course, because again
00:28 it's still beta, and I prefer to do things like importing libraries, and
00:31 updating the manifest file myself, but I'm going to show you how to install it.
00:37 So, going to go into Eclipse, and then your going to go to Help, Install New
00:42 Software. And then basically we need to add a new
00:47 download site, and that's developer.amazon.com/eclipse.
00:54 So here we can see the Amazon mobile app SDK, and then here is the plug-in.
01:01 So I'll click Next, and now it's basically reviewing.
01:06 Yes I want to install this, I'll click Next.
01:09 Yes, I accept the terms, and I'll click Finish.
01:13 And you can see I got a pop-up here, that's basically asking me if I trust the
01:19 Amazon certificate. I'm going to say yes, I do.
01:24 And, now it's going to tell me that it's for the best to actually restart Eclipse
01:29 right now, so I'll say yes. We'll let it launch up.
01:34 Alright, so here we are. Now, let's say I just have a blank
01:38 project here. If I right click and go to properties,
01:42 and we can see we have an entry for Amazon Mobile App SDK.
01:46 And, again, this is going to allow me to actually select which Kindle library I
01:51 actually want to use, maybe in-app purchasing.
01:55 And then I'm going to be able to import that into my project, so if I click OK,
01:59 it's actually going to be in there. So, we can see, under Amazon Libs, here
02:05 we have the actual jar file itself. So that's a nice feature to have.
02:11 And if we go into the manifest, we can see it's also entered a necessary
02:16 broadcast receiver for us, for the in-app purchasing api.
02:22 So definitely a nice plugin to get. Again, it's still in beta, but you should
02:27 definitely check it out.
02:30
Collapse this transcript
Creating a Kindle virtual device
00:00 So, now that we have our development environment set up, let's now create an
00:04 actual Kindle Fire emulator. So, let's go to the virtual device
00:10 manager and open that up. And then, we can go to Device
00:13 Definitions. And remember, we downloaded the Kindle
00:17 Fire device definitions when we downloaded the SDKs.
00:22 Now, in this course, I'm going to be targeting a Kindle Fire HD 7-inch, just
00:25 because that's the actual device that I own.
00:29 But later on, I'm going to be showing you how to adapt the application to the
00:33 different screen sizes and DPIs of the other Kindle devices.
00:38 So, with that selected, I'm going to click Create AVD.
00:42 And here, we can actually customize it, so the first thing I'm going to do is to
00:45 actually rename it. So, I'll say Kindle HD_7.
00:51 The device should automatically be pre-filled with the correct device.
00:57 Now, the target, this is a really important thing, by default, it set to
01:01 target Android 4.0.3. If we leave it like this, then we're
01:06 going to see just the regular Android Ice Cream Sandwich UI.
01:09 We're not actually going to see the Kindle UI, so that's not going to work.
01:14 So, we're going to change the target to Kindle Fire HD 7-inch.
01:19 Now, these next two options, they basically provide controls outside of the
01:24 emulator. If you want to keep those, you can.
01:27 I like to turn those off, just so I can see the emulator window.
01:30 Now, were not going to be using the camera in this application.
01:34 For Memory Options under RAM, we want to keep that at the default.
01:38 For VM Heap, we want to change that to 256, and that's based on recommendations
01:43 from Amazon. For Internal Storage, let's bump it up to
01:48 1024 megabytes. Now, for an SD card, that can be one of
01:53 the things that really slows down the start up of your emulators.
01:58 So, you could choose not to even include one, but we're actually going to need it
02:02 later on in the course. So, I'm going to put the smallest size
02:07 possible which is 9. Now, under Emulation Options, you can
02:12 choose to actually Emulate Hardware Acceleration.
02:16 And it actually uses the graphics card on your computer.
02:21 Now, this is definitely something you should check off because it just make
02:25 things run a lot faster in the emulator. it makes it more, like a real world
02:30 emulation. This won't actually work with every
02:34 single computer and graphics card combination out there.
02:37 So, once you boot up the emulator, if you start having issues or crashing, you can
02:42 come and actually uncheck this. The only downside of using this is you
02:47 can't use the Snapshot feature. But we're going to use the Host GPU.
02:51 Click OK. And now, you can see that we have that
02:54 virtual device created. I'm going to click on it and then click
02:59 Start. Now, for you, this is not going to be an
03:02 issue, but for me, since I'm recording this movie at a very small resolution,
03:05 I'm going to need to scale it down, so I can actually fit it on the screen.
03:11 So, I'm going to scale it to 9 inches. But again, you shouldn't have to do that
03:16 on your systems. And we're going to click Launch.
03:20 And now, it's going to start up the Kindle HD 7-inch.
03:25 Now, this start up process can actually take quite a while, especially the first
03:29 time you've started it up. So, as soon as we're done loading, we'll
03:34 continue. Okay, so the emulator has loaded up.
03:37 And you'll notice, if you actually have a Kindle device, that it doesn't look
03:41 exactly the same, things like the carousel, are not present here on the
03:45 emulator. But for testing your applications, they
03:49 will emulate perfectly, how it will run on the device.
03:53 So, it works just how you would expect on the device.
03:56 I can pull down on the notifications to see those.
04:00 Now, an important point is that when we get to the chapters on using GameCircle
04:04 and Amazon Maps, you need to have this emulator actually registered with an
04:08 Amazon account. And it should be the Amazon account that
04:14 you use to create your developer registration when you register to become
04:19 an Amazon developer. Or else, those APIs are not going to work
04:26 here in the emulator. So to do that, I'm going to swipe down
04:30 notifications, go to More, My Account, and you'll see here, this Kindle is not
04:35 registered. Please sign in with your Amazon account.
04:40 So, I'm going to register this. And it just asks for your e-mail and
04:47 password. And again, this should be the same
04:49 account that you use to become a registered Amazon developer.
04:54 Now, one of the bad things about this particular emulator is you can't use your
04:58 computer keyboard. You're going to actually have to save
05:02 here and type in your e-mail address and password.
05:06 So, again, do that. Click Register, and then this emulator
05:10 will then be tied to your Amazon account, and those APIs will work.
05:15 So, I'm going to just close this really quick, because I did want to point out,
05:18 once you have registered that Kindle device to your Amazon account.
05:22 And then, say, you want to launch it up again, you want to make sure you don't
05:26 check off Wipe User Data. because if you do, then that Emulator
05:30 will basically be fresh, brand new and you're going to have to register again.
05:35 So, when you're launching the emulator, don't check off wipe user data.
05:40 I mean, if we need to wipe some user data from our application, well, we can just
05:45 do it on an application basis inside of the emulator.
05:50
Collapse this transcript
What you will be building
00:00 So I quickly wanted to show you the application that we're acutally going to
00:03 be building throughout this course. Now I've provided a lot of the
00:07 application already done for you because the goal of this course is to learn how
00:12 to adapt it to Kindle devices, and to use the Amazon API's.
00:19 So it's a game called Spin It. A really simple game.
00:22 You just spin a wheel, kind of like Wheel of Fortune.
00:25 If you land on a money amount, it gets added to your score.
00:28 If you land on the lose it all segment, then essentially your game is over.
00:34 So let me launch here, and its going to come to the main menu screen.
00:38 And you can see these little overlays that's actually the game circle API's and
00:43 UI and specifically here this is the whispersync creature is slightly mean no
00:47 that I have two different saves for this game.
00:52 One on this device and one in the cloud. So I'm going to sync to the one in the
00:57 cloud. And then you're going to see it's
01:01 syincing. And another part of the game circle API
01:05 that we can do, I can just click View High Scores.
01:09 And this is actually going to launch up The Game Circle UI, and it's going to
01:13 show me the high scores global leaderboards for this game.
01:19 And we also are going to create an achievement, which I've already unlocked,
01:22 it's when you reach $1,000. So again, this is a nice UI presenting
01:27 you with all of your game information. So let's go ahead and click Play game.
01:33 And again, you can see it's actually downloaded that state from the cloud, so
01:37 I already have 300 dollars. Now for in-app purchases, I can click Add
01:43 Money and it's going to allow me to buy a thousand dollars of in game currency for
01:49 99 cents. So I'm going to click Purchase.
01:53 And then let me get rid of that dialog. And you can see now my dollar amount has
01:58 gone up by a thousand. Obviously I can spin the wheel to
02:02 actually play the game. And you can see my dollar amount has been
02:07 updated. So now another in app purchase we can do
02:10 is to change the style of the wheel. We can buy new wheel styles.
02:15 So I'm going to click Change the Wheel, and that's going to bring me to this
02:18 screen, which allows me to choose from these different styles.
02:23 Now you'll notice here, these two have padlocks, that are actually locked, but I
02:28 can unlock them for $0.99. So I'm going to do the Camouflage wheel,
02:32 I'm going to click Buy. And again, it's going to launch up the
02:35 in-app purchase. And, this is something that once I
02:38 purchase it I never have to purchase again.
02:41 So I'll click Purchase, and it's Thank you for purchasing, or Buying the camo
02:46 wheel, I'll dismiss that. And you'll notice now the padlock has
02:51 gone away, I can click on it, and now I have access, to that wheel style.
02:56 And I can continue playing the game this way.
03:00 And you can see there, I actually lost the game.
03:03 so now it brought me to to the game over screen.
03:07 now what I can do from here is to submit my score to the global leaderboards, so
03:12 let me do that. And it's submitting it, and I now have
03:17 the new high score. And again, you can see that game circle
03:21 UI popping out there. So that is in essence what we're going to
03:26 be building, and it's going to be integrating both the in-app purchasing
03:30 and the game circle API's, and we'll be using a separate app for the maps API.
03:37
Collapse this transcript
Creating the app on the developer portal
00:00 So, the last thing that we're going to do before actually getting into the code is
00:05 to create our application here on the Developer Portal.
00:10 So, I've signed in, obviously. And then, I clicked on My Apps.
00:15 And you can see, as of right now, we don't have any apps yet.
00:18 So, click on Add a New App. And now, we're going to go through a
00:22 series of tabs, where we describe and give information about it.
00:27 So, remember, the game we are creating is called Spin It.
00:32 Now, the apps SKU is optional, but I'm just going to put, spin_it.
00:37 Form factor we can choose phone and tablet, phone or tablet.
00:43 Obviously, we're targeting Kindle devices.
00:45 Those are Tablets. Under Category, I'm going to choose
00:48 Games. And under Games, I can choose a
00:52 particular genre, and we'll call ours Casino.
00:55 Now, for the support information, you can choose to use your default information.
01:02 Remember, I skipped that when I registered, so your stuff should show up
01:06 here. I'll click Save.
01:09 And you can see, it gives a little check box saying that that tab is completed.
01:15 So now, I'm going to go to Availability and Pricing.
01:19 Where would I like this app to be available?
01:22 Well, I want it to be in all countries where Amazon sells apps.
01:27 And then, it asks me, are you charging for this app?
01:30 And in this case, no. This is a free app.
01:33 I'm going to be monetizing it based on the in-app purchases.
01:36 So, I'm going to leave it as no. Has this app already been released on any
01:41 other mobile platforms? No, it hasn't, but if yours has, then
01:45 you're going to want to put in that information.
01:48 When would you like this app to be available?
01:51 If you leave it blank, it'll be the soonest possible after they approve your
01:54 application. When would you like this app to be
01:57 discontinued for sale? If you wanted to remove it at a certain
02:01 date. This free app of the day eligibility,
02:03 what this is, if you opt into this, is if Amazon looks at your app and says, wow,
02:07 this is a cool app, they might use it as their official free app of the day.
02:13 And that way, you can get a lot of exposure for your application.
02:17 So, I'm just going to leave it checked as Yes.
02:20 And then, I'm going to click Save. Okay, so now let's go to Description.
02:24 Now, I'm going to be really short with these, but obviously in a a real app,
02:28 you're going to want to have really nice Descriptions to give them information
02:32 that might make them want to purchase your application.
02:37 I'll just say, this is a game called Spin It.
02:43 And I'll just copy that. Put that also in for the long
02:49 description. Now, here, these product features
02:52 bullets. When your app appears in the App Store on
02:55 the Amazon website, these actually will be shown.
03:00 So, for mine, it could be, win money, fun and addictive.
03:08 I'll just say, and more. You get the idea.
03:16 So, keywords, these will help your application to be discovered.
03:20 Obviously, it works the same as HTML, where you're putting keywords will help
03:24 with search engines. So, I can just put in game, casino, win.
03:33 Again, all of this is just filler information.
03:35 for your actual applications that you're going to be building, you want to put
03:38 some real time into this. You can also add a different translation
03:42 for these, as well, but we're not going to do that, so we're going to click
03:45 Save. And now, we want to go to the Images &
03:51 Multimedia tab. So, one of the things that's interesting
03:56 about Amazon Kindle Development is the way in which icons work.
04:01 So, the icon for your application that's actually shown on the user's device in
04:05 the App Drawer, and also in the carousel, that's based on images that you're
04:10 going to upload here. Not the actual application icon that's in
04:16 your Android project. So, just be aware of that.
04:20 So, it asks for a Small Icon, Large Icon, Screenshots of your application.
04:25 A promotional image, and again this is if Amazon thinks that your application is
04:29 really cool and they want to promote it, they'll use this image.
04:33 And you can also upload a video, you've probably seen that on other app stores
04:37 where you can have a demo of your application.
04:40 So, if you look in the exercise files, I've actually provided for you already.
04:45 So, if you go into the Assets folder, Artwork.
04:48 In this directory here, are the artwork that we're actually going to be uploading
04:53 here. So, here's the large icon, here's the
04:56 promo image. I have four different screenshots of the
05:00 application. And then, there's the small icon.
05:03 So, let's go ahead and upload these. So, we'll come in, this is the small
05:10 icon, you can see it uploaded. Now, we'll upload the large icon.
05:18 And we'll add our screenshots. I upload another one.
05:26 I'm just going to upload three here, to save time.
05:33 But you can upload up to 10 different screenshots.
05:40 Okay, so we have those. Now, the promotional image, promo.png,
05:46 and that's what that looks like, are you feeling lucky?
05:52 And we're not going to do a video. So, here are our graphics now, uploaded
05:57 to the portal, and I'm going to click Save.
05:59 Now, I can go to content rating. So, if your application has any of these
06:07 nefarious activities in them, you're going to want to specify that here.
06:13 So no drug references in our game, no violence, intolerance, nudity, crude
06:18 humor, realistic violence, sexually suggestive content, no.
06:23 Gambling, I'm not going to check off , because it's not real gambling, it's just
06:27 in-game currency. I'm going to click Save.
06:30 And then, here, we have our content rating.
06:33 Now, the binary files tab, that's obviously the one that we're going to use
06:38 at the end of this course. When we finished our application, this is
06:43 where we upload our APK file. So, this is the only one, we're not
06:47 going to actually fill out right now. But now, if we click on my apps, we can
06:52 see, we have an application here called Spin It.
06:56 If I click on that, I can now start adding in-app purchase items, I can
07:00 connect it to GameCircle, to Maps. And we are now set up to start doing
07:06 Kindle Development.
07:09
Collapse this transcript
2. Integrating In-App Purchasing
Understanding the In-App Purchasing API
00:00 So the first Amazon-specific API we're going to look at is the In-App purchasing
00:04 API. And this is a really important one,
00:07 because it can be a great way to monetize your applications or maybe your
00:11 application is free, but as the user uses your application, they can buy things
00:16 directly inside of your app. Now, this is a graphic that I got off the
00:22 developer portal. But, it does a good job of showing the
00:25 workflow of how to develop for In-App purchasing.
00:29 So here, we can see, this is our actual application running on somebody's device,
00:34 and that communicates with the Amazon client, which handles the In-App
00:38 purchasing. Now, this could be the real Amazon client
00:43 running out in production or it could be a local Amazon client that we're actually
00:47 going to run on the emulator to allow us to test these things locally.
00:54 But if we start here at step 1, we first, in our Manifest, need to register for
00:58 broadcast receiver so that the Amazon client can actually send us messages.
01:05 The next step is creating a Purchasing Observer and this class is a class that
01:10 we're going to create and it basically sits there and waits for call backs from
01:14 the Amazon client. And then we can react to whatever the
01:19 Amazon client actually tells us. Step 3 is we register that Purchasing
01:24 Observer. Then, step 4.
01:27 Anywhere in our application, we initiate a new In-App purchase.
01:32 The response comes back from the Amazon client to our observer.
01:37 And then, if it was successful, then we give them what they wanted to buy.
01:41 If it wasn't, we can handle that in our application.
01:45 Now, there are some optional steps. First of all, you can persist the
01:49 receipt, so when the user actually buys something, the Amazon client will send
01:53 you a receipt which you can then store to share preferences, to SQL like database.
01:59 Any number of options. The other optional thing is this Receipt
02:03 Verification Service, but I'll talk about that in a minute.
02:08 So there are three different types of In-App items that you can create for your
02:13 application. The first type are Consumables and these
02:18 are content that don't require access right.
02:22 You're not going to be checking every time you launch your application, does
02:25 the user has the right to this particular item?
02:29 And here is an important part, they can be purchased multiple times.
02:32 So in our game, when we're clicking to buy more in-game currency, obviously, the
02:37 user can do that 100 times if they want to.
02:41 Another important thing is it's only available on the device in which it was
02:45 purchased from. So, if they play on one device, buy all
02:49 these consumables, go get a new Kindle, it's not going to carry over to that new
02:53 Kindle. And some good examples are, in a game
02:57 scenario, buying extra lives or more in-game currency, which we're actually
03:02 going to be doing in our example. The next type are Entitlements.
03:09 Now, this is content that does require access rights to use.
03:13 Essentially, you're going to be able to check when your application launches,
03:17 does the user have access rights to this in app feature or item?
03:22 Now, these are things that can be purchased only once by a customer.
03:27 And, it's also available on all compatible devices registered to the
03:31 customers account. So, for an entitlement, they can move
03:35 from one device to another and still have access to it.
03:39 Good examples of entitlements are unlocking features.
03:43 Maybe your application is free, but there's some enhanced functionality, they
03:48 can unlock or buying new level packs for games.
03:51 The last type are, Subscriptions. Now, this is content that requires access
03:57 rights, but it's bound by a period of time, like when you subscribe to a
04:00 magazine you get a one year subscription. These will auto-renew.
04:06 And, of course, they're available on all eligible devices that the customer uses.
04:12 Now, we're not going to be implementing subscriptions in our application, this is
04:16 mostly used by digital magazines and publications.
04:20 But if you go to the developer portal, there's an example of how to set this up.
04:25 It's very, very similar to the other two. So now, I just want to quickly talk about
04:29 that Receipt Verification Service. We're not going to be implementing that
04:34 in this course, but I wanted to go over what exactly it does.
04:38 So let's say that a user in the application has bought something, and
04:42 let's take the example of a game, for instance.
04:47 So you have a game running here, and let's say you can unlock a certain level.
04:52 Well, you're going to do the In-App purchase, it will return this receipt to
04:57 you. What you can then do is you can, from
05:00 your application, send that receipt to your own server.
05:04 So this is just some server that you have.
05:07 And then, you can communicate with the Receipt Verification Service through this
05:11 JSON REST API just to validate that it's actually valid.
05:16 Now, the reason that you would want to do this is, let's say you have a game that's
05:20 running on the Kindle device and also you have a web version.
05:25 While this will allow you to validate these receipts outside of the device.
05:32 So were not going to be dealing with this in our application, but it is important
05:35 to know about nonetheless. So that's an overview of In-App
05:39 purchasing. Now let's actually get started
05:42 implementing it.
05:43
Collapse this transcript
Setting up your environment
00:00 Okay, so now we're ready to set up our development environment to do in-app
00:04 purchases, but at this point we haven't even loaded in the project that I
00:08 provided for you. So let's go ahead and do that.
00:12 So I'm going to Right click > Import, then under Android, existing code into
00:17 workspace, I'm going to browse for the root directory which is then Exercise
00:21 Files and then it's that Spin It folder that you want to select right there.
00:28 Click Open and then you can click Finish. Okay.
00:33 So here's the code. Now I did want to quickly go over this
00:37 with you, so if you watched the movie earlier where I went over the full
00:41 application that we're going to be building, let me just show you real quick
00:45 in the emulator. So we have an activity here which is our
00:50 main menu screen. The View high scores, obviously we
00:53 haven't implemented that yet. I'm going full screen for this game.
00:57 If I click Play game, it launches the game activity, and from here I can spin
01:02 the wheel. Accumulate money, I can click on change
01:07 the wheel. And here, I can either choose from the
01:11 default or I can unlock one of these other wheel styles.
01:15 And this will of course be using in-app purchases.
01:18 But I will jist goback to default. This add money button which will also be
01:23 tight in a purchasing. Lets go back to our project and lets just
01:28 look at some of the source, so one of the things that I have done is to override
01:32 the main application class. And I've just called it App.
01:38 And we're going to be using this in different places in this course,
01:41 particularly around Game Circle. But this allows us to have a main class
01:46 for our application where we can put certain things that we only want to
01:50 create one of. Like for instance here, there's only one
01:55 thing in here right now a public static string called tag equal to a string of
01:59 spin it, and this is so when we log to Log Cat we're always using the same tag.
02:05 So again we're going to be using this extended application class.
02:09 To implement some things later on. So the first activity you're brought to
02:14 is that Main Menus screen. Really simple, the Play Game button,
02:19 simply launches an intent, and you're starting that game activity, to begin
02:23 playing the game. And the View High Scores method here,
02:28 hasn't been implemented. We'll do that once we get to game circle.
02:33 Now it is important to point out how I'm doing button click event handlers.
02:38 So I'm actually defining them inside of the XML, so if I actually open up the
02:44 layout file, it's called activity_main and if I go to the graphical layout.
02:53 One of the things is make sure you change it to the actual device, that you're
02:57 targeting. So we're targeting Portrait Kindle Fire
03:01 HD 7 inch. So you can see these two buttons If I
03:04 select it, I'm actually setting the on click Property down here equal to a
03:09 method that's going to exist in the Java class tied to this activity.
03:16 That's just, in my opinion, a much cleaner way than having to set it all up
03:20 inside of the Java class. So just be aware, that's how I'm doing
03:25 button click handlers. So then if we go to the game class, this
03:30 is where the main game is implemented. First thing I'm doing in on create, is
03:35 creating a new instance of the shared preferences class.
03:40 And this gets the default shared preferences for this application And it
03:44 just uses the application context here. There's a few different ways you can get
03:49 this. This is just the way that I do it.
03:52 We're going to be using these shared preferences to save things like the score
03:56 so they persist between sessions. Now here on Line 38, I'm actually setting
04:02 an integer variable equal to the score that I'm pulling out of the shared
04:07 preferences. So let's say the user, you know, was
04:12 playing, had a really high score, they left the app, and then they came back a
04:16 couple of days later, well their score is still going to be reflected.
04:21 And then in line 39 I'm simply just setting that text field, which displays
04:25 how much money the user has. Now if we come down to line 48 the
04:31 OnPause. Basically its detecting is this activity
04:35 finishing if it is then let's actually put the current score in to shared
04:39 preferences so the user doesn't lose it. On line 57, I'm essentially doing the
04:46 same exact thing in the On Stop method. I'm going to scroll down a little bit
04:52 here to line 75. Which is the spin the wheel event
04:56 handler. And this when you click on the spin the
04:59 wheel button. And I'm not going to go into all the
05:01 details here. But essentially, I'm picking a random
05:04 rotation. Then I'm using an animator set to rotate
05:08 it to that random rotation, making it happen over two seconds.
05:13 And, inside of the complete event, which is called on animation end on line 87,
05:19 I'm basically calling a method called calculateResult.
05:26 And on line 95. In this method, essentially what I'm
05:30 doing is getting the wheel's current rotation.
05:33 Here I'm modding it with 360, and then I'm flooring the value of angle divided
05:39 by 36, because there's ten segments on that wheel.
05:45 And what this will provide me with is an integer for which real piece it landed on
05:50 and then I look up what the value is for that piece.
05:56 And lets go back up to the top. Here I have an integer array called
06:01 amounts with a series of values. And these correspond to the locations on
06:06 the wheel. Now the negative 1 values are the three
06:09 wheel pieces where it says lose it all and essentially the game is over.
06:16 So that's how the score is calculated. Now, if that amount that comes back is
06:21 negative 1. That essentially means you've lost it,
06:24 and the game is over. So I create a new intent.
06:28 I put the score that they had reached before the game over into that intent.
06:34 Then I actually write into shared preferences a score, zero, and then we
06:39 start that activity, the GameOver activity.
06:43 If it wasn't negative one, then we simply add the amount to the score, and then we
06:48 also set that text field again. On line 112, we have to upgrade wheel
06:53 button click event handler And here we're simply starting the change wheel
06:59 activity, but we're starting it for a result.
07:04 So that activity is going to send us back a result, to tell us which wheel to show.
07:10 Now I have put a little back door into this game, because sometimes, let's say
07:14 you're really lucky, and you're testing things, You just can't end the game
07:18 because you keep winning so I have put a click handler on the actual wheel itself
07:22 so if you tap the wheel it essentially ends the game the same thing as if you
07:26 had landed on lose it all. And then on line 125 here's the click
07:34 handler for the add money button again, which we'll be filling in in this
07:39 chapter. So that's game.java.
07:43 We go to change real dot job. This is essentially the activity where
07:47 you can change or buy a new real style. So nothing too crazy going on here in
07:53 OnCreate, if I come down here are the individual click handlers for each of the
07:58 wheels. So on line 33 we have the camoClick.
08:03 If you click on it right now, it's just going to allow you to actually choose it
08:07 because we haven't set up that In App purchase yet.
08:11 On line 40, same thing with the goldClick event handler, and then 47.
08:16 This is the normal wheel style. And then we have the event handlers for
08:22 buyCamo and buyGold on lines 54 and 58. And these obviously we're going to be
08:27 filling these in, once we actually initiate the in-app purchase API.
08:33 So that's an overview of the code that I provided.
08:36 Now how do we set this up to be able to actually do In-App purchases?
08:40 Well we need to include the in-app purchase API that was in the Amazon SDK.
08:45 So I'm going to Right click on the Project > Properties > Java build path,
08:51 and then under Libraries, I'm going to click Add External JARs.
08:57 Now from here I'm going to go to the Amazon SDK > In-App Purchasing > lib >
09:04 JAR file and click Open. And you should now see it here.
09:11 Now an important part of this is to go to the Order and Export tab, and make sure
09:15 it's checked off. That way, this library will actually be
09:19 bundled with your application when you export it, which is important.
09:24 Now another thing we want to do is to add the Java Docs.
09:28 For this API, which is going to make development a lot easier.
09:31 So to do that, I can twirl it down, click on Java doc location > Edit> Browse.
09:40 And now you want to go to the Documentation folder, click on API
09:44 reference and choose that folder. And you click Validate if you want, and
09:50 it says location is likely valid. And I am going to click OK > OK and now
09:56 we can click OK again. So with this point you have now set up
10:02 the project to begin working with the In-App purchases API which we'll do in
10:06 the next movie.
10:09
Collapse this transcript
Adding items to the developer portal
00:00 So the way in which you create your in-app items for your game is here on the
00:05 Developer Portal. Now it's important to note, with in-app
00:10 purchasing, you don't need to actually create these on the Developer Portal, in
00:14 order to test them locally, on your device or the Emulator, because we have
00:18 that STK Tester Application that we can use.
00:24 But I figure let's just add these items here to the portal now, because we're
00:27 going to want to use the same information when we're testing locally.
00:32 From here on the My App's page, and I'm going to click on the Spin It
00:36 application. And here you can see we have a link to
00:40 in-app items. Now here it actually goes over the three
00:43 types of items you can create, that I went over in the first movie in this
00:47 chapter. The first thing we're going to add is a
00:52 consumable, and this is when the user clicks that Buy Money button and
00:56 essentially, they can buy $1,000 of in-game currency.
01:01 So this is obviously something that they can do multiple times.
01:05 So let's click Add a consumable, and it's going to ask for a title.
01:10 And I'm just going to say buy more money. And now the SKU, and this is a string
01:17 that you're going to need to reference from your code, and I'm just going to
01:22 call it money. The type is consumable.
01:27 Now this option is important because In my case if the user successfully
01:31 purchases it, I don't need to go out and download something.
01:36 I can just automatically update their score you know, increment it by 1,000.
01:41 If your In App item requires you to then download something, you need to choose,
01:45 I'll deliver the required assets. But in our case no additional file is
01:50 required. I'll click save.
01:53 And now go to availability and pricing. Are you charging for this consumable?
01:58 You bet I am. So I'm going to click this.
02:01 And it's going to ask for your base price.
02:03 And you want to choose what currency you want that base price to be in.
02:08 I wanted United States dollar. And I'm going to make it 99 cents.
02:12 And what the next section is. Essentially, it will calculate what that
02:17 is going to be in all of these other currencies.
02:21 When would you like this item to be available.
02:23 Well, as soon as possible so just leave it blank.
02:26 And click save. Now we can go to description.
02:30 And again I'm just going to put placeholder stuff here.
02:34 Buy $1,000 more Currency, keywords buy, money.
02:46 And again you can add a translation if you want.
02:48 Click Save. And now go to Images.
02:51 So this is where you provide images that will actually be displayed in certain
02:56 places. The Kindle UI for in app purchases which
03:00 pops up will display your icon, and again these assets will be used in various
03:04 places. So again, if you look in the exercise
03:09 files, if you go assets, artwork and then in-app purchase, I provided the image
03:14 files for you so that's if you buy the camouflage wheel style, that's the large
03:20 icon, small icon Gold, icon, large, small, money icon is simply buy $1,000,
03:25 so we can plug these in now. So I'm going to upload a small icon, go
03:34 to in App purchase, and this is money icon small.
03:39 Let's upload the big one Large, and you need to include a Screenshot for this.
03:46 So we're just going to use some of the existing Screenshots that we have here.
03:51 I'll do that one because it actually shows an In-App purchase.
03:55 Again, just doing this kind of as place holders to show you the process.
03:59 Now, the purchase action screenshot should show the user what happens
04:03 directly after the purchase is successful.
04:06 Well, for that, I'll just show this screen and I'll load that in.
04:11 Okay, so with that done, I can click Save, and now at this point, my in-app
04:16 purchase item is complete. Now I am not going to submit it yet.
04:21 I am going to go back to Inapp items. You can see, here is my first one.
04:25 Now we're going to create those other two which is going to be the camouflage wheel
04:30 and the gold wheel. Now remember these are going to be
04:34 entitlements because the user only buys them once and once they do.
04:38 They have access to it as much as they want.
04:40 So I'll click that, for title, buy camo wheel.
04:46 The SKU is just going to be camo, no additional file is required.
04:51 Click Save. Availability and pricing, this is all
04:57 going to be pretty much the same, US dollars, $0.99, click save, come to
05:03 description, again buy camo wheel Buy the camo wheel.
05:12 Not much more information. Again just placeholder stuff so you can
05:16 see the process. Click save, now let's load in those
05:20 images. So for small icon we want to go to the
05:24 camo small. For the large, we want camo large.
05:32 And for the screen shots, I'm just going to provide, let's see I have a
05:36 screen shot of the screen where you can actually buy these wheels, so I'll use
05:40 that, and I'm just going to use the same screenshot again, for this last one, and
05:45 click Save. Go back to in-app items, so we now have
05:51 two, we have a consumable and entitlement.
05:55 Let's add that last entitlement, Title by Gold Wheel, the skew is just going to be
06:02 gold. No additional file.
06:07 We'll also make this 99 cents even though it's made out of gold.
06:12 So I'll chose United States dollar. Click save, description, again just place
06:19 holder. By the gold wheel.
06:23 And this stuff is what's actually going to be displayed in the UI that pops
06:27 up for in at purchases. So, you definitely going to want to be
06:31 descriptive here. And lastly, let's add the images that go
06:36 along with the gold wheel. So we want gold.
06:41 icon small. Gold icon large.
06:46 And now we'll use those same screenshots of the screen where you can actually
06:52 purchase this wheel. Let it load in, and I'll upload that same
06:58 one again. And that's it, so now I can click Save.
07:02 Go back to in-app items, and here are my three in-app items defined.
07:09 Now what we just did, again, is not required for you to test in app purchases
07:13 locally, but this information is going to need to be the same when you actually
07:17 publish your application. So, for things like the SKU.
07:23 In all of these types of things, it's a good idea to add the items to the Portal,
07:28 and then use that information when you test locally.
07:33
Collapse this transcript
Setting up the Purchasing Observer
00:00 Okay, so now we're ready to begin the code implementation for our In-App
00:05 purchases. So the first thing we have to do is to
00:09 register that broadcast receiver so the Amazon client can actually notify us of
00:14 messages. So I'm going to go into the Manifest
00:18 file. And just go to the XML and come under
00:22 where that last activity was created. So we're going to create a new receiver.
00:32 Now the name of this receiver, we need to give the full package path to the
00:36 response receiver class which is in the AmazonSDK.
00:42 Now I have that path copied to my clipboard, but it's just
00:46 com.amazon.inapp.purchasing. And then the class is response receiver.
00:52 Okay, so inside of here, we need to create an intent-filter.
00:59 And then inside of that, we need to create an action.
01:05 Okay, for our action, we need to give it a name, and this name, again, is going to
01:14 be that full package path .Notify. Now, the next thing we need to add is the
01:25 actual permission. So, I'm going to say, android:permission=
01:32 and again we want that full path and now we want to go the permission class and we
01:40 want to say again uppercase notify, like that.
01:48 So this is now essentially implemented that broadcast receiver so we can be
01:53 notified by the Amazon client when it needs to respond to us.
01:59 Okay, so the next thing we need to do is to actually create our purchasing
02:04 observer class. So, one thing I wanted to show you before
02:08 we actually get started with that is, I want to jump back over to the browser and
02:12 this is on the developer portal, talking about the purchasing observer class.
02:20 Now you can implement the following call back methods and I just want to go over
02:23 them with you quickly. On SDK available, that's obviously when
02:27 you can start using the SDK, when it's ready.
02:30 IT will actually send you a Boolean telling you whether you are running in
02:34 Sandbox mode or not. Basically are you in production or are
02:37 you testing locally. And from here you can make other calls.
02:43 This on get user Id response, this handles the case of, let's say I have my
02:47 Kindle device, it's logged into my Amazon account playing the Spin It game it's
02:52 saving my, my score to shared preferences.
02:57 And then somebody else actually gets my device.
02:59 Logs themself in. There actually when their playing the
03:03 game, their going to be over riding my share of preferences.
03:06 So this will give you a unique user ID, so you could have different shared
03:11 preferences for each user. Now were not going to implement this in
03:16 this application to keep it simple. It's just going to be a single person
03:20 logged into their Kindle device. The next is on purchase updates response,
03:27 so let's take the case of, you know somebody is playing the game, and let's
03:31 say they've unlocked and bought the camouflage style wheel.
03:36 But then let's say, for whatever reason, you know, they get a new Kindle device,
03:40 or maybe they've uninstalled your application and reinstalled it.
03:44 Well then those shared preferences that say that they're entitled to that
03:48 camouflage wheel are gone. So what this does is it goes out and it
03:52 will return to you all of the things that this user is entitled to for your
03:57 application. And it will also tell you any items that
04:02 have been revoked, this is something that Amazon does very rarely, but in certain
04:06 cases they might revoke an in-app purchase.
04:10 So you can also handle that in this method.
04:12 The on-item data response, this essentially allows you to call out, to
04:16 the client and download all of the information about the In-App purchases
04:21 available for your application. So let's say you wanted to dynamically
04:27 build the UI and any time you added a new in-app item to the portal, it would
04:31 automatically update in your application. We're not going to be using this one,
04:37 because all of our stuff is baked into our app.
04:40 But again, if you want to get the information about of the in app items,
04:45 this is the callback that you would be using.
04:49 Now the most important on purchase response, this is when a user in your app
04:53 initiates a purchase to buy something The response from the Amazon client is
04:57 going to come back and call this on purchase response and from there you
05:01 handle the response that it sends back to you.
05:07 So we need to create this purchasing observer class.
05:11 So I am going to go into my source here, Right click > New > Class.
05:17 Now I am going to call mine. InAppObserver.
05:22 Now, the super class for this has to be base purchasing observer.
05:31 And again, that's a class provided by Amazon.
05:34 And I'm going to create the constructor here and click Finish.
05:42 Okay, so now we have our class created. So you can see that the constructor
05:48 actually expects a context, but what it's actually going to be getting is the
05:53 activity that initiated this purchase request.
05:58 And I'm just going to call this Caller, and I'm actually going to change this
06:04 type from context to Activity, and then to the super constructor call I'm just
06:11 going to pass in That caller argument, like that.
06:18 So the next thing we want to do is to actually create and get the default
06:25 shared preferences. Again, because we're going to be writing
06:30 to that from this class. So I'm going to create a field called
06:34 Prefs. I'm going to set it equal to
06:37 PreferencManager.getDefaultSharedPreferences. And then I'm going to use that caller
06:45 object that we passed in, to get the context.
06:52 I'm just going to say caller.getApplicationContext.
06:57 Like that. And now let me actually define this as a
07:02 field. And now we have our shared preferences
07:06 setup and ready to use. So now the next thing we want to do is to
07:11 actually implement some of those override methods that I just went over on the
07:14 Amazon side. So the first one is on SDK available.
07:23 So we generate that now again, inside of here and you can actually tell whether or
07:28 not you're running in Sandbox mode, which can be very useful.
07:36 The next one I want to overwrite is, is the on purchase update response.
07:44 And again inside of here what we're going to get is the response telling us
07:49 all of the items that this user already is entitled to so that I can unlock for
07:53 the user. Again if they've moved to another device
07:59 or somehow uninstalled my application. So the last overwrite we're going to
08:06 implement is On-purchase response. And again this is what's going to be
08:13 called when the user initiates to buy something.
08:16 The amazon client is going to send us back a response object, where you can
08:20 parse through that to find out, was it successful, if it was, let's write this
08:24 to the shared preferences and handle all of these different types of cases.
08:31 So that's the stub of our observer created right now.
08:36 Now in the next movie we're actually going to go through and fill in the
08:39 details of those callback methods.
08:43
Collapse this transcript
Implementing the response methods
00:00 Okay, so here we are in our purchasing observer, which I've called
00:03 InAppObserver. And we have these three callback, methods
00:07 that can be called from the Amazon client.
00:11 So now lets implement those. I did want to point out that Amazon
00:15 recommends like in, inside of any of these callbacks if you're doing something
00:20 that's kind of intensive. You should off load that task to a
00:25 different thread using an A sync task. I'm not going to bother with that in this
00:30 course. If you feel that you need to ,you can
00:32 definitely do that. Now there's a sample that comes with the
00:36 Amazon SDK. If you go to in app purchasing, samples
00:39 and then this button clicker application, you can load that in and check out their
00:44 observer to see how they did the a sync task, and there's also a sample about
00:48 obfuscation, for saving data with obfuscation.
00:54 Alright, so let's close this. So what I'm going to do first is I'm
00:59 going to get rid of these super calls. Some developers like to keep those in I
01:05 prefer to, to keep them out unless they're mandatory.
01:09 And then these response objects, I'm just going to shorten them because these names
01:14 are so long. I'm going to call that oen res.
01:17 And I'm also going to call that one res. So we'll just make our code look a little
01:22 bit nicer, now we can start. So again, what we're going to be doing,
01:28 in the activities that initiate these purchases, is to register this in app
01:33 observer with the purchasing manager. Now when that's complete, that's when
01:40 this onSDKAvailable will actually be called.
01:45 Now here you could log out to log cat, whether it's in Sandbox mode or not using
01:49 this boolean. But what we're going to so is to initiate
01:53 the purchase update request. And you want to do this right away
01:58 because like I said let's say somebody gets a brand new Kindle to download your
02:02 application again. You want to make sure that anything that
02:06 they're already entitled to, which means they've already bought, is going to be
02:10 shown inside of this application and that's what this method call does.
02:16 So all of the methods on the Purchasing Manager are just static methods.
02:21 So purchasingmanager.initiate purchase updates request.
02:27 Now you'll see that it, it expects an object of type offset.
02:33 And the reason for this is essentially, let's say the user has been using your
02:37 app for a year. And they've, you know, hundreds of times
02:42 they've initiated an InAppPurchase. Basically when you call this, you can
02:47 pass in an offset, and say, only give me the results starting at this particular
02:52 point. What we're going to do is to simply use
02:57 The offset class and we're just going to use the beginning constant.
03:03 And what this means is, we're going to download the entire InAppPurchasing
03:07 history for this user inside of this app. Now if you wanted to, when this response
03:14 returned. You could look at, the current offset.
03:19 Save that to shared preferences, and then the next time you called thi,s you could
03:22 give the offset, then you're only downloading the new, purchasing updates.
03:27 We're just going to do it from the beginning So, that's all we're on on SDK
03:32 available. Now, in on purchase updates response,
03:37 again we're going to get this response object.
03:41 And what we first want to do is look for revoked skus.
03:45 Now again, this is very rare, but let's say a user has bought something in your
03:49 app, and for some reason Amazon has, maybe there's some kind of fraud or
03:53 something. And they actually on their end will
03:58 revoke that purchase so that will be represented here in this response object.
04:04 So we're going to iterate over them. So I'm going to say four string and I'll
04:10 call it skew. And we're going to get those revoked
04:13 skews by going into the response object. And get revoked sku's, like that.
04:23 Now for any sku that's been revoked for this particular user, we basically want
04:29 to put into the shared preferences a false value for that particular sku.
04:36 So we're going to go to prefs.edit and then we were going to put a boolean
04:41 value. Now for the argument its going to be the
04:46 actual skew of the item which we already know so we were going to put in skew, now
04:52 the second argument is which value was since its been revoked We want to put in
04:58 false. And then lastly, I'm just going to
05:05 immediately commit that. So again, just to go over how we're
05:10 actually implementing this, if the user purchases something, say the camouflage
05:14 style wheel, when that PurchaseResponse comes back.
05:19 we're essentially going to put a value in the shared preferences the key will be
05:23 the actual SKU which would be camo and then we would actual say true because
05:27 that, they actual own that now. And here we are essentially saying if any
05:34 of these purchases have been revoked by Amazon lets change that value to false.
05:40 Okay, so under here, now what we need to do is to essentially test for two cases,
05:45 on the updates request status. And so we're going to create a Switch
05:51 statement, and the thing we're going to be switching over is that response
05:58 object, and then getPurchaseUpdatesRequestStatus.
06:05 This is going to give us the status of whether or not we've successfully
06:10 retrieved the purchase updates for this user.
06:15 So for this first case we can actual use constants from the purchase updates
06:20 request status class or actually going to do I'm going to copy this import, right
06:26 here, paste it. And then we can go to that e-num,
06:32 Purchase updates request status. And now when we come down, we can say
06:39 case Successful, that's if we've successfully downloaded the purchase
06:45 updates for this user. And now we're going to iterate over
06:50 those. So again, we're going to create a for
06:53 statement. Now what this is going to give us is the
06:55 actual receipt. So anytime you Successfully purchase an
06:59 in app item, a receipt will be sent to this on purchase response, again this
07:04 receipt contains a lot of information about the transaction.
07:11 So I'm going to say typeReceipt, I'll just say rec for receipt and we get those
07:17 receipts by going to our response object and then we call the getReceipts method.
07:27 So now inside of here, we're essentially going to do, the opposite of what we did
07:33 here. So I'm going to copy this line.
07:38 Come under here. Paste it in so we're going to say
07:42 prefs.edit.putBoolean and then now we need to get the skew from this rec.
07:49 Well, for that, we can say rec.getSku. That will get us the actual Sku of the
07:56 item that they're, have already purchased before.
07:59 But here we want to set it to true so that they have access to it.
08:04 And now we can just put a break in here and move on to our next case.
08:13 So the other case that we need to look for.
08:16 Is failed and that just means that for some reason something has happened and,
08:21 you know, this response for purchase updates has failed.
08:27 So, you can handle this error anyway you want.
08:32 It will degrade gracefully if this actually fails.
08:35 But that's in essence what we do in on purchase updates.
08:38 We reach out to the Amazon client and say look what has this user actually
08:43 purchased for my app before because for some reason they're coming into the app
08:47 and it's, it's not showing anything. Again, they've.
08:53 Gone to a different device, uninstalled it.
08:55 I want to make sure that I'm actually unlocking those items for that user.
08:59 And remember this is only for entitled InApp objects, entitled and
09:03 subscriptions, so consumables wouldn't work like this because again, they are
09:08 just one time only things and they don't travel across different devices...
09:17 Okay, so now let's go to onPurchase response, and again, this is arguably the
09:21 most important, because this means you're going to get paid, assuming everything
09:25 went well in here. What we're first going to do in here, is
09:30 to check the status of this purchase. So, what we're going to do is to create a
09:36 switch statement. And, what we're going to be switching
09:40 over is res which is our response object. And we're going to say get purchase
09:47 requests status. So the first case, is going to be
09:55 successful. Now this means that the purchase was
09:59 successful, and we can actually now unlock that item for the user inside of
10:03 our application. So the first thing I'm going to do is get
10:09 the skew which will tell me which in app item was actually purchased.
10:14 So I'll just create a string here and call it skew.
10:17 And then I'l go to my response object, and I'll get the receipt.
10:23 And inside of that, I can get the sku. So I now have that string telling me
10:30 which item was purchased. And again, up here, I'm going to copy
10:35 this line. 'Cuz it's the same thing.
10:38 We're going to write to the shared preferences that they now have access to
10:43 this item. So I'm going to want to make sure I put
10:46 true in there. And now I can actually break out of this
10:50 case. So the next case to look for is called
10:56 ALREADY_ENTITLED. What this means is somehow, the user has
11:01 initiated a purchase for an item that they've already bought before.
11:06 Now, this could happen in our application on the activity where you buy the
11:10 different wheel styles. I have a button that says, you know, buy
11:15 for $0.99. So let's say that for some reason I
11:18 didn't remove that button, even though the user had bought it.
11:22 Well, this would be the case here, the response would say, hey, they're already
11:26 entitled to this object. So, what I want to do here, is to
11:31 actually. Create a string object and this is going
11:36 to contain the request ID, and so I'm going to say req, for short, is equal to
11:43 response.getRequestId. Now, how this works is, any activities
11:51 where you actually initiate a purchase, let's say you click on that button to buy
11:55 that camouflage wheel. That method will actually return a
12:01 request ID and what we're going to do is to write that to the shared preferences,
12:06 that way once we come in here we can actually retrieve that string value and
12:10 actually set that value to true and again this part will make more sense once we.
12:20 Actually start initiating some purchases, so I have that request ID now what I want
12:25 to do, and I am just going to paste this in again and we go to perhaps edit put
12:29 Boolean and here we want to pull out the SKU from the shared preferences because
12:35 when we initiate a purchase, we're going to create a share preference with this
12:40 request ID as the key, and then the skew as the value.
12:49 So here we're going to put a boolean, and we're going to say prefs.getString, and
12:55 the key for this is going to be our request ID And the default value, we'll
13:01 just set to null. Now, the actual value that we want to put
13:08 in is true, because, again, they have already purchased this item.
13:13 But this whole part of getting the string and the request id, again, will make
13:17 sense once we've started to initiate some purchases.
13:22 Okay, so now we're done with this case. So the break.
13:27 Now another possible case to deal with is A user tried to purchase something using
13:32 an invalid skew. So I'm going to put in that case, invalid
13:36 skew. Now this is going to be pretty rare,
13:39 because, you know, how would a user actually do that, they're not inside of
13:44 the code putting in the skew. This would be more likely a problem on
13:49 your end, somehow the skew that was sent doesn't match the skew of the in-app item
13:53 that you created on the developer portal. But again, inside of this case, you
14:00 essentially want to do some type of error handling.
14:04 But again, this is maybe not something that you're going to be even presenting
14:07 to the user if that happened. And the last case is failed and that just
14:13 means that this purchase has failed, now it's important here and again you can
14:17 handle that anyway you want but I do want to point out that Amazon.
14:25 Doesn't want you to be messaging to the user about their purchase failure.
14:32 All of that will be handled inside of the Kindle UI for in-app purchases.
14:38 So let's say they try to buy it. Amazon might come back and say your
14:41 credit card is invalid. Or, you know, any number of reasons.
14:45 So. You're not supposed to be providing any,
14:48 you know, messaging to the user about why it failed.
14:53 That's all supposed to happen inside of the actual kindle UI.
14:59 So those are our three callbacks implemented.
15:02 Again, we have SDK available, which initiates those purchase updates, so we
15:06 make sure that We set the correct entitlements based on the purchasing
15:11 history of the user. And then the on purchase response, this
15:16 is where the user has initiated a purchase.
15:20 And this callback is going to be called, it'll tell you was it a successful
15:23 purchase. If it was again You're a little bit
15:27 richer. We're going to make sure we actually put
15:30 the shared preferences Boolean to true for that sku.
15:33 If they're already entitled, if that happens, we're also going to set it to
15:37 true. To make sure that we've recorded it here.
15:40 And again, invalid sku would be pretty rare.
15:43 Probably be a problem on your end. And failed basically means the
15:48 transaction failed, I mean again Amazon will message why that was to the user.
15:55
Collapse this transcript
Initiating in-app purchases
00:00 Kay. So now that we've completed our
00:02 purchasing observer class let's start initiating some purchases from within our
00:07 application. So we're going to start in Game.java, and
00:11 that's the main activity where you're actually playing the game.
00:15 Now, the first thing you're going to need to do in any activity where you want to
00:21 provide In-APp purchases is in the onStart override method here.
00:28 What we need to do is create an instance of that In-App observer class.
00:33 I'll just call it obs for short, is equal to new InAppObserver.
00:41 And remember, it's expecting the calling activity in which we can just say is
00:45 this. So now that we have that instance, now,
00:49 we need to register it as an observer with the purchasing manager.
00:55 It's going to be a static method of the PurchasingManager class and its going to
01:02 be registerObserver. And we're going to pass in that obs
01:09 property that we just created. So now, once we do this, it's now
01:17 going to go out register that observer, and when that's finished, the
01:21 onSDKAvailable call back method will actually be called in our observer class.
01:27 So now, the way we're going to handle this in our application is in our
01:32 observer. We're simply writing to the default
01:36 shared preferences whenever the user buys something or we find out that they're
01:41 entitled to something. So the way we're going to react to that
01:47 in our activity is to listen for the registerOnSharedPreferenceChangeListener,
01:52 which will fire anytime the shared preferences have been changed.
01:59 So I'm going to come right under here and onCreate.
02:03 And I'm going to say prefs.registerOnSharedPreferenceChangeListener.
02:10 So that's one of the longest method names I've ever seen.
02:14 But we're going to create a method in here called prefsChanged, like that.
02:23 'Kay, so now, we need to actually implement this method.
02:26 So I'm going to come under here, and we're going to create an instance of the
02:29 OnSharedPreferenceChangeListener. And I'm going to call this prefsChanged,
02:37 'cuz remember, that's what we called it above.
02:46 I'm going to set that equal to new. What it's going to create is an anonymous
02:53 inner type of event handler, and what this overwrite method here is, is
02:57 OnSharedPreferenceChange. This is going to give us information
03:03 about what shared preference value was actually changed, and once we have that
03:08 information, we can react to that inside our application.
03:13 Alright, so I'm just going to short this press, just because I like to keep my
03:18 variable names a little bit short. So we're first going to check that key,
03:24 because again, any preference that has been changed in the application, it will
03:28 fire this event handler, so we want to make sure it's the actual shared
03:32 preference value that we are looking for. So I'm going to put in an if statement
03:39 here, and I'm going to say if key.equals, and now, we're going to to look for the
03:45 skew for the item that you can buy from this activity.
03:52 And remember, in this activity, the only thing you can buy is more money and
03:56 that's the Buy More Money button at the top.
04:00 Now, the skew for that actual In-App item is money.
04:05 Remember, we defined that on the developer portal.
04:09 Okay, so if key equals money, and now we're going to go to prefs.getBoolean,
04:16 and we're going to, to look for the key of key, which is what was sent to this
04:22 method. And we're going to set the default value
04:30 to false. So now, again, what we're doing here is
04:35 we're checking which shared preference key and value were changed.
04:40 So if it's money, then that is the correct item for this activity.
04:45 And we're also checking to see if that value is true.
04:49 And remember, that will be set from our In-App observer class.
04:53 So if this does happen, that means they've purchased more money.
04:57 So now, we need to just go through, and that integer that holds the score, plus
05:03 equals 1,000, and now we want to also update that text field.
05:11 So I'll just copy this and paste this underneath.
05:16 So it's just setting that text field so the user can see that they have that
05:20 money. And now, the next thing we want to do is
05:23 to set this shared preference back to false.
05:27 Because remember, you can buy this item multiple times.
05:31 So now that we've seen it's true, they purchased it, we handled that.
05:35 Let's set it back to false now and wait for them to purchase it again.
05:40 So I'm going to say prefs.edit. And now we're going to put a Boolean
05:45 value and the key is going to be money, because remember, that's this queue.
05:52 And we're going to put false, so it's ready for them to essentially by this
05:57 again. So that's our preference change listener.
06:03 And again, this is a handy way to do it, because, we don't have to communicate
06:07 back and forth with the observer class. And we can just listen for changes to the
06:13 shared preferences, and then react if it's the right preference that was
06:18 changed. Okay, so this is good.
06:22 We're able to react to purchases, but now, we need to actually initiate a
06:26 purchase and the place we do that is at the bottom, inside of this addMoney
06:30 onClick event handler. Remember, this is the event handler that
06:36 gets fired once the user clicks on that button.
06:39 So to purchase something, it couldn't be easier.
06:43 It's again, a static method on the purchasing manager class and it's called
06:48 InitiatePurchaseRequest. And all you pass to it is this queue for
06:53 the In-App item that you want to purchase.
06:57 So in our case, it's money and that's all we need to do.
07:03 So essentially, when the user clicks on that button, this will initiate a
07:08 purchase request for the item with a skew of money.
07:13 The SDK manager will process that and respond back to our in app observer.
07:19 If it was successful, it will set the shared preferences value to true and
07:23 we'll get notified of that here, and we can actually, you know, increment the
07:27 score, and also do other things and react to it.
07:33 So the, again, this is a nice workflow for doing this type of stuff.
07:37 Now, the next activity where you can actually buy something is the ChangeWheel
07:41 activity. And again, this is where they can chose
07:46 to unlock certain wheel styles. So now, for the onStart, it's going to be
07:51 the same thing. So I'm just actually going to copy it
07:55 right from the Game class. Now, if you want, you can architect it so
08:00 you're perhaps using only one incidence of the In-App observer, you can
08:03 definitely do that. But for our case, we're just going to
08:07 keep it like this. Now, we're also going to be listening for
08:11 the changes to the shared preferences. So let me copy that also.
08:16 Let me go to onCreate, copy these two lines and I'll paste them into onCreate
08:23 here. Let me define that as a field.
08:29 And again, I'm going to copy that onSharedPreferenceChangeListener.
08:36 So let me copy this whole block. I'll come back under the onCreate method
08:43 and paste that in. Okay, so we're going to be doing the same
08:48 type of thing here. obviously we're not going to be doing
08:51 these specific things. But let me actually just remove these two
08:56 lines. So the first thing we're going to do is
09:00 to check if the key is equal to camo. And if it is, that means we need to
09:05 unlock the Camo Wheel style. So we're going to check for that, and
09:09 again, we're going to keep this the same and we're going to get the Boolean of the
09:14 key. if, if it's not true, we're going to set
09:18 it to false. And now, we actually want to unlock that
09:21 Camo Wheel, so there's a few things we have to do.
09:25 First, we want to change the image resource on that image.
09:30 Because, essentially, when you haven't purchased it, it has a little pad lock on
09:34 it. So I'm going to go to that camoButton and
09:37 then I'm going to call the setImageResource.
09:41 And now I can go into my resources. I'm going to go to R.drawable.camowheel.
09:51 You can see there's two, there's camowheel and camowheel locked, so we
09:56 want to change it just to the regular camowheel.
10:00 So the next thing we want to do is to actually enable this button.
10:06 So I'm going to say camobutton.set, enabled to true, because in the XML where
10:12 we defined these, I actually set it to false, so that you couldn't click on the
10:17 locked Camo Button and actually change the wheel.
10:25 Now, the last thing I want to do is to remove or to set the visibility property
10:29 of the Buy button to invisible. So that button is called Buy Camo button.
10:36 And I want to call the setVisibility method.
10:41 And I'm just going to go to a constant in the View class of invisible.
10:47 And that's essentially just going to make it invisible, and also make it so that
10:54 the user can't try to buy that item again.
11:00 Now, this line down here, we're not going to have to do, because again, the
11:04 user can only buy this item one time. So, if this comes back as true, then it's
11:10 always going to be true. Okay, so now, we need to deal with the
11:15 Gold Wheel case, so I'm going to copy this block and we're going to do an else
11:19 if. Else if key equals gold, which is the
11:25 skew for the Gold Wheel. If that equals gold and the getBoolean is
11:30 true, which will be set by the In-App observer, then we're going to come
11:34 through and all we need to do is just to change the names here.
11:41 Gold button, goldButton, the drawable is actually just called goldwheel.
11:50 And the buyGoldButton we want to set to invisible so the user can't buy it again.
12:00 Okay, so now we're set up to actually respond to changes to the shared
12:04 preferences. Now, let's actually initiate the
12:08 purchases. So I'm going to come down to the
12:11 buyCamoButton, which is the button that's actually going to initiate the purchase.
12:17 And much like I did for the game activity, I'm going to call the
12:21 PurchasingManager, .initiatiePurchaseRequest, and I'm
12:26 going to put the skew of camo, which is the skew for that item.
12:32 The difference here is this method actually returns a request ID to me.
12:39 So I'm actually going to store that, so I'm going to store that in a string.
12:43 I'll just called it req for request. And now, what I want to do is to write to
12:48 the shared preferences. So now, what I want to do is to put a
12:53 value in the shared preferences, where they key is going to be this request ID
12:58 that I just got and the value is going to be the skew of the item.
13:05 So we're going to say prefs.edit.putString, and again the key
13:10 is going to be that request ID that we just retrieved, and the value is going to
13:16 be the skew of the item that's attached to that request ID.
13:25 In this case, it's going to be camo and we'll commit that.
13:31 So now, I'll explain what's going on here in a second, but let's first fill in the
13:35 buyGold method, because it's going to be essentially the same thing.
13:40 We're looking to buy the Gold Wheel with the skew of gold, and again, we're
13:44 going to put into the shared preferences that unique request ID with the skew.
13:51 So where this is used is in the In-App observer.
13:55 So if we come to the onPurchaseResponse call back, if the user is already
13:59 entitled, meaning they've already purchased this item before, you don't
14:03 actually get a receipt returned to you so that you can get the skew.
14:09 So that's why what we do here is to find out the request ID for this purchase, and
14:15 then, we actually put a Boolean into share preferences.
14:21 And for the key, we actually retrieve what the skew is using that shared
14:27 preferences property that we just set in ChangeWheel.java.
14:33 So again, this is a way for us to get the actual skew from a request ID and we're
14:37 setting it to true and committing. So that's essentially what that's for.
14:45 So with that, we're now actually finished with our In-App purchasing code.
14:49 In the next movie, I'll show you how to set up your emulator or device to be able
14:53 to actually test these things locally.
14:57
Collapse this transcript
Testing in-app purchases
00:00 Ok, so now that our code's done, now we can actually test out our in app
00:04 purchases. So, I'm going to be testing it here in
00:08 the emulator. But if you want to test on your actual
00:12 device, I'll show you how to do that. So, I'm going to go into the Amazon_SDK,
00:19 into In App Purchasing. Tools, and then here, we can find this
00:26 AmazonSDKTester.apk. So, I'll just Copy, Paste that to the
00:32 Desktop. And then, I can go into my terminal
00:36 window. So now, we're going to install this onto
00:39 your device using ADB. So, I'm going to say adb install, then
00:45 it's on my Desktop and it's called AmazonSDKTester.apk.
00:53 Now, when I run this, it's going to fail because I already have this application
00:56 running on the emulator. But if you have your device connected
01:01 through adb and you don't have that device, this will succeed.
01:05 But you can see it's trying to push it and it's saying it already exists.
01:10 But that's how you would install this onto an actual Kindle device.
01:15 So, we have that part. Now, we, we have the STK Tester
01:19 application. The next part is we need to create a JSON
01:23 file which defines the in-app items that are available and that we're going to
01:27 test locally. So, if you go into the exercise files,
01:32 inside of the Assets folder. And then, the other folder, you'll see
01:38 this Amazon.SDKTester.json file and this is a template.
01:45 So, what we need to do is for each in-app item, we need to create a JSON object
01:49 with all of the details. So, the first thing we need is the sku.
01:55 So, lets start with the money in-app purchase.
01:57 Now, for item type, this could be consumable, entitled or subscription,
02:04 this one is a consumable. The price is $0.99.
02:10 And again, this information, you can match exactly to the information you put
02:15 into the developer portal. But again, we're just testing locally.
02:22 So, Buy more money, description, Buy more money, just do the same thing.
02:29 And then, if we wanted to test out the icon, we could actually put a path here
02:33 to that image. Okay, so that's the one item defined.
02:38 Now, I'm just going to copy this. No need to put a comma in between each of
02:43 these. And I'm going to Paste it twice.
02:47 Now, we can start filling in these other items.
02:49 So, first let's do the Camo wheel, which has a sku of Camo.
02:54 This is not a consumable, it's an entitled type, it's also $0.99.
03:03 we'll say Buy the camo wheel. (SOUND) And let me just Copy this, Paste
03:10 it in here. Again, we're not going to put a path to a
03:15 image. And the last one is gold.
03:19 Again, this entitled, not consumable. Buy the gold wheel, and I'll just Copy
03:29 this and put the same thing in for the description.
03:36 Okay, so now we have our file defined. And again, this is just for testing
03:40 locally. So, now what I'm going to do is to Save
03:44 this to the Desktop. And again, it has to be a file of this
03:49 exact name, so let me Save that. So now, what I need to do is to push this
03:54 JSON file onto my device or emulator. So, I'm going to go back to terminal, and
04:00 let me just clear this really quick. So, we're going to use the adb push
04:05 command. So, I'm going to say adb push, and then
04:09 the file we want to push, for me, it's on the Desktop, it's called
04:13 amazon.sdktester.json. And then, now we need to provide the
04:19 location for were we actually want to push that.
04:24 And we want to push it to mnt, for mount. And then, sdcard.
04:28 Essentially, we are putting it at the root of the SD card.
04:33 And when I hit Return, you can see it's uploaded that information successfully.
04:40 Okay, so now we have the necessary tools to actually test our application.
04:46 So, let's go back to Eclipse and we're just going to run this.
04:51 Now, it should, actually, if you only have one device connected, it should
04:54 automatically go to that device. But again you are familiar with Android
04:58 Development. So, I'm going to run this and it's now
05:02 going to push it to the emulator. So, let me go over to the emulator.
05:08 You could see, it's already created the App icon for me.
05:12 And here is the main menu screen. So, I'm going to click on Play Game.
05:18 And let's first try this Add Money button, which again, allows me to buy for
05:23 $0.99, 1,000 more dollars. And here you can see the Kindle UI
05:28 popping up for in-app purchase. It's a little slow here, because again,
05:32 I'm in the emulator. But this information right here is being
05:35 pulled out of that JSON file. So, the price, title, description.
05:40 So now, I'm going to click Purchase. Now, at this point, the in-app observer
05:45 hasn't been contacted yet. And it's only when this dialog is
05:49 dismissed. But it's essentially saying thank you for
05:53 purchasing. So now, I'm going to dismiss this.
05:57 And then, now, the in-app observer is notified which changes the shared
06:01 preferences. Then this activity reacts by adding
06:05 $1,000 to their total. I can also now go to Change the Wheel.
06:11 And you can see, I now have the two locked items, so let's unlock it.
06:16 So, I'm going to buy the camo wheel. And you can see here that all that
06:21 information's coming from the JSON. I'll click purchase, dismiss, and then
06:27 when I do that the updated shared preference event handler is being fired.
06:33 And then, I'm making this now, available to the user.
06:37 So, while I'm at it, I'll just go through.
06:40 I'll buy the gold wheel as well, close it.
06:43 And now, I'm going to click the camo wheel, and now we can play the game with
06:47 the camouflage wheel. Well, I didn't do very well on that one.
06:52 Now, let's go back to the Home Screen. And I want to open up that Amazon Test
06:57 Client application. There's a few different things I can do
07:01 inside of here. Most importantly, I can look at the
07:04 Active Transactions. So, when I click on that, it's
07:08 essentially going to bring me to this page and it's going to show me that there
07:12 are two active transactions. Two purchases that were successful.
07:17 And what I can do is essentially remove those here by clicking Cancel.
07:24 So now, if I were to clear the data for my game or just uninstall it and
07:28 reinstall it, they wouldn't be shown as being purchased.
07:34 So, in a way, this is a way to revoke those transactions for testing purposes.
07:40 Now, another thing you can do here is to change the user.
07:43 Now, remember in our application, we're not dealing with that case where there is
07:47 somebody has a Kindle device. And then, they give it to somebody else
07:52 and they log in into their own Amazon account and play the same game.
07:56 But this is where you could change the actual user to a different user.
08:01 And again, that all happens in the observer class, when you do the get user
08:04 ID request. So, you can do that.
08:07 And then, you can also force certain responses from the SDK Tester.
08:12 So, we go into interactive mode we can make it so that any call to initiate a
08:17 purchase, we can make it have an invalid skued, or failed, or already entitled,
08:22 and the same thing for these other APIs. So, we can test our application to see
08:29 how it responds to those different cases. So, with that, we've now successfully
08:35 implemented in-app purchases for Kindle devices.
08:40
Collapse this transcript
3. Using the GameCircle API
Overview of the GameCircle API
00:00 So the next Amazon specific API that we're going to implement is the
00:04 GameCircle API. And you can think of this as kind of
00:08 similar to Game Center on iOS or any other global leaderboard achievement type
00:13 service. So the GameCircle API allows you to
00:18 easily add global leaderboards achievements and the ability to sync a
00:23 game's progress with the Cloud. So for Leaderboards, here's what the user
00:29 will see once they've submitted a score. So it will pop up a Kindle UI window,
00:35 this is essentially their GameCircle window.
00:40 And here is the actual high score leaderboard, for Spin-it, and you could
00:44 see here is what the top high score is. And, essentially, in your game, at any
00:50 point, you can be submitting the users scores to these global Leaderboards.
00:56 And you can actually have multiple, up to 50 leaderboards for your game.
01:01 The next area are achievements, and this is a pretty simple one.
01:05 You can make different achievements, and in our example, it's going to be really
01:09 simple. Once the user has reached a $1000, then
01:13 they're going to unlock that achievement. And here, we can see in the GameCircle UI
01:19 that I can look and see that I've already earned that achievement, and again, this
01:24 is a good way to engage users and to keep them playing your game.
01:30 Now, the last piece is Whispersync. And now, this is a really cool technology
01:35 that allows players to uninstall and re-install their games without loosing
01:39 their progress, because at certain times in your application, you can sync your
01:44 games' state which is essentially going to be your shared preferences.
01:51 You can sync that to the cloud. So that when the user maybe goes to a
01:55 different Kindle device or they somehow uninstall, re-install the game, they're
02:00 going to be able to actually sync up with the Cloud and continue playing where they
02:04 last left off. So again, those are the three parts of
02:10 the GameCircle API. And now, we're actually going to go to
02:14 the Amazon developer portal and create these items.
02:20
Collapse this transcript
Creating items in the developer portal
00:00 So, now that you've seen an overview of the GameCircle API.
00:04 Now, coming to the developer portal and we're going to add the leader board and
00:09 the achievement to our application. So, I'm on the my apps page and I'm
00:14 going to click on Spin It. And much like the, in that purchasing,
00:19 there's a link here for GameCircle. And essentially, here, there's a few
00:24 options. I'll come back to this white list of
00:27 binary in a minute but first let's add a leaderboard to our game.
00:33 So, now it's going to ask for a display title and this will appear in the actual
00:37 Kindle UI that pop-up for GameCirlce and I'll just call it High Scores.
00:44 Now, for a leaderboard ID you then need to reference this in your app.
00:48 So, just call it high_scores and then for a description these are the high scores.
00:59 Now for units, this is essentially a string which is going to be at the end
01:03 after the actual value of the score, so in our game I'm going to change that to
01:08 dollars. Now, this score threshold is something
01:13 you can use to try to figure out people who are cheating at your game.
01:18 We're not going to do that here but it is an option, for the Sort Order, obviously
01:22 we want highest scores first to be shown. You could change that if you wanted, and
01:28 then we need an icon to upload which is going to be shown inside of the
01:31 GameCircle UI. Well, if you go into the Exercise Files >
01:36 Assets > Artwork, we're just going to use the actual Largeicon.png here for the
01:39 leaderboard and I'm going to go ahead and click Save.
01:44 So, this is now going to upload that image and we've now successfully added a
01:47 leaderboard to our application. Now, unlike in that purchasing, where we
01:53 had this local test environment with a (UNKNOWN) file for GameCircle, when we're
01:59 testing we're actually going to be coming out and communicating here with these
02:05 items that we're creating in the developer portal.
02:13 So, it's important that you do this step first.
02:16 Okay, so we finished that. Now, let's go ahead and, let's go back to
02:21 GameCircle, and I'm going to click Add An Achievement.
02:27 So, we can add an achievement to our game.
02:28 We're going to call it, you reached $1000, and essentially that's going to be
02:33 what the achievement is, as soon as your score goes beyond 1000, then you're
02:38 going to unlock this achievement. Achievement ID, again we're going to need
02:45 to reference this in our code. So I'm just call it 1k.
02:49 Now, here you need to provide two descriptions, one for the lock state, so
02:53 if they're in the GameCircle UI go to the achievements tab.
02:58 This is the description that will show at that location, so I'm going to just say,
03:03 you can do it a little inspirational message.
03:07 Now, when it's unlocked, the description, I'm just going to say, you did it.
03:14 Now, here you have an option to hide the achievement from the user, so even if
03:18 they're in the GameCircle UI and they go to achievements, they won't even know
03:21 that a certain achievement even exists, but we're not going to do that, so we
03:24 don't want it hidden. And now we need to upload two Icons for
03:30 this, one is for the locked state, and one is for the unlocked state.
03:37 So I go to Choose File, and again go into the Exercise Files, into Artwork, then go
03:42 into the GameCircle folder, and here I have a lockedicon.png.
03:49 So, essentially just the app icon with the little padlock on top of it.
03:53 Now, for the unlocked icon, well we're just going to use that large icon, which
03:58 is essentially just our app icon. And now I'm going to click Save, and
04:03 again it's going to upload these images and create the achievement for me.
04:09 So, now I've successfully created that achievement, and you can see the
04:13 difference in the locked icon from the unlocked icon.
04:17 Now, a couple of things I wanted to explain.
04:19 First is the sandbox. So, when you're using GameCircle enabled
04:25 games, you have to have a Profile, what they call a Nickname.
04:30 So, you can register your own nickname or one will be automatically assigned to
04:34 you. But, if you want people to be able to
04:37 actually test out the game circle APIs before they're published, you need to add
04:42 their game circle nickname to the Sandbox, and we'll get to this later in
04:46 the chapter. Now, the others, the white list registry,
04:53 where we can white list a binary, so basically what we have to do is to
04:57 generate our unique key hash based on our Android Debug Key Store, and that's the
05:02 key that we use every time we publish a debug version of our application.
05:12 So, together with the package name, once we put them here in the portal, any of
05:16 our debug applications created with that package name and with that debug key are
05:21 going to be able to properly communicate with the GameCircle APIs.
05:29 So, in the next two movies, I'm going to be showing you how to generate that Hash
05:33 Key both on Mac and on Windows.
05:37
Collapse this transcript
Whitelisting your binary on a Mac
00:00 So, like I mentioned in the last movie, an important part of being able to test
00:04 the GameCircle APIs while you're debugging your application is to
00:08 whitelist your binary file. So, we can see here, if I click whitelist
00:14 binary, it's asking me for two things. First is the package name for my
00:19 application. And then, the signature.
00:22 And this is actually the hash key, signature of the Android debug key store.
00:28 So, we're going to need to generate that. So, I'm going to go into terminal.
00:34 And to do this, we're going to use the Keytool application that's in the Java
00:38 JDK. So, I'm going to say keytool -exportcert.
00:44 And then, we're going to say -alias. And for the debug keystore, the alias is
00:52 androiddebugkey. Then, we're going to say -keystore.
00:58 And now, this is the actual path to the location of the debug keystore.
01:05 Now, on the Mac, that's usually in your Home Directory inside a Folder called
01:10 .android. But if you're not sure, you can always
01:14 open up Eclipse and go into Preferences, Android, Build, and it will actually give
01:19 you here, the path to your debug keystore.
01:23 So, I'll just go ahead and Copy that. Come back here to the command line, I'll
01:29 Paste that in. And now, we're going to use the OpenSSL
01:34 Library to generate our key. So, we're going to pipe into openssl,
01:41 sha1 -binary. And we're going to pipe those results
01:48 back into openssl and we're going to say base64.
01:55 So again, this should be pretty much identical for everybody except the
01:59 location to the keystore because obviously, our user directories are
02:02 going to be different. But this is pretty much the exact command
02:07 that you'll need to run. So, I'm going to run it.
02:11 And now, it should ask you for the password.
02:13 If it doesn't ask you for the password, it means you've done something wrong.
02:16 And usually, that means you have the wrong path to the keystore.
02:21 So, for the debug keystore, the password is always android.
02:25 And when I do that, it's now generated my hash key signature.
02:29 So now, I'm going to Copy this. And we'll go back to the Developer
02:35 Portal. And I'm going to Paste that into the
02:37 signature field. Now, for the package name of the
02:41 application that you're creating. So, if we go into Eclipse, the files that
02:47 I gave you inside of this project, if we go into the manifest, you can see that
02:51 this actually has a package of com.leebrimelow.spinit.
02:56 But the thing is, you're not going to to be able to whitelist your binary, if you
03:00 have this package name. It needs to be a unique package name that
03:06 no other Amazon developer is using. So, I am actually going to have to change
03:11 the package name, because I've already added it before under a different
03:15 account. So now we're going to change the package
03:19 name of our application. So to do that, I'm just going to
03:24 right-click on the project, go down to Android Tools, and then select Rename
03:28 Application Package. Now, here you can rename it to whatever
03:32 you want. It doesn't matter.
03:35 I'm just going to say com.brime.spinit. But again, this needs to be unique and
03:44 needs to be something that no other Amazon developer is currently using.
03:48 So, I'm going to click OK. And now, it's going to show me the
03:52 results of all of the changes that are going to be made.
03:56 You can just leave everything at the default, and click Finish.
04:00 And now it's saying that the manifest has changed.
04:04 Do you want update you launch configurations?
04:06 Yes. And now, we have a new unique package
04:09 name for our project. Now the thing is, inside of the Source
04:15 folder, the actual package to my Java classes is still com.leebrimelow.spinit.
04:22 So, more than likely, you're going to want to change those.
04:24 And to do that, just right-click on the package, Refactor, Rename, then you
04:29 want to give it that unique package that you just created for your application.
04:36 So com.brime.spinit, Update references, I don't have any subpackages.
04:43 So, I'll click OK. And this will come up, you don't have to
04:48 worry about that, just click Continue. And now, it's renamed the actual package
04:53 to my Java files to that new package name.
04:57 Now, the one thing about that is, if we go back to the manifest, it hasn't
05:01 updated the other values inside of this XML file.
05:05 So, we need to do that really quickly as well.
05:08 So, I'm going to Copy the package. And anywhere I actually see the package,
05:13 I'm just going to replace it with the new one.
05:17 So, for all of the activities, I'm going to replace it.
05:21 Now, you could do search and replace here, but I've had some really funky
05:26 results using search and replace in Eclipse.
05:30 So, I'll click Save. And now, both the actual package name of
05:33 my application, as well as the source code packages have been changed.
05:39 And you should now have a unique package name that you can add to the Portal.
05:45 So, let's do that. Let's go back to the Portal, and I'm
05:48 going to enter in my new package name. And I click Save.
05:53 And you can see it, the whitelist information was successfully saved.
05:58 Now, these other ones in here, you can see that as I was doing testing for doing
06:02 this course, I've added a, a couple of others.
06:06 Now, you can't delete these once you've added them in here.
06:09 You basically have to e-mail customer support and tell them to remove them.
06:13 But if you add multiple in here, it's not going to harm anything.
06:17 As long as a current project you're working on, again is in here with the
06:20 correct signature. So with that done, we're now ready to
06:25 start, actually incorporating some GameCircle APIs.
06:30
Collapse this transcript
Whitelisting your binary on Windows
00:00 So, in the last movie, I mentioned that a really important part of being able to
00:04 test the GameCircle API's while you're debugging your application is to
00:08 whitelist your binary. So, we can see here that there is a
00:13 button here, I'm going to click Whitelist a Binary.
00:16 And it's going to expect two pieces of information.
00:19 First is the Package Name for your application.
00:22 Now, this has to be unique. And nobody else, no other Amazon
00:26 developers can be using that package name.
00:29 And so, obviously, we're going to have to go into Eclipse.
00:32 And each of us are going to have to generate a unique package name for our
00:35 application. The next piece of information is the
00:40 actual hash key Signature for your Android debug keystore.
00:45 And that's what we're going to generate right now.
00:47 So, I'm going to go to my command prompt here.
00:53 Now, make sure you've watched the video on setting up your Windows Environment,
00:58 because remember, in that video, we added Open SSL, the Java JDK, and the Android
01:03 SDK tools to our environment path. So, we can use them from anywhere.
01:10 So, we're going to use an application from the JDK called Keytool.
01:15 So, Keytool, and then -exportcert, then -alias.
01:21 And now, the alias for the debug keystore is androiddebugkey.
01:28 And the next thing we need is the actual location of the Android debug keystore.
01:34 So, we're going to say -keystore. And now, we need to find the path.
01:39 Now, the location of this file is going to be different depending on which
01:43 version of Windows you're using. It's usually in your User Directory in
01:48 folder caller .android. But if you need to check or find out, you
01:52 can easily do it by going into Eclipse. I'm going to do Windows > Preferences,
01:58 and then under Android, Build. We can see, it actually gives us the full
02:04 path to that debug keystore. So, I'm going to Copy that and go back to
02:11 the Command Prompt. And I'll Paste that in.
02:17 So now, we have the debugged keystore in there.
02:20 Now, we need to use Open SSL to actually generate our signature key forest.
02:26 So, I'm going to use the Pipe Operator. So, we're going to be piping this onto
02:33 Open SSL. And we're going to say sha1 -binary.
02:38 And then, we're going to pipe the results of that back into Open SSL base64.
02:46 So now, this should be exactly the same for everybody except the location of the
02:49 keystore because obviously, your User Directory is going to be different than
02:53 mine. So, I'm going to run that and you can
02:57 see, it's asking me for my password. Now, if you don't see it asking you for a
03:02 password, it means you've made a mistake in the path to your keystore.
03:07 So, the password for the Debug Keystore is always just android.
03:12 And now that I've done that, here is the actual hash key that we need to put into
03:16 the Portal. So, let me go ahead and grab that, and
03:21 we'll go back to the Developer Portal. And I'll Paste that in.
03:28 So now, we need to provide the package name for application.
03:31 So, lets go into Eclipse. Now, you remember that I gave you this
03:35 Android project, and when I gave you it to you, it had a package of
03:39 com.leebrimelow.spinit. Well, now you're going to have to create
03:44 a unique package name for this application.
03:48 Because again, it has to be unique and no other Amazon developers can be already
03:52 using that package name. Even myself here, I'm going to have to
03:56 change it because when I was doing testing, I've already added
03:59 com.leebrimelow.spinit. So, to rename our package, I'm going to
04:05 right-click on my Project folder. Go down to Android Tools, and then Rename
04:11 Application Package. Now, here, I need to come up with a
04:15 unique package name, you can use whatever you want.
04:20 Usually, you use your reverse domain minus com.leebrimelow, and then the
04:24 application name. Well, I'm going to have to switch that
04:29 up. So, let's say com.brimlee.spinit.
04:32 And click OK. And now, it's going to launch this
04:39 Window, essentially telling me all of the places that it's actually going to make
04:42 changes. And you can just click Finish.
04:46 And when it does that, it's now said, the package definition in the manifest has
04:50 changed. Do you want to update your launch
04:53 configurations? You want to say Yes to that.
04:56 So now, if we look in the manifest, we can see the actual package of our
05:00 application has now been changed. But if we look in our Source folder, the
05:07 actual package to our Java files is still that old package name.
05:12 So, you're probably going to want to change that as well.
05:15 So, to do that, you can right-click, go to Refactor > Rename, and then again,
05:19 enter that new package name that you've just created.
05:25 So, brimlee.spinit, we want to Update references.
05:29 I don't have any subpackages, so I can click OK.
05:34 And you're going to get this thing pop-up and you don't need to worry about this.
05:38 Just click Continue. And now, both the package name here, as
05:42 well as the references in all of our Java files have been updated to this new
05:46 package. So, I'm going to go into our Manifest
05:51 file. Now, it hasn't actually updated the XML
05:55 references to that old package. So, I'm going to copy the new one here,
06:00 which is com.brimlee.spinit. And I'm just going to come through and
06:05 anywhere I see the old package, I'm going to replace it with the correct one.
06:12 Now, you can do search and replace for something like this, but I've had some
06:17 extremely strange results using search and replace inside of Eclipse.
06:23 But that's up to you. So now, I'm going to Save this.
06:27 And now, we have successfully changed the package name for this application,
06:31 including the Source folder package name as well.
06:35 So now, we need to go to back to the Portal and put in that unique package
06:39 name that we just created. So com.brimlee.spinit.
06:47 And I'm going to click Save. And now, you can see the whitelist
06:51 information has been successfully saved. Now, you'll see I have a bunch of them in
06:55 here. And, that's because while developing this
06:58 course, I've added various package names in here because you can't actually delete
07:02 them from here once you add them. You can e-mail customer support and have
07:07 them remove them. They're not doing any harm in here.
07:11 And in the last movie, when I did this process on the Mac, I also added this
07:14 package name in here as well. So, much perfectly okay to have multiple
07:20 whitelisted binaries. But that's the process of getting your
07:24 binary whitelisted, so you can actually connect with the GameCircle API's.
07:29 And in the next movie, we're actually going to start implementing the
07:32 GameCircle API's.
07:34
Collapse this transcript
Setting up GameCircle
00:00 Okay, so now that we have our binary whitelisted on the developer portal, we
00:04 can actually start developing for the game circle API.
00:09 So the first thing we need to do is to import that library.
00:12 So again I'm going to Right click on My Project > Properties > Java Build Path >
00:18 Add External JAR. And inside of the Amazon SDK you want to
00:24 go to GameCircle > lib. Now there's two actual JAR files in here.
00:29 You're going to want to select this one, this other one is for Java 1.5 platforms.
00:36 But you're definitely going to want to select this one right here.
00:39 Click Open and again, much like we did for in-app purchasing, let's go ahead and
00:43 make sure that this is actually exported with our project.
00:47 So let's check that off. And lastly, let's hook up the Java docs
00:52 to this so that we can get code assistance.
00:55 So I'm going to click Java doc location > Edit > Browse > GameCircle >
01:01 Documentation > API Reference. Click Open, we can click Validate, and it
01:09 looks like everything's fine, so we'll click OK, and then click OK.
01:17 So now we actually have the GameCircle library imported, and we can begin to use
01:21 it. Now the Amazon game client that we're
01:24 going to be creating, is essentially a singly client that you're going to be
01:28 using throughout your application. So there's multiple ways in which you
01:33 could implement this, personally, I like to keep it in my Application override
01:37 class, which is called app.java. And I just create it as a public static
01:43 property. That way there's a single instance of it
01:47 that I can reference from anywhere in my application.
01:52 Now you could create your own GameCircle manager class.
01:55 there was a single 10. Again, many different ways to implement
01:59 this, a lot of developers don't like public static properties.
02:03 I tend to really like them. So, again, feel free to implement this
02:07 how you want. Okay, so what we're going to be creating
02:11 is actually a series of clients. And the first client that we're going to
02:15 create is the actual game client. This is the main Amazon Games client.
02:20 That essentially initializes and sets up the whole service.
02:25 So I'm going to say public static and this is going to be of type AmazonGames
02:31 and I'm going to call it gameClient. Now we're going to be creating three
02:37 other clients so let me just copy this a few times.
02:42 The next one is going to be the achievements client.
02:45 So for each area of GameCircle, there's a different client which you use to
02:49 actually communicate with the service. So for achievements, it's going to be of
02:55 type AchievementsClient. And I am just going to call it acClient.
03:03 Now the next is the LeaderboardsClient that, and I will just call it lbClient.
03:12 Now the lose one that we're going to be working with is the WhisperSyncClient And
03:20 I'll just call that whClient. So again, throughout my game I'm going to
03:27 be able to call out to these different clients and let's say I want to show the
03:31 leaderboards for my game. I'm going to call lbClient.
03:36 and then use that API in the LeaderboardsClient to actually show the
03:40 leaderboards. So, the one thing that we need to do in
03:45 onCreate, is we need to actually initialize this game client.
03:52 So I'm going to come under the super constructor call and I'm going to set
03:57 gameClient equal to and this is a static method on the AmazonGamesClient class.
04:08 And it is initialize. Now, it expects three different
04:11 parameters. First is the application in which this
04:15 game circle API will run. Well, we're actually in that application
04:20 class right now. So I can just say this.
04:22 The next is a callback function. This will be called once the gameClient
04:29 has been initialized. So I'm just going to call that callback,
04:36 gameCallback. Now the next thing it expects is an
04:40 EnumSet of which features of gameCircle do we actually want to use in this
04:45 application. So we, we're going to need to create
04:49 that. So lets go ahead and do that.
04:51 I'm going to come under here. I'm going to create a new EnumSet, now
04:55 the type of this is going to be Amazon Games Feature, and I'm just going to call
05:02 this EnumSet Features. And set it equal to EnumSet.of.
05:14 And now we need to pass in which features do we want to implement in our game].
05:18 Now for our purposes we're going to implement all of them.
05:23 We're going to be doing Achievements, Leaderboards and Whispersync.
05:26 So I'm going to do AmazonGamesFeature.Achievements and we're
05:32 also going to be doing Leaderboards so I'll just paste that in.
05:39 I'll change this to Leaderboards. And lastly we're going to be doing
05:46 Whispersync. Like that.
05:49 So now that we have this EnumSet that is essentially telling the game client,
05:53 which features of the APR we're going to be using.
05:57 So lets go ahead and close this up now. Now the next step is to actually create
06:03 this game callback function, so let's go ahead and do that.
06:07 I'm going to come under my OnCreate method.
06:10 Now this is going to be of type AmazonGamesCallback, and again, up there
06:16 I've referenced it as Game callback is equal to new, and then when we do that it
06:21 essentially is going to implement two methods here, onServiceReady and
06:27 onServiceNotReady. And this is pretty self explanatory, this
06:34 is going to call back and tell us whether it was successful or not.
06:39 If it was successful then we can begin to use the features If it's not then we're
06:43 going to have to handle that response in some fashion.
06:47 Okay, so what we're going to do in the onServiceReady is we need to now
06:51 initialize these clients right here. So the AchievementsClient,
06:56 LeaderboardsClient and WhisperSyncClient. In a way we do that is, lets go to
07:01 acClient and we're going to set it equal to gameClient.getAchievementsClient and
07:08 its going to be the same exact thing for the other 2.
07:16 This one will be leaderboard client. And this'll be
07:28 gameClient.getLeaderboardsClient. And lastly, the WhisperSyncClient.
07:30 And we just need to, say, getWhisperSyncClient.
07:32 So now with these actually set up, now we can call from anywhere in our game.
07:37 To implement any of these different features using these different clients.
07:42 But basically if the service was not ready then essentially you're going to
07:46 have to have the user play their game kind of offline, and not be able to
07:50 submit scores and things like that. So, but it's up to you what you do if the
07:56 on service not ready gets called. Okay so with that finished, I'm now
08:02 going to save it, and I have my emulator running, and we're going to publish this
08:05 out to the emulator, and remember that on the developer portal, you need to add the
08:10 game circle nicknames of the users who are going to be testing your application,
08:14 and I'll show you how to retrieve that. So let's go ahead and build this.
08:23 And let me go over to the Emulator. And it's launching up, and we should see
08:29 in a second. Here we have this UI, because this
08:33 account that I'm using, I haven't used Game Circle before.
08:38 So, you have two options, you can either use the random one that it created for
08:44 you which is, fresh, serene, voice that doesn't sound too good to me.
08:51 So I'm just going to say, Brimlee, and I have to use the virtual keyboard here, in
08:58 the emulator. Well it needs to be more characters,
09:04 Brimleegamer. That sounds pretty good.
09:10 And I can also go through it and choose my avatar.
09:16 I'll just keep it as that. Now, again, it's important to know what
09:19 your game circle nickname is because you're going to have to add it to the
09:24 developer portal. So, mine is going to be Brimleegamer, and
09:29 I'm going to click OK. And now it's telling me what my game
09:35 circle nickname is. Do I want to add Facebook friends?
09:39 Not right now. Okay.
09:41 So now, we've created that nickname. So now what we need to do is to go into
09:46 the browser to the developer portal and actually add that nickname.
09:52 Okay. So let's go back over.
09:54 And now I'm going to open up my browser. And here I am on the Game Circle page for
09:59 my application. So what I want to do now is to click on
10:03 Sandbox. And this is going to allow me to actually
10:07 add nicknames of people who are going to be able to test the application.
10:12 So if you want to add multiple people so they can try out your game, and see how
10:15 it works with Game Circle, you can do that.
10:18 I'm going to click Add New, and then for the Game Circle nickname it's that one
10:23 that I actually created in the Emulator. Brimleegamer, and click Add.
10:33 Now if you actually have a Kindle device and you're using that for development,
10:37 again, the only thing you need to do is to go into the Games Tab on your device
10:41 go to the Menu button, and then essentially setup your profile.
10:47 And that's where you can set your nickname as well as retrieve it later, if
10:51 you have forgotten about it. Okay, so let's go back to Eclipse.
10:55 Now what I'm going to do, I'll just change something, so it's going to
10:59 reinstall the application on the emulator.
11:02 Now if everything goes as planned, when the game launches, it should actually
11:07 display a little overlay, letting me know that it's connected to Game Circle.
11:13 So let's wait for that. The app is launching.
11:16 And here we can see this little overlay. And that's now meaning that I've
11:21 successfully connected to Game Circle. And again, if you're getting an error on
11:26 this, you want to look into logcat. If we go back to logcat, you can see
11:31 there's a lot of information from Amazon about this stuff, so you can come in
11:36 here, here's one, is authenticated exited with true so there's a lot of
11:41 information. And it's pretty easy to find out if you
11:47 have errors. But, again, the main errors that could be
11:50 there are both the white listing of the binary.
11:54 And having the correct nickname inside of the developer portal.
12:00
Collapse this transcript
Implementing the leaderboard
00:00 Now, when you load this code in, there may be one or two lines that look
00:03 different than from what you're seeing on the screen right now and that's because
00:06 I've since updated this code. 'Kay, so now we have our GameCircle
00:11 client set up as well as all the clients for the different features like
00:15 achievements, leaderboards and Whispersync.
00:20 So now, let's actually implement our leaderboards.
00:23 So I'm going to go to the spinit.java file, and this is the first activity the
00:27 user sees with just the logo and the two buttons.
00:33 And obviously, we have this View High Scores button click event.
00:37 Now, what we're going to do when this is clicked is just to display the global
00:41 leaderboards to the user. So, we're going to go to our leaderboard
00:47 client, so, since it's public static, we're going to say App.lbClient, and
00:51 we're going to go to showleaderboardOverlay.
00:56 And now it's expecting the leaderboard ID, and remember, that's the string that
01:02 we used inside of the developer portal when we created the leadrboard, and it
01:08 was high_scores. Now, this second parameter, you can just
01:14 get rid of, we don't need that. And that's all it takes, so with that one
01:18 line of code we're actually going to pop up the GameCircle UI and show the high
01:21 scores for this game. So let's go ahead and run that.
01:27 And again, I have my emulator running, so let's go back over to it and we'll see if
01:31 it works. So it's launching up, I get my little
01:35 overlay letting me know that we've successfully connected to GameCircle.
01:41 I'm going to click on View High Scores. And here, you can see the GameCircle UI
01:46 has popped up, and we can see the leaderboard hauled high scores.
01:51 And again, this is pulling this information from the items that we put
01:55 into the developer portal. So these are the high scores.
02:00 Now there, obviously haven't been any high scores yet, that's what we're
02:03 going to do next. But I did just want to show this
02:06 GameCircle UI that pops up. So here is a leaderboard.
02:11 There's one leaderboard for this game. We have an achievement.
02:14 And here, we can see that locked icon. And essentially, the achievement is once
02:19 you get beyond a thousand dollars. And we can also look to see who our
02:24 GameCircle friends are. Obviously, since I just created this
02:29 account, I don't have any. But, in essence, this has now worked.
02:33 So we successfully were able to launch the leaderboards.
02:39 Okay, so let's go back to the code. Now, the next place we're going to be
02:43 working with this is in the GameOver class.
02:47 And again, that's the activity that gets launched, once essentially, you lose all
02:51 your money. So what we're going to do in here inside
02:55 of our onCreate is we're going to get the score out of the Intent.
03:00 Because remember, in the game class, once the game is over, we actually put the
03:05 highest score that they reached into the Intent that we used to launch this
03:09 activity. So I'm going to create a field called
03:14 score and then we need to get the intent, we just use the getIntent method, and
03:21 then we want to say getIntExtra. And now, the string name that we defined
03:29 for that, which is score, and then the default value would be 0.
03:35 So let's go ahead and define that as a field.
03:39 So now, we have the score. And again, the way the game works is you
03:43 build up and build up and build up. And then, if you land on one of those
03:47 pieces that says you lose it all, essentially, it records what level you
03:51 get to before actually setting it to 0. So that's what we have retrieved right
03:58 here. So now, we want to come down to or we can
04:00 come to the View Leaderboards button click event here, because that's
04:04 essentially the same exact thing that we did in the Spin It class.
04:10 So, I can actually come into here and just copy and paste this line.
04:16 And again, this is just a place where you can click to actually view the
04:20 leaderboards. Okay, so, now how to submit scores to the
04:25 leaderboard. So, that's going to be in the submitScore
04:29 ButtonClickEventHandler here. And what we're going to do first is to
04:34 check if the score is 0, if you actually try to submit a score of 0.
04:39 I've gotten errors when I did that, and why would you anyway, because that's not
04:44 much of a high score. So I'm going to say if score is grater
04:49 than 0, then we can proceed. Okay, so now, to actually submit the
04:54 score, we're going to be using that leaderboard client again, so it's
04:58 App.lbClient, and then we want to call the submitScore method.
05:04 Now, the first thing it's expecting again is that leaderboard ID and it's
05:11 high_scores. Now, the next thing is the actual score
05:17 that we want to submit, and again, we extracted that from the Intent, and it's
05:21 in that score property, so we can leave it like that.
05:26 Again, this user data, we can get rid of that, that's just if you want to pass
05:30 some data to the callback function. We don't need that.
05:34 So now, with that method signature, we're then going to say dot, and we're going to
05:40 say setCallback. And now, inside of here, we're going to
05:45 say new AGResponseCallback. And when I do that, again, it's anonymous
05:52 inner callback function here. And inside, there's just a single method,
05:57 called onComplete. And that's essentially going to tell us
06:00 whether the score was successfully submitted.
06:04 So what we're going to do is to test for that.
06:07 So it sends a result object back to us, and I'm just going to say if
06:11 result.isError, that obviously means something has gone wrong.
06:17 Again, you can handle that any way you want, I'm not going to do anything with
06:21 that. Now, if when you submit your score, if it
06:25 is the high score, then a little toast notification will pop out and let you
06:30 know that you now have the high score. Now, if it's not your high score, it's
06:37 not going to show anything. But what I'm going to do is just to make
06:40 a little toast message that just says score submitted.
06:44 So I'm going to create that else block, and, so we know if we come into else that
06:48 the submission was successful. So I'm just going to use the Toast Class
06:55 and I'm going to call makeText. And for context I can just say,
07:02 getApplicationContext. For the text, I'm just going to say Score
07:09 submitted. And the duration to show it, we want to
07:14 say Toast.Length Long. And then we want to chain onto the end of
07:19 that and call the Show method. Again, even if they haven't made a high
07:24 score, just let them know that the score actually was submitted.
07:30 It just isn't the high score. Okay, so I'm going to save this now and
07:34 I'm going to run it again. It's going to go out to the emulator.
07:39 And this time, I'm actually going to play the game to show you how that works.
07:45 So let's go over and let it launch up, and again, we get the overlay and we're
07:49 going to start playing the game. So I'm going to spin the wheel, well,
07:56 that was obviously bad. Let's try one more time.
08:02 'Kay. So there is a $100.
08:03 So remember, there are no high scores for this game yet, because I just created it.
08:09 So I'm going to use our little shortcut where we can just click on the wheel.
08:12 Now, it's important to note, you can submit the score from anywhere in your
08:16 game. You can automatically submit it.
08:19 This is actually a simple kind of example where after your game is over, you can
08:23 choose to submit your score. So what I'm going to do now is to click
08:28 Submit Your Score, and you see this little pop out, New High Score.
08:34 And also, you saw the toast message down there essentially telling me the score
08:39 was submitted. So I'm going to play again, and this time
08:43 I'm just going to use that In-App purchase, just to buy a $1,000.
08:48 So I'm going to cheat a little bit here, and I'm going to click Again, and I'm
08:52 going to submit my score. And again, it pops out, I have the new
08:58 high score. And now, I can also View Leaderboards,
09:02 and now, it's going to pop open the GameCircle UI and load in the
09:07 leaderboard. And you can see, for me, I have the top
09:12 score of $1,000. And again, you can have multiple
09:16 nicknames or have like your friends be testing the application, so you can see
09:21 multiple scores in here. But it's just that simple to actually set
09:26 up the leaderboards. Again, to display leaderboards, it's just
09:31 one line of code. To submit scores, you just need to use
09:35 the submitScore method and then get this call back.
09:39 And again if it's the high score, the Kindle UI for GameCircle will actually
09:43 come out and let the user know that they got the high score.
09:49
Collapse this transcript
Implementing an achievement
00:00 So, now that we've implemented our leader boards, let's turn our attention to the
00:04 achievements. Now, remember we defined one achievement
00:08 for our game and that's when the user reaches over $1000.
00:13 So, we're going to start in game.java. And what we need to do is to create a
00:19 function. And I'm going to call it Check
00:23 Achievements. And essentially, anytime the score is
00:26 updated in the game I'm going to call this method to see if they have actually
00:31 achieved that achievement. And if they have, then I'm actually going
00:37 to call out to the achievement client that we created and set the achievement
00:41 for the user. So, I'm just going to come under on
00:47 create here. And I'm going to say, private void
00:51 checkachievements. The first thing I'm going to do in this
00:56 function is to check whether the score is greater than or equal to 1,000.
01:03 If it is, then obviously, I'm going to give them that achievement.
01:09 So, I'm going to say, if(score >= 1000). Now, to actually submit the achievement
01:16 to these achievement client, we'll first going to go to that client.
01:24 Again, it's in our App class and its called acClient.
01:31 And now, we're going to go to the updateProgress method.
01:35 So, the way in which this method works is that you actually pass in the percentage
01:40 complete, of how close they are to achieving that particular achievement.
01:46 But in our case, we're just testing for if it's greater than or equal to 1000.
01:51 So, obviously, we're going to pass in 100% because they've reached their goal.
01:56 But if, like in a game, you, you know get to 50,000, you can calculate at certain
02:00 points, like when they close the game, and update their progress using this
02:05 percentage. So that when they go to the achievements
02:10 UI, it will actually tell them their progress.
02:13 So, for the achievement ID, that's the ID we created on the Developer Portal for
02:18 the achievement, and it's just called 1K. Now again, for percent complete, for us,
02:25 it's just a simple, as soon as you get over 1,000.
02:29 So, I'm just going to pass in 100% like that.
02:33 And again, we can get rid of this user data parameter.
02:39 And now, I'm going to say .setCallback. And, I'm going to say new
02:46 AGResponseCallback. And we can see, again, much like we did
02:52 in the last movie, it's automatically created an anonymous inner callback here.
02:59 And it has a single method, called on complete.
03:02 And that's essentially going to allow us to check to see if there was an error.
03:07 So, again, all I'm going to do is to say if(result.isError).
03:11 Then, I know something has gone wrong. And I can do some type of error handling
03:18 here or just let it to degrade gracefully.
03:22 Okay, so that's our check achievements method completed.
03:28 So now, we want to call this method from two places inside of this file.
03:33 First is in our PreferenceChangedListener, because
03:36 remember, if they use the In-App Purchase to buy more money, we need to detect
03:41 that. And once it comes inside of here, we need
03:46 to call check achievements to see if they're actually over 1,000.
03:51 Now, they've actually bought a $1,000 of in-game currency.
03:54 So, of course, this is going to be true. But again, this is a, just a simple
03:58 example. The other place is in the calculate
04:02 result method. So, if we come down here, you can see
04:06 that if they landed on negative 1, then obviously, the game is over.
04:10 But I'm going to come down here, under where we increment the score, and I'll
04:15 just, again, call check achievements. So, if that score goes over 1,000, then
04:21 we're going to actually call to the achievements client, and update the
04:25 progress and reward the user with that achievement.
04:30 And again, you can update the progress of these achievements from anywhere.
04:35 I'm doing it in a, you know, a really simple manner.
04:38 But you can be submitting to the leader boards sending progress towards
04:42 achievements from anywhere throughout the game where you think its necessary.
04:47 All right, so I'm going to Save this file now.
04:50 And I'm going to run it. And again, it's going to launch over on
04:55 the emulator, so let's go over there. Okay, so it's launching up.
05:01 And it should, and there, we have the little overlay.
05:06 So now, I'm going to play the game. Now, I'm going to try to get to a
05:10 thousand or over legitimately rather than just buying my way to the achievement.
05:16 So, I'm going to click Spin the Wheel, 650.
05:20 So, that's pretty good 900, so this could be it.
05:27 And there we go. So now, you can see its automatically
05:31 popped out as little toast, letting me know that I have earned that achievement.
05:37 So now, if I end the game and I go to View Leader Board, this is going to
05:41 again, pop open the GameCircle UI. I can click on the Achievements tab.
05:47 And you can see the text has actually changed to You Did It.
05:52 because remember, there's two versions of the text.
05:55 One for locked and one for unlocked. And now, the icon has actually changed to
05:59 be without the padlock. So now, I've earned that achievement.
06:04 And it's really just that simple. Again, you can have all kinds of
06:07 achievements for different things like getting to a certain level, a score you
06:11 know, reaching a certain amount of money. I mean, it's really up to you, how you
06:16 use this. But as you can see, it's very simple to
06:19 implement. Again, the actual submission to the
06:23 achievement client is essentially just one line of code.
06:28 You just update the progress. So, that's achievements in a nutshell.
06:33
Collapse this transcript
4. Using the Amazon Maps API
Setting up the Amazon Maps API
00:00 So if you use a Kindle device, one of the things you don't have access to is Google
00:04 Maps, because it's not available on the Amazon App store.
00:09 Well luckily, Amazon also has a maps API. It's extremely similar to the Google Maps
00:16 API, which makes it very nice if you're familiar with the Google Maps API, and
00:21 it's also really easy to port an application using Google Maps, to Amazon
00:26 Maps. So, we're not going to try to incorporate
00:31 maps into the Spin-it application so let's just go ahead and just create a new
00:36 app. I'm just going to put in the bare bones
00:39 here. Amazon, Maps.
00:45 I'm just going to do what's required. Tablet, category, we'll just say Cooking.
00:50 Doesn't really matter. Use default support information, and
00:54 click Save. So now, at this point, if we go to this
00:58 Maps link, you can see that it says this app has no registrations.
01:06 So when you want to actually test the Amazon Maps API, locally during
01:10 development, you need to add a Debug Registration, and we'll get to this in a
01:14 little bit. But it's essentially going to be the
01:19 package name of your application, as well as the MD5 fingerprint for your key
01:23 store. Very similar to what we had to do with
01:27 Game Circle. Alright, so I'm going to go into Eclipse,
01:31 and we're just going to create a brand new project, New Android App.
01:37 And, I'm going to call it Amazon Apps. That's the project name for the package
01:45 name. I'll just keep it short.
01:48 Com.lee.maps, and I'll leave everything here at the default.
01:53 Well, let me actually well I'll change that later on.
01:58 We'll click Next. I'm not going to create a custom icon.
02:02 We'll create an activity, click Next. It's going to be a blank activity.
02:07 Navigation type None, and we'll click Finish.
02:14 And here it is loading our main layout XML file.
02:20 So the first step is to actually include the Amazon Maps Library, into your
02:25 project. So I'm going to right click on the
02:28 project, go to Properties, Build Path, and then under Libraries, I'm going to
02:32 click Add External Jars. And from here, I'm going to go into the
02:38 Amazon SDK, to Maps, to Lib, and then I want to grab that Amazon Maps Jar.
02:44 Now unlike the other two, we're not going to come here and actually export
02:49 them and put them into our Libs folder because, this Jar only contains stubs of
02:55 the actual APIs. Doesn't contain the full implementations.
03:01 So you're going to get a bunch of errors if you include that, and export it with
03:04 your project. Okay, so one last thing is, I'm going to
03:08 go back to libraries. And let's just link up the Java docs.
03:13 So I'll browse to that location, to documentation, API reference, and we need
03:20 to click on Reference, click Open, OK, and then OK.
03:27 So now essentially, we are set up to begin development for maps.
03:33 But like I mentioned before we're going to have to actually register on the
03:38 Developer Portal, in order to actually see any Map Tiles, in our application.
03:45 So what we're going to need to do, is to generate that MD5 Fingerprint, of our
03:50 Debug Keystore. So let me minimize this, and I'm going to
03:54 open the terminal window. Now, in the chapter about Game Circle,
03:59 where we had to white list our binary, this is going to be almost the same exact
04:04 thing. And for people who are viewing this that
04:08 are developing on Windows, look back to that tutorial on white listing a binary
04:12 for Windows, because, essentially, it's going to be the same exact work flow.
04:18 So again, we're going to be using key tool.
04:20 And we're going to say, dash V, dash List, and then we're going to give the
04:27 Alias, which, again, for the Debug Key Store is Android Debug Key.
04:38 Now the next thing we need to provide is the location of the Key Store.
04:42 And like I mentioned before in that other tutorial on Mac, it's usually always on
04:47 your User Directory, in a folder called dot Android.
04:52 But, I'll just show you this again, that you can always find out by going into
04:56 your preferences, in Eclipse, and go to Android, Build, and it will give you the
05:01 location of that Debug Key Store. So I'll just copy that, and I'll paste it
05:09 in. And, now we're just going to run this.
05:15 Now, you can see here it's asking me for a password.
05:17 And again, if it doesn't that means you probably put in the wrong path to your
05:20 key store. So the password is always android, and
05:24 we're going to run it, but the piece of information we want is actually this MD5
05:30 fingerprint. So we're going to copy that, and go back
05:35 over to the Developer Portal, and click Add a Debug Registration.
05:41 So I'm going to paste in that fingerprint.
05:45 And then we need to give our package name for our application.
05:50 And again, you're not going to want to use the same one that I did, it needs to
05:54 be unique so, definitely create a unique package name for your app.
06:00 So for me it was com.lee.maps, and now I'm going to click Submit.
06:08 And now you can see that the application has now been registered, and it's active.
06:13 So now, what that means is, as I'm testing, I'm actually going to be able to
06:17 download map tiles, which of course are very important, if you want to test a
06:21 maps application. So again, if you're on a Windows machine,
06:27 definitely look back at that white-listing binary for Windows
06:30 tutorial, in the Game Circle chapter, because that command line thing is almost
06:35 identical to what we did there.
06:39
Collapse this transcript
Building and testing your maps app
00:00 Okay. So, now that we've set up our environment
00:03 and actually registered on the Developer Portal, we can start implementing our
00:07 maps API. So, the first place we have to start is
00:11 in our Manifest File. And the first thing we need to do is to
00:15 actually include the Amazon name space. So I'm going to copy the Android1, paste
00:20 it in and just change that to Amazon, and then also here at the end, like that.
00:21 Now the next step is to actually enable the map feature.
00:21 And we're going to use the Amazon name space to do this.
00:42 So, I'm just going to come under here, say, amazon:enable-feature.
00:49 And then we're going to say android:name is equal to.
01:00 So now, we give the actual package name of the Amazon Map API, and it's
01:07 com.Amazon.geo.maps. Now, we're going to add another attribute
01:15 here. We're going to add the required
01:19 attribute, and we're going to set that equal to false.
01:26 And the reason we do that is just in case the map feature for some reason is not
01:30 available, this will degrade gracefully. So, much like Google Maps, we also need
01:37 to define some permissions in order to make the maps work correctly.
01:44 So, I'm going to create a Uses Permission and the name of this permission is going
01:50 to be Android Permission ACCESS, COURSE, LOCATION.
01:57 And if you're doing anything with maps, you're going to also want to include the
02:03 Find Location Permission as well. It uses just two different ways of
02:10 essentially finding your location through different sensors either WiFi or the, you
02:16 know, 3G network, or whatever. Now, the next one we need to add is
02:22 actually the Internet Permission because obviously, you're going to need internet
02:28 access to download the map tiles for the map.
02:33 Okay. So, those are the three permissions that
02:37 we need to ask for. Now, for the minSdk version, when I
02:42 created the project, I just left it at the default so we actually want this to
02:50 be 15. And for a theme, let's just use the same
02:56 one that we been using in the SpinIt project.
03:01 So, we'll go to Style and then theme, and then the one we've been using is
03:07 DeviceDefault NoActionBar, and we'll make it go Full Screen as well.
03:15 Okay. So, that's how you set up your manifest
03:17 file for using Amazon maps. Again, we need to enable the feature here
03:22 and then also ask for these three permissions in order to get things
03:26 working. So, I'm going to close this file now.
03:32 Now, let's focus on our Main Layout file and we only have one activity, activity
03:37 main. And if we look at it here under Graphical
03:41 Layout, we can see it simply contains a Text View so let's go ahead and delete
03:46 that and we're going to replace it with our Amazon Map View.
03:51 So, I'm going to come down here and we need to put in the full package path to
03:56 it. But it's com.amazon.geo.maps.MapView, and
04:04 that's the MapView class that we're going to be using.
04:11 Okay. So, let's go ahead and create an ID for
04:15 it, so it's going to be @+id, and I'll just call it MapView.
04:21 The next thing we want to set is Layout Width and Height.
04:25 Well, I'm just going to copy and paste it from here.
04:27 We're just going to choose Match Parent, and that's essentially going to fill the
04:31 entire window with our map. Now, another thing we need to do is to
04:36 make sure that the MapView is clickable, so that it will receive, well, not mouse
04:40 events, but it would be normally touch events so you can interact with the map.
04:47 So, I'm going to set the clickable property equal to true.
04:52 And then, we can go ahead and close this tag.
04:56 So, pretty simple, our Main Layout is just going to be the MapView filling up
05:00 the entire screen. Okay.
05:03 So, let's go to our Java file now, and it's called mainactivity.java.
05:10 So again, just like the Google Maps API, if we want to display a map, we need to
05:15 have this class extend map activity not a regular activity.
05:21 So, I'm going to extend map activity and you're going to see here, it's going to
05:26 ask me to implement some methods. I'm going to do that.
05:31 It's put this isRouteDisplayed. And again, there are certain parts of the
05:36 Google Maps API that are not supported in the Amazon Maps API.
05:40 But they've actually included the API call so that it makes it really easy for
05:44 you to transition from a Google Maps project to an Amazon Maps project.
05:50 So, we're going to need this in here. I'm going to get rid of this on Create
05:55 Options menu. And now, we can start working with it.
05:59 So, the first thing I'm going to do is to get a reference to that MapView.
06:04 So again, this is going to be of type MapView.
06:07 I'll call it map is equal to findViewbyID and that's going to be R.Id.MapView, and
06:17 we'll add the cast to MapView. So, this is our main map object and now
06:25 we can start working with it. So, the first thing that we're going to
06:30 do is set it so we have some built-in zoom controls.
06:34 Now, on a device, you don't really need that because you can Pinch and Zoom to,
06:38 to Zoom in and out. you can just swipe around with your
06:42 fingers. But when we're running on the Emulator,
06:45 it's definitely going to help us to have those.
06:48 So, I'm going to call map.setBuiltInZoomControls and pass in
06:53 true so that it displays those. Okay.
06:58 So now, at this point, we can actually test it on the Emulator.
07:04 So, before I do that, let me bring up the Emulator.
07:07 So, one of the things we need to do on here is to enable location services
07:11 because I'm going to show you actually how to navigate to your current position.
07:17 I'm going to show you how to do it if you pull this down, go into more.
07:22 And there's a section called Location-Based Services and you just want
07:27 to turn that on, and that way, you're going to be able to determine your
07:31 location. Now, we're going to be faking it on the
07:34 Emulator. But still, that's how you would test it
07:38 also on an actual device. Okay.
07:41 So, I'm going to go ahead and publish this now out to the Emulator, and we can
07:47 see it's put it on my desktop here, and now it's loading up.
07:54 And you can see already that it's working properly.
07:58 Now, if you're not seeing map tiles here, it's more than likely the fact that you
08:02 haven't properly registered on the Developer Portal, where you had to put in
08:07 your package name and MD5 fingerprint. So, make sure that those pieces of
08:13 information are correct. So, if I click here, you can see, it
08:18 gives me these Zoom controls and I can interact and Zoom around on this map, and
08:22 I can Click and Drag. So, you know, this looks awesome on an
08:28 actual device but it's pretty limited here in the Emulator.
08:33 So ,another object we're going to need to create is the Controller or the
08:37 MapController. So I'm going to create a new instance of
08:43 MapController, and I'll call it controller is equal to map.getcontroller.
08:52 And this controller, again, if you've used the Google Maps API, this is how you
08:55 actually, you know, move the map to a certain location, control the zoom, and,
08:59 and all types of things. So, one thing we're going to do with it
09:02 right is to set the zoom of our view. And again, this is an integer between 1
09:04 and 21, 21 being zoomed in the most. So, we're going to set it to, let's set
09:16 it to 19. So, when we launched it the first time,
09:26 it actually went to the last known location that was on the Emulator.
09:31 Now, we can actually use the Emulator Control panel to put in any destination
09:36 we want, so that it appears like we're anywhere we want to be.
09:41 So, we're going to do that real quick. I am going to come to Google Maps and I
09:48 am going to search for Time Square. let's pick that one right there, and now
09:55 it's going to show me Times Square. Now in Google Maps here, I can
10:01 right-click and click what's here and then it immediately puts the GPS
10:06 coordinates here inside of the search box.
10:11 So ,I am going to copy first this longitude and go back to eclipse into
10:16 DBMS and then you want to bring up the Emulator Control panel.
10:23 Now, I am going to paste that first value here into latitude, so these are actually
10:29 latitude and longitude values. And I am going to copy this one and I'll
10:36 paste that into longitude. And now, I can click Send and that's
10:42 essentially send that location to the Emulator.
10:47 So, the next time I want the application, it should actually display the location
10:52 of Time Square. So, how do we actually set that up?
10:57 So, what we have to do is to create an instance of the MyLocationOverlay class.
11:03 So, MyLocationOverlay, I'm going to say, me is equal to new MyLocationOverlay.
11:14 And for context, we can just say this. And for MapView, we want to use map.
11:19 So, this My LocationOverlay is an actual visual overlay that will show you where
11:26 you currently are on the map. So, we want to add it to the current
11:32 overlays that are on the map. So to do that, we say, map.getoverlays.
11:42 And then, we chain a call onto that to add a new overlay, and we to add that me
11:46 overlay we just created. And that will visually show us a little
11:52 icon where we are. Now, the next thing we need to do is to
12:01 enable my location. So, we do this on this overlay.
12:07 So, we say me.enablemylocation. And that basically means that it's going
12:11 to set this up so that I can recieve location updates and, you know, create an
12:15 application where it's following wherever I am, showing me where I'm going, things
12:19 like that. But now, we need to actually move the map
12:25 to the location of where I am. And for that, were going to use the
12:30 controller object and I'm actually going to animate to this point, just so
12:35 it's a little bit cooler. And to get the actual Geo Point, we're
12:40 going to say, me.getmylocation and that's going to get my current location.
12:46 Now, in this case, on the Emulator, since we fed in those fake coordinates, it's
12:52 going to think that I'm in Times Square. So, let's go ahead and save this, and
12:59 let's relaunch it again, and see how it looks.
13:04 Now, I'm only showing you just a small amount of the APIs available.
13:08 But again, if you're familiar with Google Maps API, it's basically the same thing.
13:14 So here, you can see we have our little indicator showing us where we are, it
13:18 looks like we are in New York, so I think we got pretty close.
13:22 If I keep going in well, it's hard to tell here so let me introduce another
13:27 thing that you can do which is to change between the regular map and satellite.
13:34 So, we can say, map.setSatellite to true, and then we're actually going to see a
13:39 satellite image rather than the regular map.
13:44 And, of course you could create some UI in your application to be able to toggle
13:48 between the two. So, let's launch it one more time, let's
13:53 see if we can recognize Time Square, and it should be pretty accurate.
13:59 So, it's launching up. And you can see those tiles are starting
14:03 to load in, and that looks pretty accurate.
14:07 Let me Zoom in a little bit. And, yep, so that's Times Square.
14:18 So, you can see, you're able to feed in coordinates using the Emulator control so
14:22 that you can test out the ability to get your own location.
14:27 So, that's it for the Maps API. Again, it's essentially like using the
14:32 Google Maps API, but the most important part is to make sure you get that
14:36 registration correct on the portal with the package name and the MD5 fingerprint.
14:44
Collapse this transcript
5. Multiscreen Development
Overview of multiscreen development
00:00 So in our application we're actually targeting 3 different Kindle devices and
00:04 each has a different size and a different pixel density, so it's really important
00:09 that you have a good understanding of how multi screen development works with
00:13 Android. And the main thing is again, the
00:18 relationship between the actual screen size.
00:21 And its pixel density. So let's look again at the actual
00:26 specifics for each Kindle device that we're going to target.
00:31 So first is the Kindle Fire second generation.
00:35 Now the physical screen size is 1024 by 600, and that's obviously, in landscape
00:40 mode. Now the general density, which is the way
00:45 Android classifies devices into buckets based on their pixel density, is 160.
00:53 But it's important to note that that's not the actual pixel density of this
00:57 device. The actual density is 169.
01:01 But essentially you know, we're going to be treating it as if it's 160.
01:05 And 160 is also the baseline pixel density.
01:10 So if we move to the Kindle Fire HD 7 inch, this has a screen size of 1280 by
01:15 800 Now the general density is 240, which moves it up into the HDPI category.
01:24 And that just stands for high DPI. The actual density of the device though,
01:29 is lower than that, it's actually 216. Now the Kindle Fire HD 8.9, has a screen
01:37 size of 1920x1200. Now the general pixel density is actually
01:43 the same as the 7 inch, so it falls into that HDPI category, which is Average to
01:49 be 240, but the actual pixel density of the device is actually 254.
01:56 So you can see there's quite a, a large difference between the seven when it
02:00 comes to their actual pixel densities. So now let's just make sure we have a
02:05 good understanding of density independent pixels.
02:07 So you can see that snippet at the top looks familiar.
02:11 That was pulled out of one of the layout XML files.
02:14 So, in android development its recommended that you use density
02:19 independent pixels. You put dp in essence after the value
02:24 rather than px for pixels. Because using these dp values Will ensure
02:30 that whatever element you're using these sizes on will take up the same amount of
02:35 physical space regardless of the pixel density of the device.
02:41 So it's definitely recommended that you use dp, and there's almost no case where
02:45 you're actually going to be using real pixel values.
02:49 Now it is also recommended if you can To avoid giving specific dimensions at all.
02:55 So, you can use things like relative layout, where you can position elements
03:00 relative to one another, to, you know, the edges of the screen and you can make
03:05 your UI adapt nicely goes up to a higher DPI device.
03:11 You know, that sounds great, but there definitely are still places your going to
03:16 be using actual dimensions, you just want to make sure you use density independent
03:21 pixel values. So let's look at the Android DPI
03:26 Qualifiers. And these are the buckets that Android
03:29 has put. Various devices into based on their
03:34 densities. So here we can see, at the top, a range
03:38 of densities. starting at 100, going all the way up to
03:42 300. Now underneath, you see those 4 buckets.
03:46 So if the actual pixel density of your device falls within one of those
03:50 categories. That's how you're actually going to
03:55 provide the correct graphic or layout file for the device.
04:00 Now, when we're talking about the 3 devices that we're going to be targeting.
04:05 The first is 160. And that's the Kindle second generation.
04:10 it has a general pixel density of 160. So again, that's going to fall into the
04:17 MDPI category. And the other is 240 which is HDPI.
04:22 that is the 7 inch and the 8.9 inch. But remember, that the actual densities
04:28 of the two devices are not the same as the 8.9 is actually considerably larger.
04:34 So how do you provide alternate resources, again this course assumes you
04:38 know android development, so you probably are aware of this already.
04:43 But essentially we can create multiple folders for both drawables, layouts, and
04:50 other things as well. And the android system will automatically
04:57 pick the correct resource based on the DPI of the device.
05:03 So since we're targeting Kindle devices, we're going to be using this approach by
05:09 providing different graphics and layouts for each device.
05:16 That it's really helpful to know how to do, is how to convert actual pixel values
05:21 into DP, or density independent values. And we're just going to use an example of
05:28 the, the Kindle HD 7 inch, again which has a general pixel density of 240.
05:35 So first you divide the DPI of the device by the baseline density of 160.
05:43 So again, 160 is considered to be the base.
05:47 So if we divide 240 by 160 we get 1.5. Now, divide your pixel value by that
05:55 result, 1.5, and that will convert your pixels into a dp value.
06:03 So let's say I created an image in Photoshop that's 340 pixels.
06:07 Well to figure out what that's going to be in density-independent pixels, all I
06:12 have to do is just divide it by 1.5, and that equals 227 device-independent
06:17 pixels. Now, to go the other way, you simply just
06:23 want to multiply your DP value by 1.5 to go back to pixels.
06:29 So again, 227dp times 1.5 equals 340 pixels.
06:35 So understanding this conversion is really going to help you when it comes
06:40 time to providing alternate assets for different devices.
06:45 So a few other considerations, so in our game the one we're building we're forcing
06:49 it to stay in portrait mode. And this is true for most games, they
06:54 either run in portrait or landscape mode. You can't go in between, you know they
07:00 don't have two different modes. But if you have an application that will
07:04 work in both modes, you need to make sure that things adapt well when the user
07:09 switches between portrait and landscape. And sometimes you going to want to
07:15 provide alternate layout files for landscape and then a different one for
07:19 portrait. Now, you can also provide alternative
07:24 resources for physical screen sizes. This is actually depending on the actual,
07:28 physical screen size of the device rather than the pixel density.
07:33 And remember to also consider the differences between normal and
07:38 full-screen modes. And later in this chapter, I'll actually
07:41 be talking more about that. Just remember that your screen real
07:45 estate is going to be different based on whether you're in full-screen or in a
07:50 normal mode, where the Kindle title bar and menu bar at the bottom will be
07:54 showing. So that's an overview, and in the next
08:00 movie I'll show you how you can go about creating different versions of graphics
08:05 for each of the three devices.
08:09
Collapse this transcript
Creating multiresolution graphics
00:00 So, in the last movie, I gave you an overview of how to approach multi-screen
00:05 development for Kindle and for Android in general.
00:09 So, now we're actually going to put it into practice.
00:13 And in this move, I'm going to show you how to create different size graphics for
00:18 different pixel densities. because remember, we have those three
00:23 devices that we're targeting. So, I'm going to go into my Layout
00:27 folder. And I'm going to go to the Main Menu
00:31 screen. And let's go back and show it in Kindle
00:36 Fire HD 7-inch. Now, when I was developing the
00:41 application, I was using the 7-inch device as my target because that's the,
00:46 the device that I actually own. So now, to actually correct it and to
00:52 also support those other devices, I need to figure out what I have to do to both
00:57 the graphics and the layout in order to make it consistent across all those
01:02 devices. So, let's take a look at what this
01:08 actually looks like on the 8.9 device. And you can see that everything is
01:12 essentially gotten smaller. Remember that the pixel density of the
01:18 8.9-inch is in the same category as the 7-inch which is HDPI.
01:24 So, in Android, we need to provide different graphic resources for the
01:29 different pixel density devices. So, what we're going to need to do is to
01:35 essentially create a new graphic for the 8.9-inch.
01:39 So, what we need to do is to create a new version of this logo.
01:44 It's going to look nice and sharp on the 8.9-inch.
01:49 So, one of the things we're going to do is to create a new type of drawable
01:52 folder. Because we can't just put the logo in the
01:56 HDPI folder, because again, both the 8.9 and the 7 are considered HDPI devices.
02:03 So, I'm going to create a new folder. Right click on Res, New, Folder.
02:10 And it's going to be called Drawable, still.
02:14 And in Android 3.2, they introduce some new ways to be even more specific about
02:20 creating folders to target certain devices.
02:25 And one of the things they did is, it will let you now, say, I only want to use
02:30 this graphic for screen widths that are this amount or larger.
02:36 And that's what we're going to do. So, we're going to create a folder
02:41 drawable-sw800dp. So, why 800?
02:47 Here, it's important to understand how wide your device is in density
02:51 independent pixels, not regular pixels that you're used to.
02:55 And you can take the actual pixel width and use that formula I showed you in the
03:00 last movie to convert it to density independent pixels.
03:06 So, for the 8.9-inch, it's actually 800 dp wide.
03:10 The 7-inch is 533 dp wide. And the second generation Kindle Fire is
03:16 actually 600 dp wide. So, it's important to know those values.
03:22 So, I'm going to create this folder. And now, essentially what this is saying
03:28 is don't grab the graphics from this folder unless the screen width is 800 or
03:33 larger in dp units. And this will essentially include the 8.9
03:40 device and exclude the other two devices. Okay, so I've created this logo graphic
03:46 to be the perfect size for the 7-inch device because that's the device that I
03:51 was working with. So now, I need to figure out how much
03:56 larger do I need to make the image for the 8.9 inch.
03:59 Well, I'm going to bring up a calculator, and I'm going to put in the screen width
04:05 of the 8.9-inch, which is 800, and divide that by the 7-inch width, which is 533.
04:14 And you can see, it pretty much comes out to exactly 1.5, or 150% larger than the
04:20 graphic for the 7-inch. So, I'm going to go into Illustrator.
04:26 And this is the original graphics file that I used to create the logo.
04:30 Now, here is where it's important to mention that when you're dealing with
04:35 mobile development, you want to try to always create your assets as vectors.
04:41 that way, you can easily scale them up or down, you know, for different devices.
04:46 Because who knows what device is going to come out next, with some crazy size and,
04:49 and pixel density. Now, I have actually included this
04:54 Illustrator file in the Excercise file. So, if you go to the Assets folder,
04:59 Artwork there's a Multi-screen folder and you can find this file, if you want to
05:03 play around with it. So, I'm going to to File, Save for the
05:08 Web. And you can see that the image that's
05:11 being used on the 7-inch is 426 pixels wide.
05:16 And in Illustrator, I can actually increase that by a percentage which we
05:21 just figured out is 150% of this width and height.
05:27 Okay, so now, it's going to allow me to save this.
05:30 And I'm going to be saving it, again, into resources and into that new folder
05:35 that I've created. And I'll click Save.
05:39 And then, let's jump back to Eclipse. So, it helps to just close the file
05:44 sometimes. And also, do a Refresh on your project.
05:48 Just so it actually picks up these changes.
05:51 Okay. So, I'm going to reopen it.
05:54 So now, you can actually see the new graphic on the Kindle Fire 8.9.
06:00 Now, you'll notice it looks a lot larger than the one on the 7-inch device.
06:05 And that's because again, numerous factors, this is a larger screen, but
06:10 then, also the DPIs of these two devices are not equal.
06:15 Again, they both fall into the general bucket of HDPI, but they're quite a far
06:20 apart in actuality. So, what I'm going to do is to go back to
06:24 the 7-inch. And again, every time I switch between
06:28 these, it's pulling out the correct logo for the, whatever device I'm actually
06:33 emulating here. So now, I need to figure out how wide is
06:37 this logo in density independent pixels. So, let me go back to Illustrator and
06:44 I'll just say Save for the Web again. And here, we can see the actual
06:49 dimensions, of our image. So, what I want to do is to convert that
06:55 value into dp units. And if you watched the last movie, you
07:01 know we're going to do 426. And then, we're going to divide it by
07:06 1.5. So, it's actually 284 density independent
07:11 pixel units wide. So remember, we also figured out that
07:17 graphics on the 8.9 should be 150% larger.
07:22 So, what I'm going to do is to multiply that by 1.5 and the value that it should
07:28 be inside of the 8.9 is 426 dp. So, let's go back here.
07:36 And let's go back to the 8.9 and I'm going to go into Layout Parameters.
07:43 Now, for width, I'm going to put in, let me actually just remember what it was,
07:50 426. And again, this must be for dp, device
07:55 independent pixels. And, you'll see, we now have sized it the
07:59 way it should look. So, if we go back to the 7-inch, you'll
08:05 notice that when I go back and forth the actual size is correct for both the
08:10 7-inch device and the 8.9-inch device. And again, the actual graphic that we're
08:18 using for the 8.9 is actually larger, which means it's going to look better on
08:23 that higher resolution screen. So now, what about the Kindle Fire second
08:30 generation? So, what I can do here is to go over into
08:34 the Amazon folder and look at it here. And we'll let it load up.
08:41 And you'll notice that things are not looking exactly how they should.
08:44 Let me turn this back to Wrap Content. And this is how the graphic that's in the
08:50 HDPI folder looks on the second generation Kindle Fire.
08:55 And it's pretty decent, actually. And we could potentially just use the
09:00 same graphic, but if I go back to the 7, we can see that the logo is larger than
09:05 it is on the second generation. So another way we can figure these things
09:12 out is figuring out the percentage of how much of the width this logo actually
09:16 takes up. So, remember in the 8.9-inch, it's
09:22 going to be 426 dp, and the total width in dp for this device is actually 800.
09:31 So, I'm going to go back to my calculator.
09:34 And I'm going to say 426 which is the width in dp units for the 8.9-inch.
09:42 now remember, this is 150% bigger than the 7-inch.
09:48 So, I can now actually divide this by 1.5.
09:52 And I can see that the actual dp units for the logo on the 7-inch is 284.
10:01 And what I can do now is to divide that by 533 which is the width of the 7-inch.
10:11 And then, I get, essentially, 0.5. And now, what I can do is to multiply
10:17 that by the dp width for the second generation Kindle Fire.
10:23 So, I'll just say times 600. And we can see, it's about 320 pixels
10:29 wide is the graphic that I should be creating.
10:34 So again, it's important to learn how to do these types of calculations to be able
10:38 to go between dp units and pixels. Okay.
10:42 So now, I'm going to go back to Illustrator.
10:45 And again, do File, Save for the Web. And now, for a width, again I want to do
10:52 320, which is about 75% of the 7-inch graphic.
10:58 And now, I'm going to save that, this time into the MDPI folder because that's
11:03 where the second generation Kindle Fire falls.
11:09 So, I'll Save it. So, I also wanted to point out that I've
11:12 included the finished product with all of the graphics optimized for the different
11:18 devices. And you'll find that in a zip file in the
11:23 exercise files. And now, we can go back to Eclipse.
11:28 And again, let me just I'm not going to save these changes here.
11:35 Let me just Refresh my project to make sure it sees it.
11:39 So now, I'm going to open up the Layout file.
11:42 You'll notice that all those changes that I made are not being applied when we
11:46 reopen. Because we only have a single Layout
11:49 file, currently. So, you'll notice when we open this file,
11:53 none of those changes I made have been retained because, again, we're working
11:57 out of the same Layout file. So, what we're going to do in the next
12:03 movie is to create specific layout folders.
12:07 So that the 8.9-inch will use a specific Layout file, so I can set the width of,
12:11 of the logo and so on and so forth. But let's go to the we'll go into the
12:18 Amazon folder to second generation. And now, this is looking pretty good now.
12:25 So, let's actually see how it compares to the 7-inch.
12:29 So, it takes up essentially, the same amount of real estate, it's the same
12:34 percentage width. Now, again, for this one, I could have
12:38 just used the HDPI version of the logo. But I just wanted to show you how you can
12:43 go about converting things between different DPIs.
12:47 And I can't stress it enough that this is obviously a thousand times easier when
12:52 your artwork is in vector format.
12:56
Collapse this transcript
Creating device-specific layouts
00:00 So, now that we've seen how to create different graphic assets based on the
00:05 pixel density of a device, now let's focus on layouts, because again, just
00:09 creating the graphics is not enough in most cases.
00:16 So, if you're going to a larger device or different pixel density, it is best
00:20 practice to try to have your layouts naturally adapt to all of these different
00:24 sizes. But in reality, a lot of times, you don't
00:29 want to provide alternate layout files for different devices.
00:34 Okay. So, I'm going to go into our Resources
00:36 folder and go under Layout. And let's look at the Layout file for the
00:42 actual game screen where we play the game.
00:46 Let me go to Graphical Layout and, let's see, make it to the HD 7-inch.
00:55 And here, you can see everything, you know, is fitting nicely.
00:58 We have the correct size graphic, we have the buttons looking nice and everything
01:02 fits in perfectly. But when we take the same layout and put
01:07 it on the 8.9-inch, you could see a few things happen.
01:13 First of all, we need to resize that image and then all the text on the
01:17 buttons is too small, the buttons themselves are actually too small, so
01:21 there's a lot of issues here. So, we're going to create a separate
01:27 layout file for the 8.9-inch Kindle Fire. So I'm going to close this right now, and
01:35 I'm going to create a New folder. And this New folder, much like the
01:45 drawable one we created, we're going to say, layout-SW800dp.
01:53 And that way, if it's on a 8.9-inch device, it's going to pull the Layout
01:57 files from this folder. So now, what I'm going to do is to
02:03 actually copy that game XML file, the Layout file, and paste a copy of it into
02:08 that New folder. And then now, we can actually start
02:15 working on this. So, I've already created the larger
02:18 version of the actual wheel graphic following the same steps that we did in
02:22 the last movie. So, all I have to do is, again, to adjust
02:27 the size, so let me go to Layout Parameters.
02:31 And inside of here, again, it's 360 DP for the 7-inch but that now becomes 540
02:39 DP inside of this Layout file for the 8.9 inch.
02:46 So essentially, what we just did was to multiply that DP value by 150% or 1.5 and
02:52 that's essentially what we're going to have to do now for all of these other
02:57 things inside of this Layout file, and this includes things like margins, text
03:02 sizes, and dp widths and heights. So, I'm going to go over to the actual
03:12 XML, and you can see inside of here all of these numbers.
03:18 So essentially, what you would typically do is go through and, you know, with a
03:23 calculator, you're going to multiply each of these by 1.5 so that they become
03:28 essentially identical to the 7-inch Layout file.
03:34 But, I have an easier system for you. I've actually made this little HTML tool
03:39 launch it up here. And this is actually in your Exercise
03:44 Files in the Assets folder and then the other folder, and it's just an HTML file
03:49 called convertDP. So now what this does is, you can paste
03:54 in your layout XML file, and then, provide a multiplier.
04:00 And then, it will parse through and, find all of the DP values, all of the SP
04:05 values, and it will multiply those values by whatever the multiplier is.
04:12 So, let me show you that. So, I'm just going to Copy all of this
04:16 file to the Clipboard and I'm going to Paste it in here.
04:21 And you can just pay attention to these numbers right here because they will
04:25 change. So again, the multiplier is going to be
04:28 1.5 and I'm going to click Convert File. And you'll see automatically all of those
04:35 values have been multiplied by 1.5. And this was created using regular
04:41 expressions in JavaScript so definitely view the source if you're interested in
04:45 this. But it just saves a lot of time.
04:49 So again, now, I'm going to copy this to the Clipboard, come back, and replace
04:53 what's in the Editor here. You can save it.
04:59 So I'm going to click on the Graphical Layout.
05:01 Now, you'll notice that the wheel is now really large, and that's because that
05:07 HTML tool is actually also multiplied that value by 1.5.
05:13 So, we just need to change that back and the value should be 540 DP.
05:19 So, as you can see now, this looks almost identical to the 7-inch Layout file, in
05:24 fact, let me open that up. No, that's the wrong one.
05:30 Let's go to the game, and make sure we're looking at it on the right device.
05:36 So, here is the Layout file for the 7-inch device and here's the layout file
05:41 for the 8.9-inch device. And you can see pretty close to being
05:47 exactly the same, and yet, of course, you can come in here and tweak stuff.
05:52 So again, if you're going from a 7-inch layout file to an 8.9, you essentially
05:59 want to multiply any DP or SP values by 1.5.
06:06 Now, this is obviously pretty simple activity.
06:09 Usually, you have to a lot more work than this than just simply replacing it.
06:14 And also, with larger screen sizes, you might want to change the way your
06:17 application actually looks or behaves to take advantage of that increased screen
06:22 space. But that's an example of how you create a
06:27 separate Layout file specific for a device.
06:31 And we can also create a Layout file that was specific to the 7-inch.
06:38 We would just say, SW533dp, and then the default one would just be used by the
06:44 Kindle's second generation. Now, if you want to see all of the
06:50 finished Layout files for the different devices, remember, that in the Exercise
06:55 Files, I've given you a zip file with the completed project so you can check out
06:59 how I implemented the layouts for the different devices.
07:06
Collapse this transcript
Handling the soft menu bar
00:00 So, another thing that you need to keep in mind when you're creating your
00:04 layouts, is the various Kindle UI elements that are also sharing the screen
00:08 space with your app. And I'm specifically talking down here,
00:14 about this Softkeys Menu. this is essentially, again, usually here,
00:19 by default. It provides a Home button, Search, Back,
00:23 and even an Options Menu. And there's also the status bar at the
00:28 top. So, for the Kindle 7 Inch, it does have a
00:31 height of 1280 pixels. But remember, that isn't exactly the real
00:37 estate you have to work with. So you just need to be aware of that.
00:43 So, in this movie, I'm just going to show you a little bit more about this Softkey
00:47 Toolbar down here. So, I've just created a blank project,
00:53 and created a menu. So, again, I'm assuming you know how to
00:57 create menus, it's just another XML file. And if we look inside of here, I've just
01:03 put three items inside of this menu. And that's essentially all it does.
01:09 Now, one thing that I've done is to set the theme to just be DeviceDefault.
01:19 Okay, so lets go ahead and run that up on the Emulator.
01:25 And I'll show you how that looks. So, here's our application.
01:29 Now, one of the things you'll notice is that we have the Action bar up here,
01:33 which of course, is part of Ice Cream Sandwich.
01:38 And, by default the Options Menu is actually up here, at the right.
01:44 So, if I click, here you can see the actual menu items.
01:48 Now, this doesn't necessarily fit in with the Kindle user experience.
01:54 So, what we would like to do is to get rid of this Action bar, and have the
01:59 options actually be down here. So, I'm going to come into my manifest
02:04 file. Now, the thing we have to actually do, if
02:09 we want to have that Options Menu be down on that Soft Toolbar, is we need to
02:15 change the minimumsdkversion to 8. And then, the targetsdkversion to 11.
02:25 And then, for the theme, we just want to say Theme.NoTitlebar.
02:31 And that's essentially going to get rid of the Action bar at the top.
02:39 And, again, because of putting in this minSdk and targetSdkversion.
02:47 It's going to enable the options to be in that Soft Toolbar.
02:51 So, let's go ahead and try that. And we'll let it launch.
02:55 Okay. So, here's my application launched.
02:59 And as you can see, the application itself is basically just empty.
03:06 But you'll notice that now, I actually have the Options Menu down here in the
03:10 Soft Toolbar. And when I click on it, you can see we
03:14 have the Options. And again, this is much more in a style
03:18 of the Kindle user interface. There's nothing stopping you from using
03:23 the regular Android Action Bar. But if you want to implement the Options
03:27 Menu in the Soft Toolbar, you have to do it this way.
03:31 So now, when it comes to your actual layouts, remember again, that this
03:35 Toolbar down here is taking up space that you can't use in your Layouts.
03:41 You're going to need to make sure you take that into account.
03:45 So, I'm going to go back to the Developer Portal on the Specifications Page.
03:51 And it actually tells you here, for each device, the height in pixels of both the
03:56 Status Bar at the top and the Softkeys Bar.
04:01 And you can see, it's different for the different devices.
04:05 Again, because of pixel densities and things like that.
04:09 Again, you need to take these values into account because they do take up space
04:13 that otherwise, could be used by your Layout.
04:18
Collapse this transcript
Using the fullscreen modes
00:00 So as we've been building our Spin It game, we've been running it in fullscreen
00:05 mode, which is pretty typical for games, because you want the user to be totally
00:09 engaged and not distracted by any operating system UI.
00:15 But on the Kindle platform, you have two different options for fullscreen that I
00:19 wanted to show you now. So I've created just a blank project and
00:24 inside of the Manifest file, I'm using the same theme as we are in Spin It.
00:29 It's just DeviceDefault.NoActionBar.Fullscreen.
00:36 Now, I have this app running on the emulator, and you can see essentially, my
00:41 activity is completely filling the screen.
00:45 But I have this little thumb down here which I can click on to access the
00:49 Softkey Toolbar and also the Notifications Title bar at the top.
00:55 And then again, if I click on my application, it'll go away.
01:00 So you have this easy way to get at these navigation and these different toolbars.
01:05 But that's not always what you want and there's another option that we can use.
01:11 So I'm going to modify this to remove the Fullscreen, so it's just going to be
01:15 NoActionBar. And now, I'm going to go into my
01:19 MainActivity file, so obviously, we can set the fullscreen state either in the
01:24 Manifest file or we can do it with code. So that's what we're going to do here.
01:32 So to go fullscreen with code, I'm going to say getWindow.addflags, and then
01:41 I want to go to WindowManager.LayoutParams.
01:48 And, the one we want is Flag_Fullscreen. So now, with this, this is going to give
01:57 us the same type of fullscreen as I just showed you.
02:00 So you're going to be fullscreen, but you're still going to see that little
02:03 handle. But we can add another line of code,
02:06 which will basically show the ice cream sandwich version of fullscreen and
02:11 actually get rid of that little handle. So I'm going to call, getWindow again,
02:20 and now we're going to go to the getDecorView, and then
02:27 SetSystemUIVisibility. And it's looking for a constant from the
02:38 View class, and that is SYSTEM_UI_FLAG_HIDE_NAVIGATION.
02:46 And essentially, what's that going to do is to, so what this is going to do is
02:51 essentially remove any onscreen UI and allow your activity to truly take up the
02:56 entire screen. So I'm going to save this and let's send
03:02 it out to the emulator. So here's my app launching up, and you
03:07 can see now that I'm fully fullscreen, and there is actually no handle to get to
03:12 these softkey toolbar. But as soon as you interact with your
03:18 application like clicking on it, it essentially goes back to the regular
03:23 Fullscreen mode with the handle, and then I have access to these toolbars.
03:31 And then I click, and now, I'm back in regular fullscreen mode.
03:35 But this can be really useful for let's say a splash screen where you want an
03:40 activity to pop up totally fullscreen for maybe 5 seconds and then it's going to go
03:44 away and you don't want that little handle to be showing.
03:51 So anyway, those are the two options that you have for fullscreen on the Kindle
03:56 platform.
03:57
Collapse this transcript
6. Preparing to Publish
Targeting other devices
00:00 So throughout this course we've been targeting our application to the three
00:04 latest Kindle devices. That's the Kindle Fire 2nd generation,
00:10 and the HD 7 inch, and the HD 8.9 inch. But let's say you also wanted to support
00:16 the 1st generation Kindle Fire. So I'm going to go into the Manifest
00:21 file. Now the first thing you're going to need
00:24 to do is to actually download the Gingerbread SDK, because that's the
00:28 version of Android that runs on that device.
00:32 And you're also going to need to download the Kindle component for Gingerbread as
00:37 well. Now in the Manifest, we're going to need
00:40 to change min SDK version to 10, because that's actually the Gingerbread version.
00:46 And you could see here that I'm now getting an error under theme and, and
00:50 it's because that this theme doesn't exists in Gingerbread.
00:54 So I'm going to have to choose one that does work.
00:58 So I'm going to go to Theme and a similar one is Theme.Black.NoTitleBar.FullScreen.
01:06 And sometimes in Eclipse, even though there's no error, it still keeps that
01:10 there like that, but there is no error with this.
01:14 Now, another thing is, well, what if you want to also target non-Kindle devices,
01:19 because remember, that regular Android users can actually download the Amazon
01:23 Appsstore to their device. The actually have to go to the Amazon
01:29 website to do it. it's not in the Google Play store.
01:33 But it is possible. So you may want to make your application
01:36 available, also, to non-Kindle devices. Now, one of the things that we can add
01:42 here is about hardware acceleration. So, in Android 4 all applications are by
01:48 default hardware accelerated. But if you're planning to target devices
01:54 earlier than that, then we need to add something to our application tag.
01:59 And it's going to be hardware accelerated, and we're going to set that
02:05 to true. And we can just keep it like that, even
02:09 if we're just targeting the latest devices.
02:12 It's just going to ignore it, because again, they're automatically hardware
02:17 accelerated. So again, in this course, we haven't
02:20 focused on building something for that first generation Kindle Fire and let me
02:24 just explain a little bit of the differences.
02:28 So first of all, some of the code that I wrote wouldn't work.
02:32 Because some of the animation stuff in there is actually newer than Gingerbread.
02:38 And a big problem is that the 1st Generation emulator that you can create,
02:42 you don't have the ability to actually register it and, and login with your
02:46 Amazon account which we needed in order to test things like GameCircle and Maps
02:51 and other things. So that's a big stumbling block, but this
02:57 application, with just a few minor changes would also work just fine on the
03:02 1st Generation Kindle Fire. So like I mentioned, there is a great
03:07 possibility that people with regular Android devices will be downloading your
03:12 application and trying them out. So what I'm going to do now is to go over
03:19 to my phone. So I'm actually streaming this to my
03:23 desktop here with this application called Ashot and I've installed the Amazon SDK
03:29 tester. And that JSON file for In-App purchases
03:33 and, of course, the Spin It application itself.
03:37 So let me go ahead and watch it, and you can see the difference.
03:42 Because, obviously, this is a phone. And we haven't created a specific layout
03:48 for phones. So if you are planning to target
03:52 non-Kindle devices or non-tablet devices. You're going to need to also create
03:57 layouts that handle phone size. And the other thing is, because we're
04:02 using the default theme. This is the default button style on my
04:06 device, on my phone. Okay, so, what I'm going to do here is to
04:11 first click play game. And you can see, again, things are, you
04:16 know, a little bit out of whack here visually.
04:20 But I'm going to go to change the wheel and we can we have those two locked
04:25 wheels. So I'm going to go ahead and buy.
04:29 The Camo Wheel. Do purchase, and then I'll back out of
04:35 it. And you can see that worked.
04:40 Now, let me click on the Camo Wheel and now we're back.
04:47 So, the In-App purchasing will work outside of Amazon devices.
04:52 Now the only thing is you have to have the Amazon app store application
04:57 installed on your device for it to work in production.
05:03 Now, that's how it actually communicates. But I'm going to go back to the home
05:07 screen and I'm going to click on, View High Scores.
05:12 And you can see what has happened here is it's crashed, and that's because the
05:18 GameCircle APIs are only available on Kindle devices.
05:24 And, in our code, you know, we really didn't handle all of the exceptions and
05:28 make it gracefully degradate. But just be aware of that.
05:33 In-App purchasing will work on any Android device, so long as they also have
05:37 the Amazon Appstore on that device. But the GameCircle API, only on Kindle
05:43 devices. So again, if you plan on creating a
05:48 single APK that's going to run on the Kindle devices and also on non-Amazon
05:53 devices, on phones, then you need to make sure that you deal will all of these
05:57 different cases. Personally, I would recommend creating
06:03 versions specifically for the Amazon devices.
06:07 Let's say you already have a tablet application that you've deployed to
06:11 another platform. I would just take that and you're not
06:15 going to have to modify much, but again, integrate those Amazon APIs and then send
06:20 that to the Amazon Appstore. But, of course, you could do either, and
06:25 another thing that you can do, and I'll cover this when we actually go to publish
06:29 our application is you can target specific devices when publishing.
06:35 So under your , which is Spin It, I can actually say Send this APK to this
06:40 device, this APK to a different type of device.
06:46 So that really helps out when it comes to this dealing with different devices.
06:51
Collapse this transcript
Preparing your app for publishing
00:00 So before you actually try to submit your application to Amazon, you really want to
00:04 make sure that you've gone through and implemented everything correctly.
00:09 Because unlike the regular Google Play market, Amazon has to approve your
00:13 application. So I'm just going to show you a few
00:16 things to look for. So first I'm going to start in the
00:20 manifest file. And this uses SDK, that's a pretty
00:24 important thing. Now for our example we're just targeting
00:29 the three latest Kindle devices, which run on API 15.
00:34 So the minimum SDK version which is the lowest version of Android which your
00:39 application will work on is 15, and the target version is also 15.
00:46 But like I mentioned in the last movie, if you wanted to, say, target the first
00:50 generation Kindle Fire, You could change this to ten, or additionally, if you
00:55 wanted to go even lower to target non Amazon devices.
01:00 But for our purposes this is okay here. Now the next thing we want to do is to
01:05 implement the support screens tag. And this is going to give information
01:11 about what type of screens this application is supported for.
01:15 So I'm going to put in For large screens, I'm going to set that equal to true, 'cuz
01:21 essentially this a tablet application. And then extra large screens, going to
01:28 set it equal to true. Small screens I'll set to false.
01:34 And normal screens I'll also set to false.
01:38 And again, this is going to vary based on your application, whether you're
01:42 targeting, tablets, phones, or both. Okay, so another really important thing
01:49 to do is to lent your project. So what Lenting is going to do, it's
01:54 going to go through your project and look for any Problems like warnings and it
01:57 will give you recommendations. So here you can see the Run Android Lint.
02:04 So I'm going to do that and we can see it's letting me know all of these
02:07 potential problems that I have it, in my application.
02:11 Now, not all of these are true problems but it's essentially just trying to help
02:15 you out and let you know. So, here you can see that in my Layout
02:21 Files, I have a bunch of hard coded strings.
02:25 Well, that's not really good, because if you want to provide translated versions
02:29 of your application, you're going to want to actually use a string resource.
02:35 So, we can actually fix them from here, so, I can click on this one.
02:39 It's telling me what the problem is. For if I click on this little white bulb.
02:43 Its bringing out to that file and its going to replace it with a string
02:47 resource. Like that, and essentially I can continue
02:52 going through all of the linting recommendation.
02:56 And it will tell you things like. Certain layouts.
02:59 Perhaps you haven't optimized your layouts correctly.
03:02 And it's just a really helpful thing to do.
03:04 And again not all of these things you're going to fix.
03:06 But its just a definitely a good thing to look at before you submit your
03:12 application. So one thing I did want to point out is
03:18 The bill target for your application. So I'm going to go to properties on my
03:24 project. And if we go to Android you'll notice
03:28 here the bill target is set to Android 4.0.3, which is correct.
03:34 Now don't be tempted to check off one of these Kindle targets because these are
03:38 actually just for the emulators. So I just wanted to point that out.
03:43 So keep it at this version of Android. So another thing I wanted to point out is
03:50 about icons. So if we look inside of let's say the
03:54 drawable HDPI. So this is the actual icon for this
03:59 resolution. But, like I mentioned previously, Amazon,
04:04 on Kindle devices, doesn't use these icons at all.
04:08 They use the ones that you uploaded when you created your project on the developer
04:12 portal. But you should definitely still include
04:17 these different resolution icons, if you plan on targeting non Amazon devices with
04:22 your project. Okay, so now I lastly just want to go
04:27 through some of the code that we did. Because remember, I implemented things in
04:32 a pretty basic way just so that you could learn the API.
04:37 But I just want to cover some of the things that you need to be aware of.
04:40 So, first, in app purchasing, let me open our version of it.
04:44 And then I'm going to also open the observer from the sample which actually
04:50 comes with the Amazon stk button clicker dot observer.
04:57 So like I mentioned in here we can do this initiate user id request, and this
05:01 is for the situation again you're using your Kindle you're logged in.
05:07 And then you hand it to your family member or a friend, they log you out, log
05:11 themselves in with their own Amazon account, and then start playing the game.
05:18 Well we, in our application only have a single shared preferences.
05:23 So you can get this user ID request, which will be a unique user ID for each
05:27 Amazon account. So you could have multiple shared
05:32 preferences for each user. So definitely look at that.
05:36 Now, the other thing I wanted to point out again, is.
05:39 Inside of these call back methods, Amazon recommends, if you're going to be doing
05:43 something that is kind of intensive, then you should call it out and use an Async
05:48 task. Which will basically run it on a separate
05:52 thread from the UI. So, you can look at how that's
05:55 implemented here. Now, again, this on item data response,
05:59 we didn't use, but this is important if, say, you publish your application, and
06:04 then you want to add another in that purchase item.
06:09 Well, this will actually download the actual data, from the developer portal.
06:15 So you can dynamically build the UI with that data.
06:19 So, definitely something that you can look to implement.
06:22 And definitely check out this file, for a sample.
06:26 So last thing I want to talk about, the game circle API, which we implemented
06:30 inside of our app.Java class. Now if you watched the last movie, when I
06:36 put this application onto my Galaxy S3 and try to run it.
06:42 And then I click View leaderboards, it crashed, and that's because Game Circle
06:46 is not supported on non Amazon devices. But, in general, we're not really
06:52 checking to see if everything has worked correctly, before we try to call some of
06:57 these methods. So what we should do is, in the on
07:01 service not ready, which will come to us if we're on a non-Amazon device.
07:07 Or even if we are on an Amazon device and for some reason we can't reach the game
07:13 circle client, we can set his game circle connected equal to false.
07:22 And, then I'm basically going to create that as a Field.
07:26 And, we'll actually bring it up to the top and make it Public Static.
07:32 So that we can check it throughout our application.
07:37 So this will be public, static, Boolean, and we'll set it to false initially.
07:46 And then also now down here we want to copy this and in on service ray we
07:52 want to set it to true. So now we have this way of checking to
08:00 see whether the gamecircle client is connected.
08:03 Now in places in which we call gamecircle api's, like let's say in the spinit.java,
08:09 like here in the view high scores method, I'm simply going to do an if statement
08:14 So, if app. Is game circle connected.
08:21 then I'm going to do it not for else. I can do something like just show some
08:26 toast that will actually explain to the user that its not connected.
08:31 And so, games, circle, not connected, toast.long, and then this will actually
08:41 avoid that crashing state, and I need to show it as well.
08:53 So again, for all of this API's, you're going to want to do and handle all of the
08:56 potential things that could happen and make sure that your application doesn't
09:00 crash. Because again, your application is
09:04 going to have to be approved by Amazon, so you want to really, really make sure
09:09 that you've tested all the potential scenarios before you go ahead and upload
09:13 it to Amazon.
09:16
Collapse this transcript
Signing and exporting your application
00:00 Okay. So, let's say you've gone through your
00:02 project, everything is working perfectly, you've made sure you have all the correct
00:06 resources, adhered to the best practices, and you're ready to now export your APK
00:10 so you can publish it to the Amazon App Store.
00:16 Well, you first need to know that the signing process for this APK is not
00:20 traditional, because you have two options.
00:25 First, you can export an unsigned APK, upload that to the Developer Portal and
00:29 then essentially, what Amazon does is wrap it with some of their own technology
00:34 so that it will work on the Amazon App Store.
00:40 And then, it will sign the APK using a certificate that's unique to your user
00:46 account on Amazon. And that's definitely the easiest way to
00:51 go, just let them handle the signing. Now, if for some reason you have to sign
00:57 the APK with your own certificate, you can export a signed APK upload that to
01:02 the developer portal then Amazon will again wrap it with their own technologies
01:07 so that it's compatible with the App Store.
01:14 And then, they will send you that APK back so you can again sign it with your
01:19 own key and then you can finally upload that finished APK.
01:25 So, again, it's a little bit more complicated if you want to export a
01:29 signed APK. But one thing that's important is you
01:33 should actually export a signed APK and just hesitate to make sure that it
01:37 behaves the same because all throughout this course, we've been exporting debug
01:42 builts. So, I am going to right-click on my
01:47 project and I am going to go to Android Tools > Export Signed Application Package
01:53 and I am going to leave the name at SpinIt.
01:58 Now, this is the location of my personal certificate.
02:01 Let me put in my password. You can also create one here if you don't
02:05 have one. And let me put in my password for the
02:09 key. And now, it's asking me where do I want
02:13 to save this APK, I want to save it to my Desktop, and now it's basically exported
02:19 that to my Desktop. Okay.
02:24 So now, what I want to do is to install this APK onto my emulator, so I'm
02:29 going to go to the terminal and say, adb install SpinIt.apk.
02:36 And we'll let it install. And I'm running the HD7 inch emulator.
02:45 Okay. So, it's up there now.
02:50 It's actually launch up the emulator and let me launch the app.
02:55 Okay, so it's running here, let me click on Play Game.
03:01 And we can try out one of the in-app purchases, so I'll go to Change the
03:05 Wheel. And let's buy the camo wheel style.
03:10 So, when I click that, we can see it launches the in-app purchase UI.
03:16 I'm going to purchase that and close this.
03:21 And now you can see this, that has worked.
03:23 So locally, anyway, the in-app purchase is working fine with this release build
03:28 of our application. But, if I now go back to my Main Game,
03:33 and if I actually go back to the Main Menu screen, I'm going to click on View
03:39 High Scores. And you can see, it's crashed.
03:45 So, you'll remember, during the Game Circle chapter, that we actually had to
03:49 create our unique hash key and put it into the portal in order to get Game
03:53 Circle to work. and we base that on the Debug Key store
03:59 and now we've signed it with our release certificate so Game Circle is not
04:03 going to work. So, just be aware of that if you're
04:07 exporting a Release Build and trying to use Game Circle.
04:12 Okay. So, I'm going to minimize the emulator
04:14 when we go back into our clips. Now, in our case, we're going to go the
04:19 route of exporting an unsigned APK, uploading that to the portal and then,
04:24 we'll let Amazon deal with signing it and all of that.
04:29 It's definitely the easiest way to go. So, I'm just going to right-click again,
04:34 go to Android Tools, and this time, Export Unsigned Application Package.
04:41 And, of course, it's just simply now asking me for, the location because it's
04:45 not going to be signed. So, I'm going to save it to the Desktop,
04:49 and it's telling me an unsigned application was saved.
04:54 Click OK. And now, we have our APK that were
04:57 actually going to upload to the Developer Portal which we'll be doing in the next
05:03 movie.
05:06
Collapse this transcript
Publishing on the developer portal
00:00 Okay. So the time has finally come for you to
00:03 upload your application to the portal, submit it to Amazon, and basically wait
00:08 for their approval. So I did want to point out that this is a
00:13 lot different than regular Android development, because there is no approval
00:17 process. I can create an application today,
00:21 immediately, put it on the Google Play market and it's just very quick.
00:26 And this is more similar to the way iOS works, where you submit it, they're
00:30 going to look at it, run it through some tests, and they'll let you know if
00:33 there's any problems or if it's published.
00:37 So, I'm going to come to the my Apps page on my account, and I'm going to click on
00:42 the Spin It project. Now remember, we filled in most of this
00:46 information already. But now is the time, since we're going to
00:51 submit this now, to make sure that everything is correct, Availability &
00:56 Pricing, Description. Again, when we created this in an earlier
01:01 movie, I just put in like placeholder text here.
01:05 You're definitely going to want to think about what you want to put in here,
01:09 because this stuff is really important to help people find your application.
01:14 Images & multimedia, we've already added ours, so we're all good there.
01:20 Content Rating, we already did. And now we can go to Binary Files.
01:27 So you have an option to allow Amazon to apply DRM to your application to prevent
01:32 it from unauthorized use, and it's recommended that you do it.
01:39 And the other thing is that you can't use your own DRM scheme.
01:42 If you're going to use DRM, you have to use the one from Amazon.
01:46 So I'm going to keep that on Yes. So, the next thing I want to do is to
01:52 upload the binary. So on the desktop, there's the
01:57 Spinit.apk. And while it uploads, let me explain this
02:02 next part right here, Device Support. So here is where you tell it which
02:08 devices you plan to target with this particular APK.
02:13 So, in our case, we've been building our application for the newer Kindle Fire
02:19 devices. So I'm going to uncheck all non-Amazon
02:23 Android Devices and I'm also going to uncheck Kindle Fire 1st Generation.
02:29 Now again, I can upload a second APK for non-Amazon Devices or I can upload a
02:35 third one just for the Kindle Fire 1st Generation.
02:40 You have the ability to target specific devices with specific APKs.
02:47 So I think it's uploaded now. And, here we go.
02:51 So now, you can see that my APK has been uploaded.
02:54 And it actually shows me some information from my manifest, like the package name,
02:59 SDK version. Also the supported screens which we put
03:03 into the manifest file were only supporting large screens and extra large
03:08 screens. Now here, basically now, we want to do
03:13 what we just did a second ago which was to uncheck Kindle Fire 1st Generation and
03:19 uncheck non-Amazon devices for this APK. Now, for the language support, you know,
03:26 I didn't do any translations. But if you did, then you would want to
03:29 put the appropriate one in here. This export compliance, I'm going to
03:34 agree to that. And since we can have multiple binaries,
03:37 you can give it a unique name. And then, this is an important part is
03:42 testing instructions and this is for the people at Amazon who are actually
03:45 going to test out your application. So if there is anything unique that you
03:51 want them to test, that maybe isn't self-explanatory, you would want to put
03:55 that in here. So, even though we don't have another APK
03:59 to target a different device, let me just show you that workflow.
04:04 I can click Save and Add a Binary. So this is essentially going to save all
04:09 this information. And, now I'm brought back to this screen
04:13 again where I can upload another binary. And, you can see these are grayed out
04:17 because I've already said I have an APK for these devices.
04:22 And, now I can go through this process again.
04:24 And, you know, save it. So I'm actually just going to remove
04:30 this, because again, we only have a single APK.
04:36 So, now, what we want to do is to save it, so we are going to click Save, and
04:40 now that binary file has been saved. And now, you can see down here, we now
04:47 have a Submit App button. And this is the button that will actually
04:52 let us submit the application to Amazon. So I'm going to click that and we can see
04:59 that the Spin It application has now been submitted.
05:04 But now, I want to point out a couple of other things, the In-App items.
05:12 We created these, but we didn't submit them.
05:14 So now, we can actually submit these. So I'm going to go in Buy Camo Wheel and
05:19 Submit In-App Item. And Buy Gold Wheel, Submit.
05:26 And you're going to want to do this, because if Amazon is testing your
05:31 application, if these are not actually submitted, it's not going to work.
05:38 So now, I also need to go to GameCircle, because remember, I have Liter Boards and
05:43 Achievements, so I'm going to go to Liter Boards.
05:47 And for this one, I'm going to change the status of this right here, Ready to
05:53 Publish, and I'm going to click Start Publishing, and click Publish.
06:02 And we can see now the status is Published.
06:06 So now I'm going to go to Achievements. Again, change the status to Ready to
06:14 Publish, click Start Publishing, and now that is also published.
06:21 So you can see now, here, this link says Current Version Under Review.
06:26 Now, this review process, it can take a little while and it varies.
06:31 So it could be days or it could be weeks. But essentially, what will happen is
06:35 after they're done testing it, I'm going to come back to the my Apps page.
06:40 It will tell you here, either if it was successful, and it will also tell you if
06:44 you have an action item, which basically means they rejected it and they're
06:48 going to give you a reason why it was rejected and give you a chance to fix it.
06:55 Now, you should get an e-mail either way when it's either accepted or rejected.
07:01 But you want to keep coming back here and checking the status of your application.
07:07 But again, try to be patient, because the process can take a little while.
07:13 But that's the process complete now. Now, it's all in Amazon's hands to decide
07:17 if this is an application that they want to put on the Amazon Appstore.
07:23
Collapse this transcript
Conclusion
Downloading the Kindle sample apps
00:00 So in this course, you've learned a lot by building that Spin-it game.
00:05 But obviously, there's a lot more to learn, and one of the best places to look
00:10 is at some sample code of other applications.
00:14 Well Amazon actually provides a set of samples.
00:18 So if you come to the main SDK Kindle Fire page, under build, you can see this
00:22 link, Kindle Fire Sample Code. And if you click on here, this basically
00:28 explains all of the different projects that's included, and you just download
00:33 this zip file. Now, I've already downloaded it, and
00:38 actually extracted it, here on the desktop.
00:42 And you could see, these are just eclipse projects ready to be imported.
00:47 And they cover a lot of really nice topics and there's some really good
00:52 sample code in there. So I've actually loaded one into Eclipse,
00:57 called Camera Activity. So when I bought my Kindle Fire HD seven
01:01 inch, I noticed there is no camera app on the device, even though there is a
01:06 cameras. So how would we go about creating an
01:10 actual camera app? So I've actually published this out to my
01:15 device, and let me show you what that looks like.
01:20 Okay, so again, this is my actual device, and I'm actually streaming it to my
01:24 desktop here, using a great application called Ashot.
01:29 And you can see, I have that sample custom camera app here, and I'm going to
01:33 launch it. Now this has a really slow framerate,
01:37 this actual streaming to the desktop, but you can see the camera is working.
01:43 And, I can actually go ahead and tap on it, and it will actually save a picture.
01:49 So it's a very basic camera app. But as you can see, those sample files do
01:54 have some really interesting application source code in them, so I definitely
01:58 recommend that you check them out.
02:02
Collapse this transcript
Additional Amazon services
00:00 So, this course was designed to give you the fundamentals of how to use the Amazon
00:05 specific APIs for creating apps for the Kindle platform.
00:11 Now, of course, there are some other things that I didn't cover, and I just
00:15 want to go over what those are right now. So, I'm on the main sdk page here.
00:20 And I'm going to click on In-App Purchasing.
00:26 Now, we've covered everything here, except, we didn't integrate Subscription
00:30 Content into our game. But it's very simple and it's basically
00:35 almost identical to the entitled In-App Purchase.
00:38 And again, the sample that comes with the Amazon SDK will show you that
00:42 subscription code. And the other area that we didn't cover,
00:47 but I did talk about when I gave the overview, is the validating transactions
00:51 outside of your app. Where you can actually send the purchase
00:56 receipt to one of your own servers, and then you can actually validate that with
01:01 the receipt verification service. So, just be aware of that.
01:07 Now, there's also plug-ins for other technologies besides Android, like Adobe
01:11 Air and Unity. And if those interest you, you should
01:15 definitely check those out as well. Okay, so let's go over to Game Circle.
01:20 Now, in Game Circle, we covered everything except the J and I API.
01:26 And essentially, what that is, is an API that allows you to use native code inside
01:31 of your application. So, if you have C++ that you need to
01:37 integrate into your application, that's what this API is for.
01:43 And again, for Game Circle, there are plug-ins from Unity, Adobe, and also for
01:48 cocos2d. Now, one area I didn't cover is A/B
01:53 Testing. And what this service is, it basically
01:57 lets you send out tests of your application to certain customers to see
02:02 how successful that test was. So, say, maybe you're implementing a new
02:08 feature. You can send it out just to a certain set
02:12 of users. And see how that goes before you unlock
02:16 it for everybody. So again, if you're interested in that,
02:20 definitely come and check this out. This is still in Beta however, so just be
02:25 aware of that. Now, for Maps, pretty much, like I
02:28 mentioned, in the chapter on Maps, it's pretty much the same as Google Maps.
02:34 So, if you've used Google Maps before, this shouldn't be a big deal.
02:37 The only thing I didn't cover was how to migrate an existing application with
02:43 Google Maps to the Amazon Maps API. But there's a link right here which gives
02:48 you all the details. So, the last one is device messaging.
02:54 And this is a really cool API, unfortunately it's still in a closed Beta
02:58 program. But you can request access to get onto
03:01 that Beta program. But essentially, what this allows you to
03:05 do is to send push notifications from the cloud to Kindle Fire devices that run
03:10 your app. And you could be doing those for any
03:14 number of reasons. And when your app receives these you can,
03:17 you know, make various things happen inside of your application, like display
03:21 a different UI and things like that. So, once this comes out of Private Beta,
03:27 this is definitely going to be an API that's going to be very interesting.
03:33 So again, we've covered a lot, but just keep looking here on the Developer Portal
03:38 for updates and other APIs that Amazon may release.
03:44
Collapse this transcript
Next steps
00:00 So, we're now at the end of the course, and I hope that it has been a great
00:04 learning experience for you on developing applications for the Kindle platform.
00:09 Now, I've covered a lot of things in this course, but like any technology, there's
00:13 always more to learn. And in technology, things change rapidly,
00:18 so I definitely recommend that you continue to visit the Amazon developer
00:22 portal for updates on the things you learned in this course, and also to find
00:26 out about any new API's that Amazon is working on.
00:31 Finally I wanted to mention that there is an active forum for Kindle developers
00:36 that is linked to from the developer portal, and it can be a great place to
00:40 get your questions answered. So again, thanks for joining me, and I'll
00:46 hopefully see some of your own applications acheiving success on the
00:50 Amazon App Store.
00:52
Collapse this transcript


Suggested courses to watch next:

Android SDK: Local Data Storage (3h 41m)
David Gassner


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,024 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked