Developer Console
Appstore Blogs Appstore DeveloperBlog /blogs/appstore/feed/entries/atom 2021-07-21T14:49:49+00:00 Apache Roller /blogs/appstore/post/6c32f2d7-4770-416f-bcbd-a891f885a0e8/amazon-device-messaging-adm-and-local-notifications-on-fire-tv Amazon Device Messaging (ADM) and local notifications on Fire TV schwille 2021-07-21T14:49:49+00:00 2021-07-21T14:49:49+00:00 <p><a href="https://developer.amazon.com /blogs/appstore/post/6c32f2d7-4770-416f-bcbd-a891f885a0e8/amazon-device-messaging-adm-and-local-notifications-on-fire-tv"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_ADMnotification_954x240.png" style="height:240px; width:954px" /></a></p> <p>Learn how to use Amazon Device Messaging (ADM) to notify customers of new features, content, or promotions available in your app.&nbsp;&nbsp;</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_ADMnotification_954x240.png" /></p> <p>Currently, Amazon Fire TV supports standard Android notifications through the <a href="http://developer.android.com/reference/android/app/Notification.html">Android Notifications API</a>, which developers can use to send local notifications to customers that appear outside of your app's user interface. Nowadays, it is quite common practice for apps developers to send notifications to smartphone users to grab their attention.<br /> <br /> Similarly, on Fire TV, notifications allow developers to reach out to your customers to encourage them to revisit your app. You can use notifications to inform your customers when there is a new feature, content, or a promotional campaign available in your app.<br /> <br /> This blog post will walk you through several types of notifications and the customer experience, how to send a server message through <a href="https://developer.amazon.com/docs/adm/overview.html">Amazon Devices Messaging</a> (ADM), and how to convert that message to local notifications on Fire TV through the Android Notification API.<br /> <br /> <em><strong>Note: </strong>Please be aware that ADM is required to push messages from your back-end to Amazon Fire OS devices, including Fire TV and Fire tablet.</em></p> <p>&nbsp;</p> <h3><strong>Local notifications</strong></h3> <p>There are <strong>3 types</strong> of local notifications supported on Fire TV:</p> <ul> <li>Heads-up notifications</li> <li>Standard notifications</li> <li>Toasts</li> </ul> <p>&nbsp;</p> <h4><strong>1. Heads-up notifications</strong></h4> <p>Fire TV by default sends notifications to customers when there is a new app or new update app available. You can also send heads-up notifications to the customer by using the Android notification API and specify the notification priority to high.<br /> <br /> This is the method you need to invoke:</p> <pre> <code class="language-java">.setPriority(NotificationCompat.PRIORITY_HIGH)</code></pre> <p>&nbsp;</p> <p>Fire TV displays Heads up Notifications slightly differently from standard Android. See below for the user experience for Heads-up notifications on Fire TV:</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/ADMnotification.PNG" style="height:536px; width:954px" /></p> <p>&nbsp;</p> <h4><strong>2. Standard notifications</strong></h4> <p>Standard notifications will be sent when the developer did not specify the notification priority. Standard notification will be stored inside the Notifications center under the Settings of Fire TV. These notifications are not shown as heads-up display and hence do not interrupt the user experience in any visible way when the customer is using a different app or is navigating the main Fire TV UI.<br /> <br /> This is what the Notifications center looks like on Fire TV:</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/standard_notifications.PNG" style="height:536px; width:954px" /></p> <p>&nbsp;</p> <h4><strong>3. Toasts</strong></h4> <p>Toasts are small pop-ups that appear within your app briefly and then disappear, with no ability for the user to interact with the message. Unlike heads-up notifications, toasts are not stored within the Notification Center. Developers can send a Toast message by using the <strong>makeText() </strong>and <strong>show()</strong> methods below. The display duration can also be adjusted in the <strong>makeText()</strong> method.:</p> <pre> <code class="language-java"> Context context = getApplicationContext(); CharSequence text = title + message; int duration = Toast.LENGTH_LONG; Toast toast = Toast.makeText(context, text, duration); toast.show();</code></pre> <p>&nbsp;</p> <p>This is how Toast messages are displayed on Fire TV:</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/toastnotification.PNG" style="height:536px; width:954px" /></p> <p>&nbsp;</p> <h3><strong>How to choose a notification method</strong></h3> <p>While toasts notification allow a pop-up dialog to appear, Heads-up notification could also draw the customer’s attention via richer graphics and direct customers to launch your app immediately.<br /> <br /> <strong><u>Note:</u>&nbsp;</strong>Keep in mind that <strong>your app should not send a Heads-Up notification when another app is in the foreground</strong>, as this would provide a broken customer experience. Build your notification mechanism in order to verify if another app is in the foreground and do not display Heads-Up notifications in that case.</p> <p>&nbsp;</p> <p>For less critical notifications such as app release information, standard notifications could be are a better choice instead of Heads-up notifications&nbsp;since they will not distract customers while they are consuming content.&nbsp; Always be mindful of the customer experience when planning your notification mechanism.</p> <p>&nbsp;</p> <h3><strong>Server-side messaging using ADM</strong></h3> <p>Server-side messaging solution provide a scalable communication tools to mobile developers. Developers can send messages to millions of cross platform devices and connect with customers over channels like email, SMS, push, or voice.<br /> <br /> One example of server-side messaging solution which supports Amazon Device Messaging (ADM) -required for sending messages to Fire OS devices such as Fire TV - is <strong>AWS Pinpoint</strong>. With AWS Pinpoint, developer can also measure customer engagement and generate analytical data from its applications. A marketing team can then use this insight to strengthen campaigns and determine how to most effectively communicate with its customers.<br /> <br /> In this blog post, we will instead focus on the <strong>ADM implementation by using the </strong><a href="https://amzndevresources.com/adm/sdk/AmazonDeviceMessaging.zip"><strong>ADM SDK</strong></a> available on <a href="https://developer.amazon.com/docs/apps-and-games/sdk-downloads.html#adm">Amazon Developer portal</a>. Before you read through the setup procedures below, you can find more information on the ADM Architecture and Roles/Responsibilities for each ADM component by referring to the <a href="https://developer.amazon.com/docs/adm/overview.html">ADM Overview page</a>.<br /> &nbsp;</p> <h4><strong>1. Server setup</strong></h4> <p>Download the <a href="https://developer.amazon.com/docs/adm/overview.html#download">ADM SDK</a> and under the example folder, you could see the server scripts inside the <strong>server-python folder</strong>. To run the server, perform the following actions:</p> <ol> <li>Change the value of PORT at the beginning of server.py to the port you would like the server to listen on. Make sure this port is opened and accessible before proceeding.</li> <li>Change the values of PROD_CLIENT_ID and PROD_CLIENT_SECRET to the ones you received from Amazon. These are also located at the beginning of server.py.</li> <li>Run from the command line: &gt; python server.py</li> </ol> <p>For #2, PROD_CLIENT_ID and PROD_CLIENT_SECRET, <a href="https://developer.amazon.com/docs/adm/obtain-credentials.html">these credentials are assigned to you by Amazon</a>. Your servers use both pieces of these credentials in their requests to obtain access tokens.<br /> <br /> After #3 above, you can access the server through a browser. In the image below you can see the Server UI for sending message to the clients.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/image_33.png" style="height:274px; width:1500px" />The diagram below shows you the high level message flow from your server to your app. In this example, “your server” will be replaced with a self-contained sample web application written as a Python script which is provided as part of the ADM SDK. The web application simulates a range of tasks your server could implement to send messages to client applications.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/image_34.png" style="height:153px; width:628px" /></p> <p>&nbsp;</p> <h4><strong>2. Client setup</strong></h4> <p>Under the same example folder, you should see the ADMMessenger folder where the client project is located.<br /> <br /> To run the client:</p> <ol> <li>In ADMMessenger/assets/api_key.txt, replace the line of text you see with the API Key you received from Amazon.</li> <li>In ADMMessenger/res/values/strings.xml, change the values of server_address and server_port to values that reference your server.</li> </ol> <pre> <code class="language-java">&lt;string name=&quot;server_address&quot;&gt;http://xxx.xxx.xx.xx&lt;/string&gt; &lt;string name=&quot;server_port&quot;&gt;8080&lt;/string&gt;</code></pre> <p>&nbsp;</p> <p>When you completed the setting above, you can build, install and run the client app from Android studio.<br /> <br /> Here is the sample code, based on the ADM SDK, for how we could build local notification, with the data from JSON file through ADM, and display them on the Fire TV as a head-ups notification.<br /> &nbsp;</p> <pre> <code class="language-java">public static void createADMNotification(final Context context, final String titleKey, final String msgKey, final String urlKey, final String timeKey, final String intentAction, final String title, final String msg, final String url, final String time) { /* Clicking the notification should bring up the MainActivity. */ /* Intent FLAGS prevent opening multiple instances of MainActivity. */ final Intent notificationIntent = new Intent(context, MainActivity.class); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); notificationIntent.putExtra(titleKey, title); notificationIntent.putExtra(msgKey, msg); notificationIntent.putExtra(urlKey, url); notificationIntent.putExtra(timeKey, time); /* Android reuses intents that have the same action. Adding a time stamp to the action ensures that */ /* the notification intent received in onResume() isn't one that was recycled and that may hold old extras. */ notificationIntent.setAction(intentAction + time); final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent,Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL); Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.amazon1280); Notification.Builder builder; if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) { builder = new Notification.Builder(context, CHANNEL_ID) .setContentTitle(title) .setContentText(msg) .setContentText(url) .setColor(Color.BLUE) .setSmallIcon(R.drawable.ic_launcher_foreground) .setLargeIcon(largeIcon) .setContentIntent(pendingIntent) .setAutoCancel(true); } else { builder = new Notification.Builder(context) .setContentTitle(title) .setContentText(msg) .setContentText(url) .setColor(Color.BLUE) .setPriority(NotificationCompat.PRIORITY_HIGH) .setSmallIcon(R.drawable.ic_launcher_foreground) .setLargeIcon(largeIcon) .setContentIntent(pendingIntent) .setAutoCancel(true); } Notification notification = builder.build(); NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE); notificationManager.notify(context.getResources().getInteger(R.integer.sample_app_notification_id), notification); }</code></pre> <p>&nbsp;</p> <p>Here is what the customer experience looks like when the alert was sent from the app:</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/ADMnotification_1.PNG" style="height:536px; width:954px" /></p> <p>&nbsp;</p> <h3><strong>Conclusion</strong></h3> <p>Together with marketing communications services such as AWS Pinpoint, Amazon Device Messaging, and the local notification features, Fire TV provides a powerful way to increase engagement.&nbsp; Learn more with our&nbsp;<a href="https://developer.amazon.com/docs/adm/overview.html">documentation for Amazon Device Messaging</a> (ADM).</p> <p>&nbsp;</p> <p>&nbsp;</p> <p><strong><img alt="KevinKaiTsang.jpg" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/Kevin_Hing_Kai_Tsang.JPG" style="height:160px; width:160px" /></strong></p> <p><em>Kevin Tsang is an Amazon Solutions Architect experienced with Fire TV and Fire tablet app development, Live TV, Catalogue Integration, and Alexa Video Skills implementation.</em></p> /blogs/appstore/post/50b1ca0f-bbec-48ec-9eea-3c395efb8f9f/amazon-appstore-to-support-android-app-bundle Amazon Appstore to support Android App Bundle schwille 2021-07-16T14:18:43+00:00 2021-07-16T17:48:10+00:00 <p>Amazon Appstore to support new publishing format - App Bundles</p> <p>Earlier this year, <a href="https://android-developers.googleblog.com/2021/06/the-future-of-android-app-bundles-is.html">Android App Bundle format</a> was announced by Google as mandatory open-source format for new Google Play app submissions starting August 2021. Amazon Appstore is actively working to support the new format, which will provide benefits such as smaller app size downloads for customers and on-demand downloads for features and assets. These changes benefit customers by helping them download specific aspects of an app in real-time as needed.<br /> <br /> For Amazon Appstore developers, in addition to the existing APK format, we are working to support the app bundles format across all types of submissions. We will share updates later this year on our progress to continue making app submission as simple and friction-less as possible for our developers.<br /> &nbsp;</p> <hr /> <p><strong>FAQs</strong><br /> <br /> <br /> <strong>1. Will Android App Bundles be mandated for Amazon Appstore?</strong><br /> App Bundles will be completely optional, and developers will be able to continue submitting apps using existing APK format.<br /> <br /> <strong>2. Will there be any changes to the way developers submit apps ?</strong><br /> There are no changes to the app submission process. For both app formats (APK or bundle), developers will continue to submit apps in the same way as before.<br /> <br /> <strong>3. Will I need to resubmit my app if it was published using APK?</strong><br /> No, you will not need to resubmit your app if it was submitted and published in APK format earlier. You can continue publishing new apps and updates to existing apps using APK format. In order to utilize app bundles, developers would need to plan future submissions using the bundles format (*.aab), however, there will be no changes in the way developers currently submit apps to Appstore.<br /> <br /> <strong>5. Will my apps get all available App Bundle benefits when Amazon Appstore starts supporting it?</strong><br /> We will support upload of apps in App Bundle format. We have a roadmap to enable customer experience benefits incrementally over time. We will share our roadmap and more details closer to rollout.<br /> <br /> <strong>6. Will I need to submit my app signing key to Amazon to submit App Bundles?</strong><br /> No, Amazon Appstore does not require you to share your app signing key to submit App Bundles. You will continue to sign App Bundles similar to the way that you sign APKs and submit today.<br /> &nbsp;</p> <p>&nbsp;</p> /blogs/appstore/post/945e954c-08f4-4c31-8829-8a5ef625cba1/how-to-build-a-touch-enabled-fire-tv-app-using-webview-and-html5-web-app How to build a Touch-enabled Fire TV app using WebView and HTML5 web-app schwille 2021-07-13T20:23:45+00:00 2021-07-13T20:37:53+00:00 <p><a href="https://developer.amazon.com /blogs/appstore/post/945e954c-08f4-4c31-8829-8a5ef625cba1/how-to-build-a-touch-enabled-fire-tv-app-using-webview-and-html5-web-app"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_firetv_touch_html5JS_954x240.png" style="height:240px; width:954px" /></a></p> <p>This tutorial will show you how to&nbsp;create a wrapper app for Fire TV devices using <a href="https://developer.amazon.com/docs/fire-tv/hybrid-apps-overview.html#amazon-webview-awv">Amazon WebView (AWV)</a>&nbsp;along with touch-based UX best practices.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_firetv_touch_html5JS_954x240.png" /></p> <p>Fire TV offers a variety of ways for developers to present content to customers. An HTML5 based web application could be a good candidate to provide a customer experience that is consistent with the rest of your service and have faster time to market, making it easier to deploy your apps in several marketplaces &amp; devices. It also allows for an easier roll out of updates without having to build &amp; release the whole app.</p> <p>In this tutorial, you will learn how to create a <strong>wrapper app</strong> for Fire TV devices using <a href="https://developer.amazon.com/docs/fire-tv/hybrid-apps-overview.html#amazon-webview-awv">Amazon WebView (AWV)</a> technology that works using both D-Pad and touch interactions. <a href="https://developer.amazon.com/docs/fire-tv/design-and-user-experience-guidelines.html">The Fire TV documentation on UX Best Practices</a> covers this basic aspects of app navigation and input.</p> <p>&nbsp;</p> <p>The tutorial will cover 4 key steps:</p> <ul> <li><u>Step 1</u>: Declare Touchscreen hardware features</li> <li><u>Step 2</u>: Adding support for Amazon WebView (AWV) and enabling JavaScript</li> <li><u>Step 3</u>: Handling page navigation and device configuration changes</li> <li><u>Step 4</u>: Handling interactions between WebView and web application</li> </ul> <p>&nbsp;</p> <h3><strong>Step 1: Declare Touchscreen hardware features</strong></h3> <p>To enable basic touch interaction events such as tapping and dragging, add <code>android.hardware.touchscreen</code> declaration to your <code>AndroidManifest.xml</code> file. This feature indicates that the app is compatible with a device if that device has an actual touchscreen or emulates a touchscreen (&quot;fake touch&quot; interface). We need to add this as we will be targeting Fire TV devices with a touchscreen.</p> <p><strong><code>AndroidManifest.xml</code></strong></p> <pre> <code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; &lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; ...&gt; &lt;uses-feature android:name=&quot;android.hardware.touchscreen&quot; android:required=&quot;false&quot; /&gt; ... &lt;/manifest&gt;</code></pre> <p>Since your web application is hosted online, your wrapper app must have access to the Internet. To get internet access, request the <a href="https://developer.android.com/reference/android/Manifest.permission#INTERNET"><code>INTERNET</code></a> permission in your <a href="https://developer.android.com/reference/android/Manifest.permission">manifest</a> file. For example:</p> <pre> <code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; &lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; xmlns:tools=&quot;http://schemas.android.com/tools&quot; package=&quot;com.example.myapplication&quot; tools:ignore=&quot;MissingLeanbackLauncher&quot;&gt; &lt;uses-feature android:name=&quot;android.hardware.touchscreen&quot; android:required=&quot;false&quot; /&gt; &lt;uses-feature android:name=&quot;android.software.leanback&quot; android:required=&quot;false&quot; /&gt; &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt; &lt;application android:allowBackup=&quot;true&quot; android:banner=&quot;@drawable/amazon_firetv&quot; android:icon=&quot;@drawable/ic_launcher&quot; android:label=&quot;@string/app_name&quot; android:supportsRtl=&quot;true&quot;&gt; &lt;activity android:name=&quot;.MainActivity&quot; android:configChanges=&quot;fontScale&quot; android:label=&quot;@string/player_activity_name&quot; android:launchMode=&quot;singleTop&quot; android:theme=&quot;@style/AppTheme&quot;&gt; &lt;intent-filter&gt; &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt; &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt; &lt;/intent-filter&gt; &lt;/activity&gt; &lt;uses-library android:name=&quot;com.amazon.webview&quot; android:required=&quot;false&quot; /&gt; &lt;/application&gt; &lt;/manifest&gt;</code></pre> <h3>&nbsp;</h3> <h3><strong>Step 2: Adding support for Amazon WebView (AWV) and enabling JavaScript</strong></h3> <p>The <code>[WebView](https://developer.android.com/reference/android/webkit/WebView)</code> class is an extension of Android's <a href="https://developer.android.com/reference/android/view/View"><code>View</code></a> class that allows you to render web pages as a part of your <a href="https://developer.android.com/reference/android/app/Activity"><code>Activity</code></a> layout. It does not include any features of a fully developed web browser, such as navigation controls or an address bar. All that <code>WebView</code> does, by default, is show a web page.</p> <p>To add a <code>WebView</code> to your app in the layout, add the following code to your activity's layout XML file:</p> <p><strong><code>activity_main.xml</code></strong></p> <pre> <code class="language-xml">&lt;FrameLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot; xmlns:tools=&quot;http://schemas.android.com/tools&quot; android:id=&quot;@+id/container&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;match_parent&quot; android:fitsSystemWindows=&quot;true&quot; tools:context=&quot;.MainActivity&quot;&gt; &lt;WebView android:id=&quot;@+id/web_view&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;match_parent&quot; android:layout_gravity=&quot;center&quot; /&gt; &lt;/FrameLayout&gt;</code></pre> <p>Now, within your Fire TV app, create an <a href="https://developer.android.com/reference/android/app/Activity"><code>Activity</code></a> that contains a <code>WebView</code>, then use that to display your online web application in <a href="https://developer.android.com/reference/android/app/Activity#onCreate(android.os.Bundle,%20android.os.PersistableBundle"><code>onCreate()</code></a>). To load a web page in the <code>WebView</code>, use <a href="https://developer.android.com/reference/android/webkit/WebView#loadUrl(java.lang.String"><code>loadUrl()</code></a>). In the following example, <code>mBaseUri</code>, holds the address to your online hosted web application.</p> <p><strong><code>MainActivity.java</code></strong></p> <pre> <code class="language-java">public class MainActivity extends Activity { // Address to your online hosted web application private final String mBaseUri = &quot;https://mysampleapp.com&quot;; private Context mContext = null; private WebView mWebView; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = this.getApplicationContext(); // An activity is a single, focused thing that the customer can do. // Activity class takes care of creating a window for you in which // you can place your layout resource defining your UI. // In this example layout resource is defined in activity_main.xml. setContentView(R.layout.activity_main); // Retrieve the WebView widget in UI that you need to interact with. // In this example WebView widget is identified by &quot;web_view&quot; in activity_main.xml. mWebView = findViewById(R.id.web_view); mWebView.loadUrl(mBaseUrl); } ... }</code></pre> <h4>Amazon WebView (AWV) optimizations</h4> <p>All Fire TV devices running on Fire OS 5 and later include <a href="https://developer.amazon.com/docs/fire-tv/hybrid-apps-overview.html#amazon-webview-awv">Amazon WebView (AWV)</a> as a transparent replacement for the standard <a href="https://developer.android.com/guide/webapps/webview">Android WebView</a> class. AWV uses a custom build of Chromium that has been optimized specifically for Fire OS, devices providing faster and more efficient rendering, better video performance, and improved resource management.</p> <p>To enable support for AWV, specify <code>com.amazon.webview</code> shared library that the application must be linked against. This tells the system to include the library's code in the class loader for the package.</p> <p><strong><code>AndroidManifest.xml</code></strong></p> <pre> <code class="language-xml">&lt;application android:allowBackup=&quot;true&quot; android:banner=&quot;@drawable/amazon_firetv&quot; android:icon=&quot;@drawable/ic_launcher&quot; android:label=&quot;@string/app_name&quot; android:supportsRtl=&quot;true&quot;&gt; ... &lt;uses-library android:name=&quot;com.amazon.webview&quot; android:required=&quot;false&quot; /&gt; &lt;/application&gt;</code></pre> <p>To take a full advantage of various optimizations available with AWV, you can also enable additional functionalities by passing command line options in <a href="https://developer.android.com/reference/android/app/Activity#onCreate(android.os.Bundle,%20android.os.PersistableBundle"><code>onCreate()</code></a>) method of your app’s <a href="https://developer.android.com/reference/android/app/Activity"><code>Activity</code></a> that contains a <code>WebView</code>. For example:</p> <p><strong><code>MainActivity.java</code></strong></p> <pre> <code class="language-java">public class MainActivity extends Activity { private static final String TAG = MainActivity.class.getSimpleName(); ... private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ArrayList&lt;String&gt; cmd_args = new ArrayList&lt;&gt;(); cmd_args.add(&quot;enable-system-key-events-processing&quot;); cmd_args.add(&quot;enable-awv-mode&quot;); cmd_args.add(&quot;amazon-player-type=exoplayer&quot;); cmd_args.add(&quot;enable-experimental-webkit-features&quot;); cmd_args.add(&quot;enable-use-wide-viewport&quot;); cmd_args.add(&quot;enable-full-paint-on-dom-update&quot;); cmd_args.add(&quot;enable-devtools-experiments&quot;); try { Class&lt;?&gt; webViewExtensionClassObj = Class.forName(&quot;com.amazon.webview.extensions.WebViewExt&quot;); Method setOptionsMethod = webViewExtensionClassObj.getDeclaredMethod(&quot;setEngineOptions&quot;, List.class); setOptionsMethod.invoke(webViewExtensionClassObj, cmd_args); } catch (Exception e) { Log.e(TAG, &quot;com.amazon.webview load Exception: &quot; + Log.getStackTraceString(e)); } ... mWebView = findViewById(R.id.web_view); ... } ... }</code></pre> <p><em><strong>Note</strong>: Enabling AWV support using <code>com.amazon.webview</code> and optimization via flags added in <code>Activity</code> class is completely optional. Developers are advised to measure performance of their applications against individual flags.</em></p> <h4>&nbsp;</h4> <h4><strong>Enabling JavaScript</strong></h4> <p>As your web application is most likely to use JavaScript for enabling various customer interactions and communicate with your backend services, you must enable JavaScript for your <code>WebView</code>.</p> <p>JavaScript is disabled in a <code>WebView</code> by default. You must enable it through the <a href="https://developer.android.com/reference/android/webkit/WebSettings"><code>WebSettings</code></a> attached to your <code>WebView</code>. To achieve this retrieve <code>WebSettings</code> with <a href="https://developer.android.com/reference/android/webkit/WebView#getSettings("><code>getSettings()</code></a>), then enable JavaScript with <a href="https://developer.android.com/reference/android/webkit/WebSettings#setJavaScriptEnabled(boolean"><code>setJavaScriptEnabled()</code></a>).</p> <p><strong><code>MainActivity.java</code></strong></p> <pre> <code class="language-java">public class MainActivity extends Activity { private final String mBaseUrl = &quot;https://mysampleapp.com&quot;; private Context mContext = null; private WebView mWebView; ... @Override protected void onCreate(Bundle savedInstanceState) { ... mWebView = findViewById(R.id.web_view); WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); ... mWebView.loadUrl(mBaseUrl); } ... }</code></pre> <p><code>WebSettings</code> provides access to a variety of other settings that you might find useful. For example, if you're developing a web application that's designed specifically for the <code>WebView</code> in your Fire TV app, then you can define a custom user agent string with <a href="https://developer.android.com/reference/android/webkit/WebSettings#setUserAgentString(java.lang.String"><code>setUserAgentString()</code></a>), then query the custom user agent in your web page to verify that the client requesting your web page is actually your Fire TV app.</p> <h3>&nbsp;</h3> <h3><strong>Step 3: Handling page navigation and device configuration changes</strong></h3> <p><em><strong>Note:</strong> If your web application is built as a <a href="https://developer.mozilla.org/en-US/docs/Glossary/SPA">SPA (Single-page application)</a> that only loads a single web document, and then updates the body content of that single document via JavaScript APIs, <u>you can skip this step</u>.</em></p> <h4>&nbsp;</h4> <h4><strong>Navigation for non-SPA web applications</strong></h4> <p>In case your web application requires customers to click a link for navigating to a different section of the app, for example a navigation menu, when the customer clicks a link in your <code>WebView</code>, the default behaviour is for Fire TV to launch an app that handles URLs. Usually, the default web browser opens and loads the destination URL. However, you can override this behavior for your <code>WebView</code>, so links open within your <code>WebView</code>. You can then allow the customer to navigate backward and forward through their web page history that's maintained by your <code>WebView</code>.</p> <p><em><strong>Note:</strong> For security reasons, the Fire OS browser app does not share its application data with your web application.</em></p> <p>&nbsp;</p> <p>To open all links clicked by the customer, provide a <a href="https://developer.android.com/reference/android/webkit/WebViewClient"><code>WebViewClient</code></a> for your <code>WebView</code>, using <a href="https://developer.android.com/reference/android/webkit/WebView#setWebViewClient(android.webkit.WebViewClient"><code>setWebViewClient()</code></a>). Creating a custom <code>WebViewClient</code> that overrides the <a href="https://developer.android.com/reference/android/webkit/WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView,%20java.lang.String"><code>shouldOverrideUrlLoading()</code></a>) gives the host application a chance to take control when a URL is about to be loaded in the current WebView.</p> <p>In the following example we are creating a <code>CustomWebViewClient</code> as an inner class of <a href="https://developer.android.com/reference/android/app/Activity"><code>Activity</code></a> and an instance of this new <code>WebViewClient</code> for the <code>WebView</code>.</p> <p><strong><code>MainActivity.java</code></strong></p> <pre> <code class="language-java">public class MainActivity extends Activity { private final String mBaseUrl = &quot;https://mysampleapp.com&quot;; private WebView mWebView; private CustomWebViewClient webViewClient; ... @Override protected void onCreate(Bundle savedInstanceState) { ... mWebView = findViewById(R.id.web_view); webViewClient = new CustomWebViewClient(); mWebView.setWebViewClient(webViewClient); ... mWebView.loadUrl(mBaseUrl); } ... } class CustomWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { view.loadUrl(request.getUrl().toString()); return super.shouldOverrideUrlLoading(view, request); } }</code></pre> <h4><strong>Device configuration changes in response to accessibility features customization</strong></h4> <p>There are various accessibility features available on Fire TV. One of them is the Text Banner, an on-screen text banner that will help customers with visual impairments view the text on their screen. When the customer changes accessibility features during the runtime, activity state changes occur causing device configuration changes. This could interfere with <code>WebView</code> object's activity to be destroyed and a new activity to be created, which also creates a new <code>WebView</code> object that loads the destroyed object's URL.</p> <p>In order to handle configuration changes during runtime so that your application doesn't need to update resources during a specific configuration change and avoid the activity restart, declare that your activity handles the <code>fontScale</code> configuration change itself which prevents the system from restarting your activity.</p> <p><strong><code>AndroidManifest.xml</code></strong></p> <pre> <code class="language-xml">&lt;activity android:name=&quot;.MainActivity&quot; android:configChanges=&quot;fontScale&quot; android:label=&quot;@string/player_activity_name&quot; android:launchMode=&quot;singleTop&quot; android:theme=&quot;@style/AppTheme&quot;&gt; ... &lt;/activity&gt;</code></pre> <p>Now, when the configurations change, <code>MainActivity</code> does not restart. Instead, the <code>MainActivity</code> receives a call to <a href="https://developer.android.com/reference/android/app/Activity#onconfigurationchanged"><code>onConfigurationChanged()</code></a>. This method is passed a <a href="https://developer.android.com/reference/android/content/res/Configuration"><code>Configuration</code></a> object that specifies the new device configuration. By reading fields in the <a href="https://developer.android.com/reference/android/content/res/Configuration"><code>Configuration</code></a>, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's <a href="https://developer.android.com/reference/android/content/res/Resources"><code>Resources</code></a> object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.</p> <p><strong><code>MainActivity.java</code></strong></p> <pre> <code class="language-java">public class MainActivity extends Activity { ... @Override public void onConfigurationChanged(final Configuration c) { super.onConfigurationChanged(c); mWebView.getSettings().setTextZoom((int) (c.fontScale * 100)); } }</code></pre> <p>That's all you need for a basic <code>WebView</code> that displays a web page. Additionally, you can customise your <code>WebView</code> by modifying the following:</p> <ul> <li>Enabling fullscreen support with <a href="https://developer.android.com/reference/android/webkit/WebChromeClient"><code>WebChromeClient</code></a>. This class is also called when a <code>WebView</code> needs permission to alter the web application’s UI, such as creating or closing windows and sending JavaScript dialogs to the customer.</li> <li>Handling events that impact content rendering, such as errors on form submissions or navigation with <a href="https://developer.android.com/reference/android/webkit/WebViewClient"><code>WebViewClient</code></a>. You can also use this subclass to intercept URL loading.</li> </ul> <h3>&nbsp;</h3> <h3><strong>Step 4: Handling interactions between WebView and web application</strong></h3> <h4>&nbsp;</h4> <h4><strong>Dispatching D-PAD events from webview</strong></h4> <p>All Amazon Fire TV remote controls generate <a href="http://developer.android.com/reference/android/view/KeyEvent.html"><code>KeyEvent</code></a> events for button presses, as any Android input device does. You can handle controller button input with standard Android event listener interfaces and callbacks. Neither the Amazon Fire TV Remote nor the Voice Remote raises motion events (from the Android <a href="http://developer.android.com/reference/android/view/MotionEvent.html"><code>MotionEvent</code></a> class).</p> <p><em><strong>Note:</strong> The remote controllers for Fire TV Edition has some additional buttons — such as volume up/down, power, and specific app buttons that allow to directly open those apps. However, these buttons can't be mapped to events in third-party apps.</em></p> <p>&nbsp;</p> <p>You can greatly enhance the customer experience in your application by managing the D-Pad interactions. The Android framework provides APIs for detecting and processing D-Pad (or any other controller) inputs. In your Activity class, override the <a href="https://developer.android.com/reference/android/webkit/WebView#dispatchKeyEvent(android.view.KeyEvent"><code>dispatchKeyEvent()</code></a>) method, and add customizations as needed. The following example shows how to change the “BACK” key on D-Pad to go back in the <code>WebView</code> consistently, and exit the app if there is no history to navigate. Overriding the <code>dispatchKeyEvent()</code> method simultaneously allows sending the key events to <code>WebView</code> which can be handled in your web application using JavaScript to perform desired actions.</p> <p><strong><code>MainActivity.java</code></strong></p> <pre> <code class="language-java">public class MainActivity extends Activity { private final String mBaseUrl = &quot;https://mysampleapp.com&quot;; private Context mContext = null; private WebView mWebView; ... @Override protected void onCreate(Bundle savedInstanceState) { ... } ... @Override public boolean dispatchKeyEvent(KeyEvent event) { Log.d(TAG, &quot;dispatchKeyEvent : KeyCode = &quot; + event.getKeyCode() + &quot; (&quot; + KeyEvent.keyCodeToString(event.getKeyCode()) + &quot;)&quot;); switch (event.getKeyCode()) { // Handle back button from D-Pad case KeyEvent.KEYCODE_BACK: Log.d(TAG, &quot;dispatchKeyEvent : mWebView.canGoBack = &quot; + mWebView.canGoBack()); if (mWebView.canGoBack()) { // Navigate back on WebView mWebView.goBack(); } else { // WebView has no more history, exit the app finish(); } } return super.dispatchKeyEvent(event); } }</code></pre> <p>After overriding the <code>dispatchKeyEvent()</code> method, when you press Play/Pause button from the D-Pad you should see following lines in ADB logs. <code>KEYCODE_MEDIA_PLAY_PAUSE</code> is represented as <code>KeyCode = 85</code>. Please follow <a href="https://developer.amazon.com/docs/fire-tv/remote-input.html#input-event-reference">this link</a> to learn more about the Android <a href="http://developer.android.com/reference/android/view/KeyEvent.html"><code>KeyEvent</code></a> constants, and the default behavior of those buttons on Fire TV devices.</p> <pre> <code>D/MainActivity: dispatchKeyEvent : KeyCode = 85 (KEYCODE_MEDIA_PLAY_PAUSE) </code></pre> <h4><strong>Handling D-pad interactions in javascript</strong></h4> <p>D-Pad interactions by customers are received as <a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent"><code>KeyboardEvent</code></a> events in your web application’s JavaScript. To handle a <code>KeyboardEvent</code>, you need to follow these steps:</p> <p style="margin-left:40px">1.&nbsp; Select the <code>[Element](https://developer.mozilla.org/en-US/docs/Web/API/Element)</code> on which the event will fire. Since we are using <code>WebView</code> to render the web application’s content in your Fire TV wrapper application, it is recommended that events are listened on the <code>[Window](https://developer.mozilla.org/en-US/docs/Web/API/Window)</code> object.</p> <p style="margin-left:40px">2.&nbsp; Use <code>[element.addEventListener()](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)</code> to register an event handler. For each key press on D-Pad, JavaScript receives two events,</p> <p style="margin-left:80px">a. <code>keydown</code> – when a key on the D-Pad is pressed down, and auto repeats if the key is pressed down for long.</p> <p style="margin-left:80px">b. <code>keyup</code> – when a key on the D-Pad is released.</p> <p>&nbsp;</p> <p>In following example, we are using an open source HTML5 video player called <a href="https://github.com/videojs/video.js"><code>Video.js</code></a> to setup a basic media player experience. <code>keydown</code> event is triggered as soon as D-Pad interaction starts, for the demonstration purpose, we are setting the background of whole document to green color. When the key press is released, <code>keyup</code> event is triggered. The custom key handling mechanism is defined in <code>handleKeyEvent()</code> method.</p> <p><strong><code>index.html</code></strong></p> <pre> <code class="language-html">// https://videojs.com/getting-started/ const player = videojs(&quot;video&quot;, {...}); // Custom Key Event Handler const moveTime = 10; // Move time by number of seconds const handleKeyEvent = (event) =&gt; { switch(event.code) { case &quot;MediaPlayPause&quot;: case &quot;NumpadEnter&quot;: // Check is the playback is paused if (player.paused()) { videojs.log('handleKeyEvent:', 'Play', player.currentTime()); // Resume the playback player.play(); } else { videojs.log('handleKeyEvent:', 'Pause', player.currentTime()); // Pause the playback player.pause(); } break; case &quot;MediaRewind&quot;: case &quot;ArrowLeft&quot;: // Move back the playback time by 10 seconds player.currentTime((player.currentTime() - moveTime) &lt; 0 ? 0 : (player.currentTime() - moveTime)); videojs.log('handleKeyEvent:', 'Rewind', player.currentTime()); break; case &quot;MediaFastForward&quot;: case &quot;ArrowRight&quot;: // Move forward the playback time by 10 seconds player.currentTime(player.currentTime() + moveTime); videojs.log('handleKeyEvent:', 'Fast Forward', player.currentTime()); break; default: videojs.log('handleKeyEvent:', 'Unhandled event.code =', event.code); break; } } // Listen for Keyboard Events dispatched by Fire TV app's WebView window.addEventListener(&quot;keyup&quot;, (event) =&gt; { // Reset the background colour when key press is lifted document.body.style.background = &quot;&quot;; if (event.key !== undefined) { console.log('keyup:', 'event.key =', event.key); // Handle the event with KeyboardEvent.key handleKeyEvent(event); } }); window.addEventListener(&quot;keydown&quot;, (event) =&gt; { // Change background colour when key press is down document.body.style.background = &quot;green&quot;; });</code></pre> <h4>&nbsp;</h4> <h4><strong>Dispatching Touch events from webview</strong></h4> <p>Although your app should not exclusively depend on touch gestures for basic behaviors, since this form of interaction may not be available on all Fire TV devices, adding a touch-based interaction to your app wrapper application can greatly increase its usefulness and appeal.</p> <p>A touch gesture occurs when a customer places one of more fingers on the touch enabled device’s screen, and your application interprets that pattern of touch as a particular gesture. There are two phases to the gesture detection:</p> <p style="margin-left:40px">1.&nbsp; Gather data about the touch events - When a customer places one or more fingers on the screen, this triggers the callback <a href="https://developer.android.com/reference/android/view/View#onTouchEvent(android.view.MotionEvent"><code>onTouchEvent()</code></a>) on the View that received the touch events. For each sequence of touch events (position, pressure, size, addition of another finger, etc.) that is ultimately identified as a gesture, <a href="https://developer.android.com/reference/android/view/View#onTouchEvent(android.view.MotionEvent"><code>onTouchEvent()</code></a>) is fired several times.</p> <p style="margin-left:40px">2.&nbsp; Interpret the data to see if it meets the criteria for any of the gestures your app supports. The gesture starts when the customer first touches the screen, continues as the system tracks the position of the customer’s finger(s), and ends by capturing the final event of the customer’s finger(s) leaving the screen. Throughout this interaction, the <a href="https://developer.android.com/reference/android/view/MotionEvent"><code>MotionEvent</code></a> delivered to <a href="https://developer.android.com/reference/android/view/View#onTouchEvent(android.view.MotionEvent"><code>onTouchEvent()</code></a>) provides the details of every interaction. Your app can use the data provided by the <a href="https://developer.android.com/reference/android/view/MotionEvent"><code>MotionEvent</code></a> to determine if a gesture it cares about happened.</p> <p>In the following example, we are intercepting touch events in app’s <a href="https://developer.android.com/reference/android/app/Activity"><code>Activity</code></a> class, overriding the <a href="https://developer.android.com/reference/android/view/View#onTouchEvent(android.view.MotionEvent"><code>onTouchEvent()</code></a>) callback. The snippet uses <a href="https://developer.android.com/reference/androidx/core/view/MotionEventCompat#getActionMasked(android.view.MotionEvent"><code>getActionMasked()</code></a>) to extract the action the customer performed from the <code>event</code> parameter. This gives you the raw data you need to determine if a gesture you care about occurred:</p> <p><strong><code>MainActivity.java</code></strong></p> <pre> <code class="language-java">public class MainActivity extends Activity { ... @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getActionMasked(); switch(action) { case (MotionEvent.ACTION_DOWN): Log.d(TAG,&quot;Action was DOWN&quot;); return true; case (MotionEvent.ACTION_MOVE): Log.d(TAG,&quot;Action was MOVE&quot;); return true; case (MotionEvent.ACTION_UP): Log.d(TAG,&quot;Action was UP&quot;); return true; case (MotionEvent.ACTION_CANCEL): Log.d(TAG,&quot;Action was CANCEL&quot;); return true; case (MotionEvent.ACTION_OUTSIDE) : Log.d(TAG,&quot;Movement occurred outside bounds of current screen element&quot;); return true; default: return super.onTouchEvent(event); } } }</code></pre> <h4><strong>Handling Touch interactions in JavaScript</strong></h4> <p>Touch events are similar to mouse events except they support simultaneous touches and at different locations on the touch surface. The <a href="https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent"><code>TouchEvent</code></a> interface encapsulates all of the touch-points that are currently active. The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Touch"><code>Touch</code></a> interface, which represents a single touchpoint, includes information such as the position of the touch point relative to the browser viewport.</p> <p>Touch events consist of three interfaces (<a href="https://developer.mozilla.org/en-US/docs/Web/API/Touch"><code>Touch</code></a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent"><code>TouchEvent</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/TouchList"><code>TouchList</code></a>) and the following event types:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/docs/Web/Events/touchstart"><code>touchstart</code></a> - fired when a touch point is placed on the touch surface.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/touchmove_event"><code>touchmove</code></a> - fired when a touch point is moved along the touch surface.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/touchend_event"><code>touchend</code></a> - fired when a touch point is removed from the touch surface.</li> <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/touchcancel_event"><code>touchcancel</code></a> - fired when a touch point has been disrupted in an implementation-specific manner (for example, too many touch points are created).</li> </ul> <p>Continuing from the previous example of HTML5 video player, we can now add some basic touch interactions on button elements defined within the player’s media control. <code>playPauseControl</code> element targets the play/pause button from the player, and <code>muteControl</code> targets audio the mute/un-mute button. You can learn more about JavaScript Touch Events from <a href="https://developer.mozilla.org/en-US/docs/Web/API/Touch_events">MDN Web Docs</a> and a guide to adding touch events to your application is available on <a href="https://developers.google.com/web/fundamentals/design-and-ux/input/touch">Google Web Fundamentals</a>.</p> <p><strong><code>index.html</code></strong></p> <pre> <code class="language-html">const player = videojs(&quot;video&quot;, {...}); // Listen for Touch Events dispatched by Fire TV app's WebView // Play/Pause let playPauseControl = document.getElementsByClassName('vjs-play-control')[0]; playPauseControl.addEventListener(&quot;click touchstart&quot;, (event) =&gt; { videojs.log('playPauseControl', 'touched'); }); // Mute/Un-mute let muteControl = document.getElementsByClassName('vjs-mute-control')[0]; muteControl.addEventListener(&quot;click touchstart&quot;, (event) =&gt; { videojs.log('muteControl', 'touched'); });</code></pre> <h3>&nbsp;</h3> <h3><strong>Conclusion</strong></h3> <p>If you are planning to deliver an existing HTML5 based web application as a part of a client application to Fire TV, this guide will help implement the necessary interactions and navigation required for a smooth customer experience. You can learn more about how to optimize Web Apps for Fire devices on the Amazon Developer Portal.</p> <p>For more details, check out our documentation:</p> <ul> <li><a href="https://developer.amazon.com/docs/fire-tv/automotive-ux-guidelines.html">Automotive UX Guidelines</a></li> <li><a href="https://developer.amazon.com/docs/fire-tv/automotive-developer-reference.html">Automotive Developer Reference</a></li> <li>Official <a href="https://developer.android.com/training/tv/start/navigation">Android documentation on directional navigation</a></li> <li><a href="https://developer.amazon.com/docs/fire-tv/getting-started-with-web-apps.html">Getting Started with Web Apps on Fire TV</a></li> </ul> <p>&nbsp;</p> <p>&nbsp;</p> <p><strong><img alt="MayurAhir.jpg" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/Mayur_Ahir_Profile.jpg" style="height:160px; width:160px" /></strong></p> <p><em>Mayur Ahir is an Amazon Solutions Architect with domain expertise in developing cross-platform HTML5 applications for devices powered by Fire OS and Alexa, such as Fire TV, Fire Tablets, and Echo Show.</em></p> /blogs/appstore/post/4e284d99-98f7-4687-8a00-0e362eb000dd/recommendations-on-fire-tv Recommendations on Fire TV - Optimize for different versions of Fire OS schwille 2021-07-02T16:48:18+00:00 2021-07-06T13:01:38+00:00 <p><a href="https://developer.amazon.com /blogs/appstore/post/4e284d99-98f7-4687-8a00-0e362eb000dd/recommendations-on-fire-tv"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/Reya_header.png" /></a></p> <p>Optimize your apps to send recommendations to users about movies, shows, music, and games.&nbsp;</p> <p>Fire TV devices offer a variety of entertainment options for the over 50 million monthly active users worldwide.&nbsp; With so many choices available, simplify content discovery with recommendations. Your app can send recommendations to users about the movies, shows, music, and games that you want them to watch.</p> <p>Recommendations appear on a &quot;Recommended By Your Apps&quot; (<a href="https://developer.amazon.com/docs/fire-tv/recommendations-overview.html">ReYA</a>) row on the Amazon Fire TV home screen and shows all recommendations from apps the user has currently installed (and opened at least once).</p> <p>&nbsp;</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/ReYA.jpg" style="display:block; height:536px; margin-left:auto; margin-right:auto; width:954px" /></p> <p>&nbsp;</p> <p>ReYA in Fire TV is based on the <a href="https://developer.android.com/training/tv/discovery/recommendations">Android Recommendations API</a>, which in turn, is based on Android notifications.&nbsp; Amazon <a href="https://developer.amazon.com/docs/fire-tv/recommendations-send-recommendations.html#amazon-enhancements">extends the Android recommendations API</a> to provide deeper integration with Amazon Fire TV.</p> <p>If developers have optimized their apps for Fire OS 5, they may see their recommendations are missing from the ReYA row on Fire OS 7 devices; this is because Fire OS 7 is built on Android 9, which introduces changes to the recommendations engine. The Fire TV home screen, therefore, displays recommendations in two different ways depending on the version of Fire OS running on the device:</p> <p>&nbsp;</p> <ul> <li><u>Fire OS 5 and 6</u>: Older Fire TV devices are on Fire OS 5 (Android 5.1, API level 22). Before Android 8.0, Android shows all recommendations in a single recommendations row that always appears on the screen. Fire OS 6 is based on Android Nougat (Android 7.1.2, level 25), so the ReYA row will still show up correctly on these devices with no changes from Fire OS 5.</li> </ul> <p>&nbsp;</p> <ul> <li><u>Fire OS 7</u>: In Android 8.0 (API level 26) and later, apps can show recommendations in one or more channels that appear on separate rows. One channel (the default channel) always appears. Hence, in Fire OS 7, which is based on Android 9.0 Pie (API level 28), notifications that any app sends must be <a href="https://developer.amazon.com/docs/fire-tv/recommendations-send-recommendations.html#notifications">assigned to a channel</a> (since recommendations are a kind of notification). If an app sends notifications or recommendations, then it must create a channel and associate the channel with the notification. A notification without a channel ID will be dropped.</li> </ul> <p>&nbsp;</p> <p>To be able to show recommendations on all versions of Fire TV, apps<strong> should implement both recommendation APIs, </strong>i.e. for <a href="https://developer.amazon.com/docs/fire-tv/recommendations-send-recommendations.html">Fire OS 5 and 6</a> and for <a href="https://developer.amazon.com/docs/fire-tv/fire-os-7.html#notifications">Fire OS 7</a>.</p> <p>&nbsp;</p> <p>Interested in learning more or ready to get started? Check out these resources:</p> <ul> <li><a href="https://developer.amazon.com/docs/fire-tv/recommendations-overview.html">Recommended By Your Apps technical documentation</a></li> <li><a href="http://developer.amazon.com/docs/fire-tv/device-specifications.html">Fire TV device specs</a></li> <li><a href="https://developer.amazon.com/docs/fire-tv/fire-os-7.html">Developing for Fire OS 7</a></li> </ul> <p>&nbsp;</p> <p style="text-align:left"><strong><img alt="PriyaRajan.jpg" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/priyarajan.jpg" /></strong></p> <p><em>Priya Rajan is an Amazon Solutions Architect with domain expertise in app development on Fire TV, Fire tablets, and Echo Show devices.</em></p> <p>&nbsp;</p> /blogs/appstore/post/a7583854-9367-4480-99c4-15f91456558c/amazon-and-microsoft-create-new-opportunities-for-developers-and-increase-return-on-investment-in-the-amazon-appstore Amazon and Microsoft create new opportunities for developers and increase return on investment in the Amazon Appstore schwille 2021-06-24T15:53:30+00:00 2021-06-24T15:53:30+00:00 <p><a href="https://developer.amazon.com /blogs/appstore/post/a7583854-9367-4480-99c4-15f91456558c/amazon-and-microsoft-create-new-opportunities-for-developers-and-increase-return-on-investment-in-the-amazon-appstore"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_msftappstore_954x240.png" style="height:240px; width:954px" /></a></p> <p>The Amazon Appstore will be available on Windows 11 devices, integrated into the Microsoft Store, which will dramatically expand customer reach for developers.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_msftappstore_954x240.png" style="height:240px; width:954px" /></p> <p>&nbsp;</p> <p>Today, at the <a href="https://blogs.windows.com/windowsexperience/2021/06/24/introducing-windows-11/" target="_blank">Microsoft’s Windows Event</a>, Microsoft and Amazon announced plans to bring the Amazon Appstore to Windows 11. With the upcoming release of Microsoft’s operating system, Windows customers will have access to Android apps on their Windows 11 devices, expanding the selection of apps for customers across multiple genres.</p> <p>“Today we offer a broad selection of mobile apps in our Amazon Appstore, available across Fire TV, Fire Tablets, and Android devices that our customers use and enjoy every day,” said Palanidaran Chidambaram, Director of the Amazon Appstore and Cross-Screen Technology. “With this announcement, Amazon Appstore developers will now have the opportunity to make their Android apps available to hundreds of millions of Windows customers.”</p> <p>The availability of the Amazon Appstore on Windows 11 will allow developers to easily expand their app reach to Windows devices and increase their return on investment. Microsoft customers will be able to discover a new selection of Android apps in the Microsoft Store on Windows 11, and download them through the Amazon Appstore.</p> <p>The initial Amazon Appstore selection will be available to Windows customers later this year. We will have more to share in the future about how you can make your app available to Windows customers.</p> <p>&nbsp;</p> <p>Are you new to the Amazon Appstore? The best way to get started is to submit your app <a href="https://developer.amazon.com/apps-and-games/app-submission">here</a> to unlock the benefits of the Amazon Appstore.&nbsp;&nbsp;&nbsp;</p> <hr /> <p><strong>FAQs&nbsp; </strong></p> <p>&nbsp;</p> <p><strong>1. How will the Amazon Appstore work for Windows customers? </strong></p> <p>The expanded mobile app selection in the Microsoft Store is powered by the Amazon Appstore, offering more app choice and selection for Windows 11 customers. Customers can access these mobile apps within the Microsoft Store on their Windows device.<br /> &nbsp;</p> <p><strong>2. How will customers find my app in the Microsoft Store?</strong></p> <p>Windows customers will be able to find Amazon Appstore apps through integrated search, browse, and discovery in the Microsoft Store.<br /> &nbsp;</p> <p><strong>3. Will existing Amazon Appstore apps automatically be included on Windows? </strong></p> <p>The Amazon Appstore team will be in touch with developers later this year to share details on how to publish to Windows. Developers who aren’t currently part of the Amazon Appstore can submit their Android apps <a href="https://developer.amazon.com/apps-and-games/app-submission">here</a>.<br /> &nbsp;</p> /blogs/appstore/post/63ff3988-9d3d-44d5-bbec-111f46895669/how-to-add-touch-interactions-to-android-based-fire-tv-applications How to add Touch interactions to Android-based Fire TV applications schwille 2021-06-23T20:30:01+00:00 2021-07-13T14:01:48+00:00 <p><img alt="" src="https://developer.amazon.com/blogs/appstore/post/63ff3988-9d3d-44d5-bbec-111f46895669/how-to-add-touch-interactions-to-android-based-fire-tv-applications" style="height:240px; width:954px" /><a href="https://developer.amazon.com/blogs/appstore/post/63ff3988-9d3d-44d5-bbec-111f46895669/how-to-add-touch-interactions-to-android-based-fire-tv-applications"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_firetv_touchscreen_954x240.jpg" style="height:240px; width:954px" /></a></p> <p>This tutorial will show you how to add touch interactions to Android-based Fire TV apps along with touch-based UX best practices.&nbsp;</p> <p style="margin-left:0in; margin-right:0in"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_firetv_touchscreen_954x240.jpg" /></p> <p style="margin-left:0in; margin-right:0in">If you are building an app for Amazon Fire TV, it is good practice to implement the navigation and interaction of your app UI with the <strong>remote control</strong>. This can be achieved in multiple ways, but the key concept is to map the controls of the movement and interactions inside your apps to the D-Pad and buttons present on the Fire TV remote.<a href="https://developer.amazon.com/docs/fire-tv/design-and-user-experience-guidelines.html#navigation-and-input"> </a><a href="https://developer.amazon.com/docs/fire-tv/design-and-user-experience-guidelines.html#navigation-and-input">The Fire TV documentation on UX best practices</a> covers this basic aspects of app navigation and input.</p> <p style="margin-left:0in; margin-right:0in">With Fire TV expanding to automotive,&nbsp;it’s important to now <strong>add touch interactions to Fire TV apps</strong> on top of the D-Pad navigation. Customers will both be able to use remote controls, and touch on these devices.</p> <p style="margin-left:0in; margin-right:0in">In this tutorial we will see <strong>how to modify Android-based Fire TV apps</strong> designed for D-Pad to add touch interaction and how to provide a good touch-based UX.</p> <p style="margin-left:0in; margin-right:0in">The tutorial will cover 5 key steps:</p> <p style="margin-left:0in; margin-right:0in">&nbsp;</p> <ul> <li><u>Step 1</u>: Understanding UI Directional Navigation and focus with D-Pad</li> <li><u>Step 2</u>: Applying Directional Navigation to TV apps layouts</li> <li><u>Step 3</u>: Adding touch interactions for clicks: OnClickListeners</li> <li><u>Step 4</u>: Managing view focus between D-Pad and touch interactions</li> <li><u>Step 5:</u> Additional best practices and testing touch on Fire TV</li> </ul> <p>&nbsp;</p> <p><strong>Sample App - Github Repository:</strong></p> <p>As you follow through the steps of this tutorial, you can also download/clone from GitHub the <strong>Fire TV Sample App – Touch and D-Pad: </strong><a href="https://github.com/amzn/firetv-sample-touch-app"><strong>https://github.com/amzn/firetv-sample-touch-app</strong></a></p> <p>This Sample App is a companion to this tutorial as it integrates all the code shown below and allows you to quickly see it in action. You can then also use it as a starting reference when editing or creating your app.</p> <p>&nbsp;</p> <h3 style="margin-left:0in; margin-right:0in"><strong>Step 1: Understanding UI Directional Navigation and focus with D-Pad </strong></h3> <p style="margin-left:0in; margin-right:0in">Android-based applications for Fire TV should follow clear platform-level patterns for remote-based navigation. Since Fire OS is built on top of Android, it follows the same layout and design patterns as standard Android apps.</p> <p style="margin-left:0in; margin-right:0in">In order to map app UI navigation automatically to the remote D-Pad, and specify in what order the different Android Views should be navigated by the customer, we need to use <strong>Android’s Directional Navigation</strong> (<a href="https://developer.android.com/training/tv/start/navigation#modifying_directional_navigation">see Android’s documentation here</a>). This is a <strong>best practice,</strong> and if your Android application doesn’t follow this pattern, it’s important to apply the following changes as this impacts how the Touch behaviour connects to the D-Pad behaviour.</p> <p style="margin-left:0in; margin-right:0in">The Directional Navigation requires us to <strong>specify for each “focusable” view what is the next or previous view that needs to be selected</strong>. This will allow the system to automatically map what is the next view that will be focused on when a user presses the navigation buttons on their remote D-Pad (Up, Down, Left, Right).</p> <p>This is achieved by adding to our layout XML files views the following tags:</p> <pre> <code class="language-xml">android:nextFocusDown, android:nextFocusRight, android:nextFocusLeft, android:nextFocusUp</code></pre> <p style="margin-left:0in; margin-right:0in">followed by the id of the view we want the app to select next based on the order.</p> <p style="margin-left:0in; margin-right:0in">So for example</p> <pre> <code class="language-xml">&lt;TextView android:id=&quot;@+id/Item1&quot; android:nextFocusRight=&quot;@+id/Item2&quot;/&gt; </code></pre> <p>Allows the TextView called Item1 to move to the view called Item2 when the customer presses the “Right” button on their D-Pad. This applies to all directions in navigation.</p> <p>&nbsp;</p> <h3 style="margin-left:0in; margin-right:0in"><strong>Step 2: Applying Directional Navigation to TV apps layouts</strong><strong> </strong></h3> <p style="margin-left:0in; margin-right:0in">Before we apply touch interactions to our Fire TV app, we need to make sure that we create a consistent Directional Navigation experience between D-pad and touch navigation.</p> <p style="margin-left:0in; margin-right:0in">This is quite simple for basic apps interfaces, but Media and Entertainment TV Apps interfaces can be quite complex, as more often than not they need to display dynamic content. Hence, most views might be generated at runtime.</p> <p style="margin-left:0in; margin-right:0in">In order to achieve this, most developers use Android Views that can easily hold dynamic content. A good example of this is the <strong>RecyclerView</strong>. The RecyclerView is a component which allows dynamic content to be parsed from an adapter. RecyclerView is efficient and it implements one of the standard Android patterns: the ViewHolder.</p> <p style="margin-left:0in; margin-right:0in">However, since the content of a RecyclerView is dynamic, we need to make sure that the navigation between the views which are generated inside RecyclerViews is correct.</p> <p style="margin-left:0in; margin-right:0in">In order to demonstrate this, we created a simple application which simulates the standard implementation of a TV interface. This application has two main UI components:</p> <ul> <li>A first LinearLayout called “<em>menuLayout</em>”, containing a RecyclerView called “recyclerViewMenu” which itself contains the left-side menu with all the categories</li> <li>A second LinearLayout called “<em>rowsLayout</em>” containing other RecyclerViews which instead contain all the movies and content that can be played</li> </ul> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/image1_layout1.jpg" style="height:450px; width:800px" /></p> <p style="margin-left:0in; margin-right:0in"><em>On the left you can see the menuLayout in black, and on the right the rowsLayout in grey</em></p> <p style="margin-left:0in; margin-right:0in">&nbsp;</p> <p style="margin-left:0in; margin-right:0in">While this is an oversimplification for the sake of this tutorial, as your app might have more complex nesting for its views, this represents the skeleton of a dynamic Media/TV App UI.</p> <p style="margin-left:0in; margin-right:0in">What you want to do now is to define how the <strong>directional navigation</strong> works on this layout.</p> <p style="margin-left:0in; margin-right:0in">The first thing that we want to make sure of is that we can actually move from our categories menu to the content rows. So what we do is to set <strong><em>nextFocusRight</em></strong> to the first row RecyclerView for our LinearLayout:</p> <pre> <code class="language-xml">&lt;LinearLayout android:id=&quot;@+id/menuLayout&quot; [...] android:nextFocusRight=&quot;@id/rowRecyclerView1&quot;&gt; </code></pre> <p style="margin-left:0in; margin-right:0in">This way, once the user clicks on the right button, it will automatically move the focus to the first RecyclerView on the right.</p> <p>Another thing that we need to do is to set up how the navigation between the items of the RecyclerView itself works. Since the views of a RecyclerView are created dynamically at runtime, it is not practical to manually set the direction of navigation on each individual view; it cannot be achieved using the XML layout anyway. Instead, in order to do this, we need to use a very specific tag on the RecyclerView called <strong>descendantFocusability:</strong></p> <pre> <code class="language-xml">&lt;androidx.recyclerview.widget.RecyclerView android:id=&quot;@+id/recyclerViewMenu&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;wrap_content&quot; android:descendantFocusability=&quot;afterDescendants&quot; /&gt; </code></pre> <p style="margin-left:0in; margin-right:0in">By setting <strong>descendantFocusability</strong> to <strong>afterDescendants</strong> we ensure that automatically, once the views are dynamically generated, the RecyclerView itself provides focus to the items inside the RecyclerView (in this case, it gives focus to the categories defined inside the RecyclerView menu).</p> <p><strong>Note:</strong> it is important to apply this to all our RecyclerViews, as this automatically defines the relationship between the items. The great news is that we don't have to manually define the relationship between each item because Android automatically takes care of that for us as a framework level feature.</p> <p>We need to apply this to all the RecyclerViews in our right side layout as well.We need to define the Directional Navigation between each one of the RecyclerView (for sake of simplicity, in our example we defined 4 rows through 4 dedicated RecyclerView)</p> <p>At the end, our RecyclerViews should look like this:</p> <pre> <code class="language-xml">&lt;androidx.recyclerview.widget.RecyclerView android:id=&quot;@+id/rowRecyclerView1&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;wrap_content&quot; android:descendantFocusability=&quot;afterDescendants&quot; android:nextFocusDown=&quot;@id/rowRecyclerView2&quot; /&gt; &lt;androidx.recyclerview.widget.RecyclerView android:id=&quot;@+id/rowRecyclerView2&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;wrap_content&quot; android:descendantFocusability=&quot;afterDescendants&quot; android:nextFocusDown=&quot;@id/recyclerView3&quot; /&gt; &lt;androidx.recyclerview.widget.RecyclerView android:id=&quot;@+id/rowRecyclerView3&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;wrap_content&quot; android:descendantFocusability=&quot;afterDescendants&quot; android:nextFocusDown=&quot;@id/rowRecyclerView4&quot; /&gt; &lt;androidx.recyclerview.widget.RecyclerView android:id=&quot;@+id/rowRecyclerView4&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;wrap_content&quot; android:descendantFocusability=&quot;afterDescendants&quot;/&gt; </code></pre> <p>Notice how the last RecyclerView, <strong>rowRecyclerView4, </strong>doesn't have the next Focus down target. The reason for that is there is no further RecyclerView to navigate to.</p> <p>Once we complete this step, we now have a fully navigable UI using the D-Pad. We can now look into how to properly touch-enable our interface by modifying the content of our RecyclerViews.<strong> </strong></p> <p style="margin-left:0in; margin-right:0in"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/clip1_dpadnavigation1.gif" style="height:444px; width:800px" /></p> <p style="margin-left:0in; margin-right:0in"><em>You can see how the UI is fully navigable using the remote even though the views are generated dynamically. </em></p> <p style="margin-left:0in; margin-right:0in">&nbsp;</p> <h3><strong>Step 3: Adding touch interactions for clicks: OnClickListeners</strong></h3> <p>The next step is to add touch interactions when the user clicks on an item. Luckily for us, Android was built for touch in mind. To add click actions to our applications UI, we can use standard Android components which will allow us to cover both the D-Pad interaction and the touch interaction.&nbsp;</p> <p>The best and easiest way to implement click actions or touch actions on a view is to use the standard Android <strong>OnClickListener</strong>. OnClickListener allows both touch clicks and d-pad button clicks to be performed on a view. onClickListener triggers a method called <strong>onClick()</strong> where you can execute any desired operation.</p> <p><strong>Note:</strong> If you have implemented the click action on your or D-Pad based UI in any other way, you might need to add the <strong>OnClickListener</strong> on top of any custom implementation you have. This is to ensure D-Pad clicks and touch clicks both execute the desired operation.</p> <p>While on a D-Pad style navigation the size of the view is not important, , it is very relevant for touch interactions. Therefore, it's better to use larger views and areas in our UI to provide a good user experience.</p> <p>In our simple application we are going to <strong>apply the OnClickListener to the layout itself and not to the views inside of the layout.</strong> This &nbsp;could be achieved also by expanding the internal views to fill the entire layout area and apply the OnClickListener to the individual views like TextView or ImageView, however applying it to the entire layout it's a simple solution that allows us to fulfil our goal and doesn't require to change the look and feel of the UI at all.</p> <p>The views are dynamic and created by the RecyclerViews, so we need to apply individual on click listeners to each one of the created elements of each RecyclerView.We do this by modifying the code for the RecyclerView adaptors, getting a reference to the layout of each individual item of the RecyclerView and applying the onClickListener in the onBindViewHolder() method of the adapter:</p> <pre> <code class="language-java">public class MenuItemsAdapter extends RecyclerView.Adapter&lt;MenuItemsAdapter.ViewHolder&gt; { private String[] localDataSet; /** * Provide a reference to the type of views that you are using * (custom ViewHolder). */ public class ViewHolder extends RecyclerView.ViewHolder { private final TextView textView; private final ConstraintLayout menuConstraintLayout; public ViewHolder(View view) { super(view); // Define click listener for the ViewHolder's View textView = (TextView) view.findViewById(R.id.textView); menuConstraintLayout = view.findViewById(R.id.menuconstraintLayout); } public TextView getTextView() { return textView; } public ConstraintLayout getMenuConstraintLayout() { return menuConstraintLayout; } } /** * Initialize the dataset of the Adapter. * * @param dataSet String[] containing the data to populate views to be used * by RecyclerView. */ public MenuItemsAdapter(String[] dataSet) { localDataSet = dataSet; } // Create new views (invoked by the layout manager) @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // Create a new view, which defines the UI of the list item View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.menulayout, viewGroup, false); return new ViewHolder(view); } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.getTextView().setText(localDataSet[position]); viewHolder.getMenuConstraintLayout().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //In this sample app we are just logging the Click, //but here you could for example open a new Activity or select //a specific Category Log.e(&quot;Click &quot;, &quot;Clicked &quot;+localDataSet[position]); } }); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return localDataSet.length; } } </code></pre> <p style="margin-left:0in; margin-right:0in">In order to show if an item is focused on or clicked, it's important to use backgrounds and drawables that contain the different states in which a specific view can find itself.</p> <p>This is easily achieved using a selector drawable, which can contain multiple states like focused and pressed (clicked)</p> <p><strong>Menuselectordrawable.xml (used as background for our Menu Layout)</strong></p> <pre> <code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; &lt;selector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt; &lt;item android:state_pressed=&quot;true&quot; android:drawable=&quot;@android:color/holo_blue_bright&quot; /&gt; &lt;!-- pressed --&gt; &lt;item android:state_focused=&quot;true&quot; android:drawable=&quot;@android:color/holo_orange_light&quot; /&gt; &lt;!-- focused --&gt; &lt;item android:state_hovered=&quot;true&quot; android:drawable=&quot;@android:color/holo_green_light&quot; /&gt; &lt;!-- hovered --&gt; &lt;item android:drawable=&quot;@android:color/background_dark&quot; /&gt; &lt;!-- default --&gt; &lt;/selector&gt; </code></pre> <p style="margin-left:0in; margin-right:0in">In the menulayout.xml</p> <pre> <code class="language-xml">&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot; xmlns:tools=&quot;http://schemas.android.com/tools&quot; android:id=&quot;@+id/menuconstraintLayout&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;wrap_content&quot; android:background=&quot;@drawable/menuselectordrawable&quot; android:focusable=&quot;true&quot; android:focusableInTouchMode=&quot;true&quot;&gt; </code></pre> <p>At this point, all of our UI views are clickable and will show a different background color when clicked on (blue) and when focused on (orange)</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/clip2_onclicklistener1.gif" /></p> <p><em>You can see the onClickListeners being correctly triggered via the remote control.</em></p> <p>&nbsp;</p> <h3 style="margin-left:0in; margin-right:0in"><strong>Step 4: Managing view focus between D-Pad and touch interactions</strong></h3> <p style="margin-left:0in; margin-right:0in">The next step is to build a consistent experience between the d-pad and touch interactions. This means making sure that the directional navigation works consistently if we are using a remote or if we are interacting using touch.</p> <p>As we mentioned above, Android was built with touchscreen and touch interactions in mind.&nbsp; This means that the underlying layer managing our apps UI and views is mostly touch-enabled already.</p> <p>In Android, most of the views are visible and focusable by default. Actually, views inherit a parameter called <strong><em>focusable</em></strong>, which by default is set to “auto”, meaning that is up to the platform itself to determine if this view should be focusable or not. Views like Buttons, TextView, EditText are focusable by default as those are main UI components, while layouts and layout inflators are usually not automatically focusable by default, as they are usually used just to define the UI structure.</p> <p>In order to make our app fully touch-enabled, we need to make sure that the <strong>most important views in our app are focusable, </strong>and also we need to make sure that they can be focused on when the customer uses touch.</p> <p>For this reason, we are going to edit two parameters in our views:<strong> <em>focusable</em> </strong>and<strong> <em>focusableInTouchMode</em>.</strong></p> <p>Going back to our sample app, we created two new separate layouts which are used to populate the individual items inside the “Categories” RecyclerView and the “rows” RecyclerView.</p> <p style="margin-left:0in; margin-right:0in"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/image1_layout1.jpg" style="height:450px; width:800px" /></p> <p style="margin-left:0in; margin-right:0in">&nbsp;</p> <p style="margin-left:0in; margin-right:0in">We need to make sure that:</p> <ol> <li>The whole layout is treated as touch surface.</li> <li>We are enabling users to focus on the layout both using the D-Pad and touch.</li> </ol> <p>We do this by setting both focusable and focusableInTouchMode to <strong>true</strong>.</p> <p>&nbsp;</p> <p><strong>menuLayout.xml (defines the individual content of the Categories on the left, which contains only a TextView)</strong></p> <pre> <code class="language-xml">&lt;androidx.constraintlayout.widget.ConstraintLayout [...] android:id=&quot;@+id/menuconstraintLayout&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;wrap_content&quot; android:background=&quot;@drawable/menuselectordrawable&quot; android:focusable=&quot;true&quot; android:focusableInTouchMode=&quot;true&quot;&gt; &lt;TextView android:id=&quot;@+id/textView&quot; android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot; [...] /&gt; </code></pre> <p><strong>cardLayout.xml (defines the individual content of the Movies rows on the right. Each card contains a ImageView and a TextView)</strong></p> <pre> <code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; &lt;androidx.constraintlayout.widget.ConstraintLayout [...] android:id=&quot;@+id/cardconstraintLayout&quot; android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot; android:background=&quot;@drawable/selectordrawable&quot; android:focusable=&quot;true&quot; android:focusableInTouchMode=&quot;true&quot; &gt; &lt;ImageView android:id=&quot;@+id/imageView&quot; android:layout_width=&quot;150dp&quot; android:layout_height=&quot;100dp&quot; [...] /&gt; &lt;TextView android:id=&quot;@+id/textView&quot; android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot; [...] /&gt; &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt; </code></pre> <p>By doing this, we ensure that if the user touches the UI or if they navigate through the d-pad controllers, in both cases the right UI element will be focused on. See clip below for a demonstration.</p> <p style="margin-left:0in; margin-right:0in"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/clip3_touchnavigation1.gif" /></p> <p style="margin-left:0in; margin-right:0in"><em>In this clip you can see how the views are correctly clicked and focused on using touch interaction. </em></p> <p style="margin-left:0in; margin-right:0in">&nbsp;</p> <h3><strong>Step 5: Additional best practices and testing Touch on Fire TV</strong></h3> <p style="margin-left:0in; margin-right:0in">After completing the steps above, we will have successful touch-enabled the most important components of our app UI.</p> <p style="margin-left:0in; margin-right:0in">There are additional simple steps to ensure that we are providing a great user experience for both touch and d-pad navigation:</p> <p style="margin-left:0in; margin-right:0in">&nbsp;</p> <ul> <li>Ensuring that all the views that need any kind of interaction have an OnClickListener assigned to them and can be focused on</li> <li>Remember that touch interaction also includes the gestures and scrolling. Therefore do not just rely on the standard behaviours of views using D-Pad Navigation but make sure that least include ways to be scrolled through gestures (for example using scroll views and RecyclerView is where possible).</li> <li>Secondary activities of your applications (for example a Detail page or the Playback UI) need to be also touch enabled so make sure that if you have any settings page those are touch enabled as well and use the same patterns described above.</li> </ul> <p>&nbsp;</p> <p><strong>How can you test Touch on Fire TV devices without a touchscreen</strong>?</p> <p>The easiest solution is to connect a <strong>wireless mouse</strong> to your Fire TV. Mouse on Android simulates touch interaction. You can do this by:</p> <ol> <li>Going to Settings</li> <li>Go to Remote and Bluetooth Devices</li> <li>Go to Other Bluetooth devices</li> <li>Follow the on-screen instructions on how to connect your Bluetooth mouse</li> <li>After connecting the mouse, go back to your app. The mouse will show a cursor on screen you can use to simulate touch interactions, including clicks and gestures.</li> </ol> <p style="margin-left:0in; margin-right:0in">&nbsp;</p> <p><strong>Download and test the Fire TV Sample App for Touch and D-Pad</strong></p> <p>Remember to download the <strong>Fire TV Sample App – Touch and D-Pad </strong>at<strong> </strong><a href="https://github.com/amzn/firetv-sample-touch-app"><strong>https://github.com/amzn/firetv-sample-touch-app</strong></a><strong>. </strong>This app includes all the code you have seen above and is a great starting point for optimizing your Android-based Fire TV app for Touch.</p> <p style="margin-left:0in; margin-right:0in">&nbsp;</p> <h3><strong>Conclusion</strong></h3> <p style="margin-left:0in; margin-right:0in">This tutorial gave you a practical first overview on how to touch enable your Fire TV application.&nbsp;</p> <p style="margin-left:0in; margin-right:0in">For more details on these please check out our documentation:</p> <ul> <li><a href="https://developer.amazon.com/docs/fire-tv/automotive-ux-guidelines.html">Automotive UX Guidelines</a></li> <li><a href="https://developer.amazon.com/docs/fire-tv/automotive-developer-reference.html">Automotive Developer Reference</a></li> <li>Official <a href="https://developer.android.com/training/tv/start/navigation">Android documentation on directional navigation</a></li> <li><a href="https://github.com/amzn/firetv-sample-touch-app">Fire TV Sample App – Touch and D-Pad on GitHub</a></li> </ul> /blogs/appstore/post/9411ce62-6031-4dbc-a8bf-6b9c7868ee37/in-app-search-using-the-video-skills-kit-vsk-on-fire-tv In-App Search using the Video Skills Kit (VSK) on Fire TV schwille 2021-06-18T17:41:26+00:00 2021-06-18T17:41:26+00:00 <p><a href="https://developer.amazon.com/blogs/appstore/post/9411ce62-6031-4dbc-a8bf-6b9c7868ee37/in-app-search-using-the-video-skills-kit-vsk-on-fire-tv"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_vsk_954x240.png" style="height:240px; width:954px" /></a></p> <p>&nbsp;</p> <p>Create&nbsp;voice-enabled experiences in&nbsp;your Fire TV apps with the Video Skills Kit.&nbsp;&nbsp;</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_vsk_954x240.png" /></p> <p>&nbsp;</p> <p>Video Skills Kit (VSK) for Fire TV allows customers to more easily discover, find, and engage with content in your app without relying on a remote. A prerequisite to integrating your app with the VSK is to first <a href="https://developer.amazon.com/docs/catalog/getting-started-catalog-ingestion.html">ingest your catalog</a> and then integrate with <a href="https://developer.amazon.com/docs/catalog/getting-started-universal-search-and-browse.html">Universal Search and Browse on Fire TV</a>. <em>Catalog integration is currently only available to selected developers</em>. VSK works together with Catalog Integration to surface your content in multiple ways across Fire TV.</p> <p>VSK allows you to voice-enable the experience in your app. Customers can say &quot;<em>Alexa, watch Batman</em>&quot; (<a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/searchandplay.html">SearchAndPlay</a>) or &quot;<em>Alexa, find Batman</em>&quot; (<a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/searchanddisplayresults.html">SearchAndDisplayResults</a>) and Alexa will send a directive to your app, where you can take the customerinto playback or show search results. Customers can skip the use of a verb and simply say &quot;<em>Batman</em>&quot;, which is treated by Alexa as a search request. Alexa also supports more ambiguous requests such as &quot;<em>Alexa, find Tom Hanks movies</em>&quot; to find movies by actor, or &quot;<em>Alexa, find comedies</em>&quot; to search by genre.</p> <h2>&nbsp;</h2> <h2>How does VSK work on Fire TV?</h2> <p>With the App-only implementation for VSK, the Alexa Video Skill API sends directives directly to your app on a Fire TV device. Fire TV has a service called the &quot;VSK Agent&quot; that receives the Alexa directives and broadcasts them as an intent, which your app then handles through a <code>BroadcastReceiver</code>. The entire VSK integration is done directly within your Android code. If you already have Catalog Integration completed, and your app already has logic to handle text inputs for searches and other lookups, the integration can be completed in a short amount of time (a couple of weeks or less).</p> <p>Alexa service in the cloud does the hard work of interpreting the customer's request, determining the intent, and then packaging it into a directive so that you can process the requests with your own app's logic. Directives sent to your app contain a structured and resolved representation of the request, where we include entitles such as <code>Video</code>, <code>Actor</code>, <code>Genre</code> and <code>MediaType</code>. See <a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/searchandplay.html">SearchAndPlay</a> and <a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/searchanddisplayresults.html">SearchAndDisplayResults</a> for a more comprehensive list of search and play utterances and the directives sent.</p> <h2>&nbsp;</h2> <h2>Best practices for building a great search experience</h2> <p>Here are some of the best practices for building a great search experience using VSK.</p> <ul> <li>Declare search as a&nbsp;<a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/report-static-capabilities-app-only.html">static capability</a> if your app allows all customers to browse content regardless of the customer’s state (signed in) and other factors (subscription level). Otherwise, you can declare search as a <a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/report-dynamic-capabilities-app-only.html">dynamic capability</a> to gate the feature.</li> </ul> <ul> <li>Customers can say “<em>Alexa, find Breaking Bad season 2 episode 3</em>” to search (or watch) a TV series by <code>Season</code> and <code>Episode</code>. You can use Season and Episode fields to take the customer to the episode. If you're missing either season or episode number, you should determine this based on the customer's last watched episode.</li> </ul> <ul> <li>Customers can say &quot;<em>Alexa, find Tom Hanks movies</em>&quot; to find movies by the actor, or &quot;<em>Alexa, find comedies</em>&quot; to search by genre. You have the option to show search results using the <code>Actor</code>, <code>Franchise</code> or <code>Genre</code> fields, or take the customer to special pages dedicated to that particular entity. If your app does not support lookup by these fields, you should fallback to a literal text search of the value sent through in the directive.</li> </ul> <ul> <li>Leverage the <code>SearchText</code> field to help improve the relevancy of results that customers see in your app. For ambiguous requests (those that do not contain a title name), search text will give you an unstructured and more complete view of what the customer has asked - this includes additional entities and unresolved words. For example, &quot;<em>Alexa, watch popular comedy tv shows in HD</em>&quot; will give you the <code>transcribed</code> value &quot;h.d. popular comedy tv shows&quot;. Note that there is no word order or formatting guarantee. See <a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/searchandplay.html#search_text">SearchText</a> for more information.</li> </ul> <ul> <li>Search results that you present to the customer should include relevant artwork applicable to the titles. The artwork should make it easier for the customer to identify the content you are recommending in the search.</li> </ul> <h2>&nbsp;</h2> <h2>Handling SearchAndDisplayResults directives</h2> <p>Here is a <code>SearchAndDisplayResults</code> directive Alexa might send in response to a customer’s request to search for &quot;Alexa, find Batman&quot;.</p> <pre> <code>EXTRA_DIRECTIVE_NAMESPACE: Alexa.RemoteVideoPlayer EXTRA_DIRECTIVE_NAME: SearchAndDisplayResults EXTRA_DIRECTIVE_PAYLOAD_VERSION: 3 EXTRA_DIRECTIVE_PAYLOAD: payload </code></pre> <p><code>payload</code> contains the following:</p> <pre> <code>{ &quot;payload&quot;: { &quot;entities&quot;: [ { &quot;externalIds&quot;: { &quot;ENTITY_ID&quot;: &quot;0&quot; }, &quot;type&quot;: &quot;Franchise&quot;, &quot;uri&quot;: &quot;entity://avers/franchise/Batman&quot;, &quot;value&quot;: &quot;Batman&quot; } ], &quot;searchText&quot;: [ { &quot;transcribed&quot;: &quot;batman&quot; } ], &quot;timeWindow&quot;: { &quot;end&quot;: &quot;2016-09-07T23:59:00+00:00&quot;, &quot;start&quot;: &quot;2016-09-01T00:00:00+00:00&quot; } } } </code></pre> <p>With VSK integration, you create a <code>BroadcastReciever</code> class in your app. The VSK Agent packages the directive in an intent, which is passed into the <code>onReceive</code> method. With the support of a JSON parser, you can retrieve both the customer’s <a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/searchandplay.html#search_text">transcribed search request</a> under <code>transcribed</code> and the <code>entities</code> object, which contains an array of <a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/searchandplay.html#entity_types">entity objects</a> to search, such as a <code>Title</code>, <code>Genre</code>, <code>Actor</code>, <code>Franchise</code>, <code>Season</code>, <code>Episode</code>, or <code>MediaType</code>. In this example, you should show the customer search results for &quot;batman&quot; in your app.</p> <p>Once your app handled the directive successfully (or not), your <code>BroadcastReciever</code> class should send a success intent back with a status in the form of a <code>true</code> (for success) or <code>false</code> (for failure) value.</p> <h2>&nbsp;</h2> <h2>Get Started</h2> <p>Learn more about integrating VSK through our the developer documentation <a href="https://developer.amazon.com/docs/video-skills-fire-tv-apps/integration-overview-app-only.html">here</a>. You can also follow this high-level <a href="https://youtu.be/RIOl1OS8rvc">video tutorial</a> about integrating the VSK into your Fire TV app.</p> /blogs/appstore/post/93e89be7-1611-4764-8f97-f4eef0a7c0e0/coming-soon-amazon-appstore-small-business-accelerator-program Coming Soon: Amazon Appstore Small Business Accelerator Program schwille 2021-06-15T17:06:35+00:00 2021-06-17T20:42:00+00:00 <p><a href="https://developer.amazon.com/blogs/appstore/post/93e89be7-1611-4764-8f97-f4eef0a7c0e0/coming-soon-amazon-appstore-small-business-accelerator-program"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_revshare01_954x240.png" style="height:240px; width:954px" /></a></p> <p>Announcing the Amazon Appstore Small Business Accelerator Program to grow and support the developer community.&nbsp;&nbsp;</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_revshare01_954x240.png" style="display:block; height:240px; margin-left:auto; margin-right:auto; width:954px" /></p> <p>&nbsp;</p> <p><em>Authored by Palanidaran Chidambaram, Director, Amazon Appstore</em></p> <p>&nbsp;</p> <p>To further support our developers, today we are announcing the Amazon Appstore Small Business Accelerator Program. This new program enables developers to build a scalable business by reducing cloud infrastructure costs, while also offering better revenue share to help them get started on their own day one.</p> <p>Starting in Q4, for developers that earn less than $1 million in revenue in the previous calendar year, we are increasing developer revenue share and adding AWS credit options. This brings total program benefits up to an equivalent of 90 percent of revenue.&nbsp;</p> <p>When the program launches, all qualifying small developers will receive an 80/20 revenue share by default. Additionally, we will provide AWS promotional credits in an amount equivalent to 10 percent of revenue, so that developers can take advantage of the <a href="https://aws.amazon.com/campaigns/small-medium-businesses/">benefits of building on the cloud</a>.</p> <p>By helping small businesses get started with AWS through credits, we are making it easier for them to build and grow their app businesses. AWS gives developers easy access to a broad range of technologies so they can innovate faster and build nearly anything they can imagine.</p> <p>In a recent survey of mobile developers over 94% indicated they use cloud services in their application development efforts.</p> <p>With AWS, developers can access more than <a href="https://aws.amazon.com/products/?pg=WIAWS-N&amp;tile=learn_more">200 fully featured services</a> so that they can spend less time managing infrastructure and can focus more attention on customer feedback and growing their app businesses. They can deploy technology services in a matter of minutes, and get from idea to implementation several orders of magnitude faster than before.</p> <p>We also will help developers promote their content in new ways by highlighting smaller developers within our Appstore experience via a new dedicated application row.</p> <p>We believe these investments in our global developer community will generate more innovation within Amazon Appstore and increase the selection of apps for our customers.</p> <p>The Small Business Accelerator Program is one of many projects we are undertaking to grow and support the developer community across Amazon so that developers of all sizes can continue to build for our Appstore and for our customers. We’ll have more implementation details to announce later this year.</p> <p>&nbsp;</p> <p>Thank you for building with us.</p> <hr /> <p><u><strong>FAQs:</strong></u></p> <p>&nbsp;</p> <p><strong>How does eligibility for the Appstore Small Business Accelerator program work? </strong></p> <ul> <li>Developers who earned up to $1 million in the prior calendar year and developers new to Amazon Appstore are eligible.</li> <li>If an eligible developer’s revenue exceeds $1 million in the current year, they will revert to the standard royalty rate and no longer receive AWS credits for the rest of that year.</li> <li>If a developer’s revenue falls below $1 million in a future year, the developer will be eligible in the next calendar year.</li> </ul> <p>&nbsp;</p> <p><strong>How will the AWS credits work? </strong></p> <p>Developers with less than $1 million in Appstore revenue in a calendar year will receive 10% of their revenue as promotional credit for AWS services from infrastructure technologies like compute, storage, and databases–to emerging technologies, such as machine learning and artificial intelligence, data lakes and analytics, and Internet of Things. To receive the credit, when the program launches, developers can provide their AWS Account ID in the Appstore developer portal. The credit will be sent monthly and developers can choose which eligible services to apply the credit to.</p> <p>&nbsp;</p> <p><strong>How long are the AWS credits valid? </strong></p> <p>The AWS promotional credits can be used for 12 months from the date they were granted.</p> /blogs/appstore/post/1e4b2f82-9242-4570-bc00-a86da4e6a829/jp-new-fire-hd-10-tablets-and-fire-os-split-screen-feature1 新世代「Fire HD 10」と「Fire HD 10 Plus」が登場:Fire OSに2画面表示機能を新搭載 Nanaho Nishiyama 2021-06-09T00:10:20+00:00 2021-06-24T00:15:29+00:00 <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_fireTablet102021_jp_954x240.png" style="height:240px; width:954px" /></p> <p>Amazonは4月27日(火)、新世代タブレット「Fire HD 10」と「Fire HD 10 Plus」を発表しました。エンターテインメントやビデオ通話をワイドスクリーンで楽しめる洗練されたデザインになっています。</p> <p>この新世代タブレットは開発者の皆さまにとっても、新規ユーザーとの関係構築やアプリの利用・リーチ促進など、新たな価値の創出に役立つはずです。</p> <p>&nbsp;</p> <p>&nbsp;</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_fireTablet102021_jp_954x240.png" style="height:240px; width:954px" /></p> <p>(本ブログは、<a href="https://developer.amazon.com/blogs/appstore/post/1f1077ac-2e6f-4c24-b712-32cd5ac01bf5/new-fire-hd-10-tablets-with-features-like-split-screen-and-drag-drop" target="_blank">こちらの英語記事</a>を翻訳したものです)</p> <p>&nbsp;</p> <p>Amazonは4月27日(火)、新世代タブレット「Fire HD 10」と「Fire HD 10 Plus」を発表しました。エンターテインメントやビデオ通話をワイドスクリーンで楽しめる洗練されたデザインになっています。映画はもちろん、ZoomやAlexaでの通話や、ウェブブラウジング、ゲーム、読書など、この新しいタブレット1台で日々のあらゆるシーンに対応可能。家族や友達とも手軽につながることができ、新機能としてマルチタスクを可能にする2画面表示機能も搭載されています。また今回の発売に合わせて、取り外し可能なMade for Amazonのキーボード付きカバーが新たに登場。仕事効率化アプリの数も拡充されています。</p> <p><br /> この新世代タブレットは開発者の皆さまにとっても、新規ユーザーとの関係構築やアプリの利用・リーチ促進など、新たな価値の創出に役立つはずです。</p> <p>&nbsp;</p> <p><strong>仕事効率化アプリの高まるニーズ</strong></p> <p>Fireタブレットシリーズはこれまで、主にゲームやエンターテインメントの用途で使用されてきましたが、2020年になって業務効率化やコラボレーションの促進に役立つアプリが人気を博してきました。昨年、Amazonアプリストアにおける仕事効率化アプリのユーザーエンゲージメントが前年比226%向上を記録。同アプリの月間アクティブユーザー数も昨年をとおして62%増加しました(本ブログでの指標は、全世界における数値を基にしています)。キーボード付きカバーとMicrosoft 365 Personal 1年版がセットになった「エッセンシャルセット」(<a href="https://www.amazon.co.jp/dp/B08Z8M1CTJ">Fire HD 10版</a>と<a href="https://www.amazon.co.jp/dp/B08Z8QF8YY?ref=ods_ucc_tablet_B08Z8QF8YY_rc_nd_ucc">Fire HD 10 Plus版</a>)で、快適な入力操作と仕事効率化アプリをぜひお試しください。<br /> <br /> Fireタブレットでのマルチタスクに役立つアプリを開発するなら、今が絶好の機会です。やることリストの作成やリマインダーの設定、Eメールへの返信、コラボレーションの促進などを行えるアプリを開発している場合は、Amazonアプリストアでの配信をご検討ください。利用を促せるよう、アプリを新機能に対応させることも大切です。</p> <p>&nbsp;</p> <p><strong>Fire OSの新機能:2画面表示機能</strong></p> <p>Fire HD 10タブレットには、Fire OSの新たな機能として、2画面表示機能が搭載されています。10.1インチのディスプレイで、2画面表示に対応している2つのアプリを同時に開くことができるほか、ウィンドウ間でファイルをドラッグアンドドロップすることも可能です。この新機能の登場でマルチタスクが容易・快適になり、アプリのエンゲージメント向上も見込めます。<br /> <br /> 2画面表示機能の実装については、<a href="https://developer.amazon.com/ja/docs/fire-tablets/ft-screen-layout-and-resolution.html#declare-support-for-split-screen-multi-window">2画面表示機能のサポート宣言</a>をご参照ください。</p> <p>&nbsp;</p> <p><strong>性能と耐久性の向上</strong></p> <p>新Fire HD 10は、高速かつ応答性に優れたパワフルなタブレットです。オクタコアプロセッサを搭載し、RAMも前世代機より50%増量。2メガピクセル以上の解像度で10%明るくなったディスプレイで、アプリを鮮やかに表示することができます。<br /> 新タブレットの詳細や開発に関しては、 以下のリソースをご参照ください。</p> <ul> <li>テクニカルドキュメント <ul> <li><a href="https://developer.amazon.com/ja/docs/fire-tablets/ft-device-specifications-firehd-models.html">Fire HD 10のデバイス仕様</a></li> <li><a href="https://developer.amazon.com/ja/docs/fire-tablets/fire-os-7.html">Fireタブレット向けFire OS 7</a></li> <li><a href="https://developer.amazon.com/ja/docs/fire-tablets/ft-screen-layout-and-resolution.html#declare-support-for-split-screen-multi-window">2画面表示機能のサポート宣言</a></li> </ul> </li> <li><a href="https://developer.amazon.com/ja/home.html">Amazon開発者アカウントの作成</a></li> <li><a href="https://developer.amazon.com/ja/login.html">開発者コンソールへのログイン</a></li> </ul> <p>&nbsp;</p> <p>&nbsp;</p> /blogs/appstore/post/7e6eb624-40b9-4562-86f2-3b1fcd065882/tips-tricks-for-adobe-primetime-single-sign-on-sso-on-amazon-fire-tv Tips &amp; tricks for Adobe Primetime Single Sign-On (SSO) on Amazon Fire TV schwille 2021-05-18T14:09:56+00:00 2021-06-15T01:56:13+00:00 <p><a href="https://developer.amazon.com/blogs/appstore/post/7e6eb624-40b9-4562-86f2-3b1fcd065882/tips-tricks-for-adobe-primetime-single-sign-on-sso-on-amazon-fire-tv"><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_sso_954x240.png" style="height:240px; width:954px" /></a></p> <p>Tips and tricks from our Amazon Solutions Architects for&nbsp;easily implementing Single Sign-On for Fire TV, streamlining your customers' experience.&nbsp;</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/blog_sso_954x240.png" style="height:240px; width:954px" /></p> <p>&nbsp;</p> <p>Have you have followed the <strong>Adobe Primetime Single Sign-On (SSO)</strong> <strong><a href="https://tve.helpdocsonline.com/amazon-firetv-sso-programmer-kick-off-guide" target="_blank">integration</a> <a href="https://tve.helpdocsonline.com/amazon-firetv-sso-programmer-kick-off-guide" target="_blank">documentation</a></strong>, but it’s not working as expected?</p> <p>A common problem that users face is when they are not able to select a Multi-Channel Video Programming Distributor (MVPD) to log into from a list of MVPDs within your app. Another scenario is users who have successfully logged into a selected MVPD, but keep getting asked to log in every time they try to play content within your app.</p> <p>The tips in this blog will help you get past some of these very issues.</p> <p>&nbsp;</p> <p><strong>Recap of SSO on Fire TV</strong></p> <p>SSO allows customers who authenticate in one SSO app to not have to authenticate again when logging into another SSO-enabled app. Adobe provides the Primetime authentication API to facilitate this method of authentication for third party TV Everywhere (TVE) apps on Fire TV.</p> <p>Adobe provides Fire TV client developers with a stub library with its APIs. Developers need to use Fire OS system level APIs to retrieve a personalized token and use it when calling <a href="https://tve.helpdocsonline.com/amazon-firetv-sso-programmer-kick-off-guide" target="_blank">Adobe APIs</a>. And, the Fire OS system level APIs are encapsulated within a Fire TV system app, called the SSO companion app. &nbsp;</p> <p>Here is a set of diagrams that explains the SSO workflow.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/SSO_01.png" style="height:322px; width:1100px" /></p> <p>There are 4 key steps in the SSO workflow:</p> <ol> <li><u>Initialization</u>: The Android client application initiates Adobe Primetime authentication using the Adobe Primetime authentication native Amazon Fire OS library (AccessEnabler).</li> <li><u>Authentication</u>: This starts the authentication flow, or gets confirmation that the user is already authenticated.</li> <li><u>Authorization</u>: This is the authorization flow and ensures that the user is authenticated and authorized to watch the requested media. It returns a short media token.</li> <li><u>Media token issuance</u>: The short media token is then validated. If valid, it is issued to the Android client application and the media is played for the user.</li> </ol> <p>Here is a breakdown of each of these steps in the SSO process.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/SSO_02.png" /></p> <p><u>Step 1: Initialization</u></p> <p>In this step, the Android client application initializes the Adobe Primetime Authentication native Amazon Fire OS library (AccessEnabler) that has been integrated with the application. It establishes the identity of the application using a personalized token, and then proceeds to the Authentication flow.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/SSO_03.png" /></p> <p>&nbsp;</p> <p><u>Step 2: Authentication</u></p> <p>The Android client application now starts the authentication flow, or gets confirmation that the user is already authenticated. If the user is not authenticated, the user is presented with a list of MVPD providers. After the user selects a provider, the provider page is opened for the user to login. Upon successful login by the user, the authentication token is retrieved from the backend Adobe server. The token is validated and the user proceeds to the Authorization flow.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/SSO_04.png" style="height:840px; width:1314px" /></p> <p><u>Step 3: Authorization</u></p> <p>The Android client application next gets the authorization token, and then validates the authentication and authorization tokens. This means checking whether the user is authenticated and authorized to watch the requested media. If there is an authentication (AuthN) error, then the authentication flow is re-started. If there is an authorization (AuthZ) error, then the user is not authorized to watch the requested media and a relevant error message is displayed to the user. If authorization is successful, a short media token is returned by Adobe’s server.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/SSO_05.png" /></p> <p><u>Step 4: Media Token Issuance</u></p> <p>Next, the short-lived media token returned from the authorization flow is validated by the Adobe server. If the validation succeeds, the Android client application plays the requested media for the user. However, if the validation fails, The AuthZ token was invalid, the media request is refused, and an error message is displayed to the user.</p> <p>Now that you have an overview of how the SSO process flow works, let’s get into some of the issues you can face and how to solve them.</p> <p>&nbsp;</p> <p><strong><u>T</u></strong><strong><u>ip #1:</u></strong><strong> App not authorized to use SSO on Fire TV</strong></p> <p>A common SSO error, as we mentioned above, is that when users select a valid MVPD provider (see figure Step 2: Authentication) to log into in order to play their content, instead of seeing the MVPD provider’s login page, they loop back into the provider picker page.</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/SSO_06.png" /></p> <p>&nbsp;</p> <p>The user is following the entitlement steps in <a href="http://tve.helpdocsonline.com/fireos-integration-cookbook$startup_flow">this</a> workflow (also see figure 1: High-Level Single Sign-on Flow).</p> <p>Your call to authenticate the user initially should successfully log the user into to a selected MVPD using valid credentials and store the returned authentication token in the backend server. Subsequent call(s) to authenticate should ideally get confirmation that the user is already authenticated, and the user should then be authorized to single-sign on into the app. However, these calls fail, and the user keeps getting asked to login into the MVPD.</p> <p>This error may simply be a function of your app not being authorized or allow-listed to use Single-Sign-On (SSO) on Fire TV platforms.</p> <p>In the workflow in Figure 1, before the SSO companion app checks if the authentication is complete, under the hood, it checks to see if the app is allow-listed, i.e. whether the app is authorized to use SSO on Fire TV. If not, it does not allow the user to proceed beyond the MVPD list display page.</p> <p>To determine if this is indeed the reason for the login issue, look for the following error in your device logs:</p> <pre> <code>E/OttSso_OttSsoService: Trying to verify app com.yourappname.yourpackagename but Approved apps list size is 0.</code></pre> <p>This error means that your app needs to be authorized to use SSO on Fire TV platforms. Please work with your Fire TV Solutions Architect at Amazon to get this done.</p> <p>Once your app package name has been authorized for SSO, you need to wait for 24 hours for the device cache to be refreshed. If you are still facing the same error, check your package name. Please note that both the debug and production package names need to be allow-listed.</p> <p>If you are still running into the same errors, you will need to clear the companion app cache manually with the following commands:</p> <pre> <code>adb shell pm clear com.amazon.tv.ottssocompanionapp adb shell am force-stop com.amazon.tv.ottssocompanionapp </code></pre> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/SSO_07.png" style="height:194px; width:839px" /></p> <p>Now when the user goes through your app login workflow again, instead of the E/OttSso_OttSsoService error in your device logs, they will be able to log in successfully with valid credentials. And the following line will appear in the device logs as proof that your app is now allow-listed for SSO on Fire TV:</p> <pre> <code>I OttSso_OttSsoService: app setup complete, number of approved apps </code></pre> <p>&nbsp;</p> <p><strong><u>Tip #2:</u></strong><strong> Adobe SDK and SSO Companion version mismatch</strong></p> <p>The Adobe SDK that your app has integrated with is a stub library which makes calls to the SSO companion system app on Fire TV to deliver SSO functionality. For SSO to work correctly with your apps on Fire TV, both the SSO companion app and the Adobe stub library integrated within your app should always be up-to-date with their most recent versions.</p> <p>To check the version of this app via ADB, use the following command:</p> <p><u>Mac: </u></p> <pre> <code>adb shell dumpsys package com.amazon.tv.ottssocompanionapp | grep versionCode</code></pre> <p><u>Windows:</u></p> <pre> <code>adb shell dumpsys package com.amazon.tv.ottssocompanionapp | find /I &quot;versionCode&quot;</code></pre> <p><u>Results:</u></p> <p style="margin-left:40px">Old version output:</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/SSO_08.png" /></p> <p>In the example stated above, the last updated version number of the SSO companion app on this specific device is 4810. However, the latest version of the Adobe SDK requires the system SSO companion app to be of version number 5510 or greater. To update the SSO companion app in SMP devices, go to device Settings-&gt;My Fire TV-&gt;About-&gt;Check for Updates. In Fire TV Edition devices, go to device Settings-&gt;Device &amp; Software-&gt;About-&gt;Check for Updates. Run this command repeatedly, until there are no more system updates left to be received. When you run your adb version command again, the results should now be as follows:</p> <p><img alt="" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/SSO_09.png" style="height:32px; width:454px" /></p> <p>To prevent your app users from facing SSO issues because they have not updated their device system OS recently, the app should perform a version check and nudge the users to update their app and device OS.</p> <p>&nbsp;</p> <p>For more information about Single-Sign On, please see <strong><a href="https://tve.helpdocsonline.com/amazon-firetv-sso-programmer-kick-off-guide" target="_blank">this</a></strong> documentation on Adobe Primetime Authentication Fire TV SDK.</p> <p>&nbsp;</p> <p style="text-align:left"><strong><img alt="PriyaRajan.jpg" src="https://m.media-amazon.com/images/G/01/mobile-apps/devportal2/content/priyarajan.jpg" /></strong></p> <p><em>Priya Rajan is an Amazon Solutions Architect with domain expertise in app development on Fire TV, Fire tablets, and Echo Show devices.</em></p> <p>&nbsp;</p>