Derek Gebhard, Solutions Architect for Amazon, is our guest blogger for this post.
One of the things you will spend time on when building a Kindle Fire app is testing and debugging. Using a Kindle Fire emulator is the recommended way to test and debug your mobile apps if you do not have the device available. This post will cover tips on increasing the performance of the KindleFire emulators, including the newly released KindleFire HD 8.9” emulator, but will also apply to most other Android emulators.
For Ice Cream Sandwich-based Kindle Fire emulators(Android SDK 4.0.3, API level 15) you can enableGPU emulation to significantly improve the performance. One thing to be aware of: GPU emulation is currently an experimental feature in the Android tools suite, and may not work on all host hardware configurations or operating systems. If you experience issues, you may need to disable this functionality.
To enable GPU emulation, launch the Android Virtual Device Manager. This can be done by running “android avd” or clicking the Android Virtual Device Manager icon in Eclipse.
For existing emulators:
When creating a newemulator:
Image 1:Changing the GPU emulation property
To showcase the effect of GPU emulation property, there are two screenshots below. These GPU measurements were taken on a Windows desktop,using the Kindle Fire HD 7” emulator. This test included starting the emulator,running SDK Tester, and accessing the Kindle Fire settings. As you can see, GPU emulation must be enabled in order for the emulator to leverage the GPU’s dedicated memory.
Image 2:GPU emulation set to “no”
Image 3:GPU emulation set to “yes”
There are also a few other things that can help when running apps on the Kindle Fire emulators. Below is a list of the other ways we can increase performance and save time:
E-dan Bloch, Solutions Architect for Amazon, is our guest blogger for this post.
The new Kindle Fire HD 7” and 8.9” tablets introduce high definition screens that provide a great opportunity for mobile app developers to deliver an improved user interface, high resolution images,and apps that take advantage of more “screen real estate”. While native layouts make use of these higher resolutions by default, layouts within WebViews may require some HTML adjustments to be made.
WebView control may display pages that are logically longer and wider than the physical screen size, allowing users to pinch to zoom and scroll through a web page. To accommodate the difference in size, the WebView control takes two properties into consideration: the native view size (the size of the control itself) and the logical view port size (the size of the content currently visible within the control).
The viewport, with respect to the WebView control, is the area of the page currently visible to the user. The native Android layout engine controls the view size, and the HTML page determines the logical viewport size. For example, when the WebView displays a page that is zoomed in, the logical viewport size is smaller than the actual size of the control (hence the zooming). This can lead to seemingly unexpected behavior of web apps, especially when JavaScript is used to create the page’s layout.
There are two key properties that mobile app developers leveraging WebViews should be familiar with: the viewport metadata property and the android:theme property.
The “viewport” metadata property is represented as <meta name="viewport" content="…" />. Adding this entry to the <head> section of your HTML pages will allow you to better control how your pages are displayed on users’ devices. Control this property by setting its content attribute with the following descriptors:
height = [pixel_value | device-height],
width = [pixel_value | device-width ],
initial-scale = float_value,
maximum-scale = float_value,
minimum-scale = float_value,
user-scalable = [yes | no],
target-densitydpi =
[dpi_value | device-dpi | high-dpi | medium-dpi | low-dpi]
By default, the target-densitydpi descriptor assumes the medium-dpi value. For Kindle Fire HD devices, you should change this setting to high-dpi so that your content will display properly. Alternatively, you can use the device-dpivalue and have the WebView control determine the density dynamically according to the device being used. This automatic setting will cause the viewport to scale differently for each device’s pixel density.
To use this automatic setting, add the following line to the <head> section of the HTML page being viewed:
<meta name="viewport" content="target-densitydpi = device-dpi" />
In instances where a web page uses a fixed-size layout, or a purely relative (fluid) layout, we may also want to have the width and/or height descriptors set to device-width or device-height (respectively). Setting these values will set the logical size of the WebView to match that of the device being used. So the viewport property would look like this:
<meta name="viewport" content="target-densitydpi = device-dpi, width = device-width" />
Combined with the auto-density selection we get:
<meta name="viewport" content=" target-densitydpi = device-dpi, target-densitydpi = device-dpi, width = device-width" />
To demonstrate the effect of the latter tag, here is a side-by-side comparison of a simple web page displaying different size values with and without it:
Notice how, in the example on the right, the ViewPort size matches the WebView size. The difference, in both examples, between the screen size and the WebView size are due to the status (above) and menu (below) bars.
The second property is the android:theme property. Although it relates to the Android activity itself, and not just the WebView control, it can impact the screen real estate that your apps use. A good example is full-screen browsing. The Kindle Fire’s soft-key menu provides developers with power over the amount of screen their app can use by allowing them to hide both the title bar and the menu buttons. To use this feature, you can add the android:theme attribute to the <application> or <activity> elements in your AndroidManifest.xml manifest file and set the appropriate theme. For example, you can use@android:style/Theme.NoTitleBar to hide the top title bar, or
@android:style/Theme.NoTitleBar.Fullscreen to hide both the title bar and the soft-key menu bar. For example, if you want your entire app to operate in full-screen, your AndroidManifest.xml file might look like this:
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">…</application>
This last value gives you the most screen area to work with. However, this option should be used with care as it affects the user experience by minimizing standard controls such as the clock and battery indicator, as well as the “back”, “search”, and “home” buttons.
To demonstrate, here is a side-by-side comparison of the default theme versus the Fullscreen theme:
Notice how, in the example on the right, all buttons are hidden until the user taps on the pull-up button seen on the bottom.
For more information, please also see the User Experience Guidelines.
One of the great new features that the Kindle Fire HD offers is a set of dual-driver stereo speakers on both sides of the display. This sound setup opens new possibilities to game and app developers by allowing for a more comprehensive and immersive sound experience.With minor adjustments, any app can leverage the stereo speakers and enhance the user experience. By default, Kindle Fire HD uses both speakers to output balanced sound (left speaker = right speaker). By changing the volume on either side, we can achieve an effect of localized sound. As a simple example, we can consider a conga drum app. The app will have two conga drums displayed, one on the left and one on the right. Tapping on the left conga produces sound only in the left speaker and similarly, tapping on the right drum produces sound only in the right speaker.
The way to control the volume on the speakers depends on the method being used to actually play sound. For the purpose of this post, we will assume that the MediaPlayer class is used, but most other methods should be similar if not identical in nature. The following code will create a MediaPlayer instance that will play audio only through the left speaker:
import android.media.MediaPlayer;
…
float leftVolume = 1.0f;
float rightVolume = 0.0f;
MediaPlayer mPlayer = MediaPlayer.create(…);
if (nPlayer == null) {
mPlayer.setVolume(leftVolume,rightVolume);
}
The leftVolume and rightVolume parameters can be set toany value between 0.0 (“off”) and 1.0 (“full volume”). The volume level is relative to the master volume of the device so changing these values is basically just changing the balance between the stereo channels or, in this case, the two speakers.
Using the SoundPool class is not all that different:
import android.media.SoundPool;
…
float leftVolume = 1.0f;
float rightVolume = 0.0f;
SoundPool sPool = new SoundPool(…);
// Load an asset into the pool
int streamId = sPool.load(…);
sPool.play(streamId,leftVolume, rightVolume ,0, 0, 1.0);