Eclipse schaut fern

Anwendungen für Smart-TVs in Eclipse realisieren

Tam Hanna

Wer Anwendungen für Smart-TVs entwickeln möchte, landet über kurz oder lang bei Samsung. Das koreanische Unternehmen dominiert ganz klar den Smart-TV-Markt. Doch das Entwickeln von Anwendungen für diese Geräte war bisher alles andere als angenehm – was daran liegt, dass Samsung das SDK um eine eigene und im Haus entwickelte IDE ergänzt. Diese wurde zwar mit jeder Version besser, reicht aber trotzdem nicht an Umgebungen wie Eclipse oder Visual Studio heran. Im Jahr 2013 dürfen sich Entwickler auf die Version 4.0 des Samsung-SDKs freuen – sie ersetzt die bekannte IDE durch Eclipse.

Wer erste Schritte in Richtung Apps on TV gehen möchte, muss sich die Entwicklungsumgebung von Samsung D Forum herunterladen [1]. Zur Registrierung benötigen Sie einen Samsung-Account – wenn Sie beim AdHub oder dem App Seller Office registriert sind, verwenden Sie die existierenden Login-Daten bitte weiter. Samsung liefert das SDK als .zip-Archiv aus. Nachdem Sie die Datei extrahiert haben, spielt ein automatischer Installer das 1.2 GB große Programm auf Ihre Maschine. Einen eventuellen Fehler in Bezug auf die Visual C++-Runtime können Sie getrost ignorieren. Die Installation von Apache ist nur dann erforderlich, wenn Sie Ihre Programme auf einem echten Fernseher testen möchten.

Erste Schritte

Die Installationsroutine legt auf Ihrem Desktop ein [Eclipse] Samsung SMART TV Apps Editor genanntes Icon an. Benutzen Sie dieses, um die IDE zu starten – wenn das Samsung-Plug-in aktiv ist, sehen Sie im Hauptmenü von Eclipse ein zusätzliches Menü namens Samsung Smart TV. Dort stehen – wie schon von Samsungs klassischer Entwicklungsumgebung gewohnt – drei verschiedene Projekttypen zur Auswahl. Das Basic Apps Project entspricht dabei der bekannten TV-Applikation mit Scenes, während ein JavaScript Project normalen HTML5-Code verarbeitet.

In den folgenden Schritten arbeiten wir mit einer Basic-App namens SusBasicTVApp. Nach dem Erstellen des in Abbildung 1 gezeigten Projektskeletts öffnet Eclipse automatisch die erste „Scene“ zur Bearbeitung im WYSIWYG-Editor.

Abb. 1: Das Projektskelett unserer neuen Smart-TV-Applikation

Vereinfacht gesagt sind die meisten Smart-TVs Webbrowser auf Steroiden. Das bedeutet, dass Sie Ihre Applikation wie eine normale Web-App schreiben. Das Fernsehgerät führt die Webseite danach im Vollbildmodus aus, was beim Benutzer den Eindruck einer echten „nativen“ Applikation entstehen lässt.

Der Einsprungpunkt heißt – wie sollte es anders sein – index.html. Samsung lädt dort die Widget-Manager-Bibliothek, die die eigentliche Initialisierung der Anwendung durchführt. Für Sie als Entwickler gibt es in dieser Datei nichts zu tun. Stattdessen platzieren Sie Ihren Initialisierungs- und Destruktorcode in der Datei init.js. Ihr Skelett sieht dann aus wie in Listing 1.

function onStart () {
  // TODO : Add your Initilize code here
  // NOTE : In order to start your app, call "sf.start()" at the end of this function!!

  sf.scene.show('Scene1');
  sf.scene.focus('Scene1');
}
function onDestroy () {
  //stop your XHR or Ajax operation and put codes to destroy your application here

}

alert("init.js loaded.");

onStart() dient als Konstruktor für TV-Anwendungen. In unserem Projektskelett weisen wir das Framework zum Anzeigen unserer Scene an. Danach verwenden wir den Focus-Befehl, um die von der Fernbedienung ankommenden Eingaben an die Event Handler der Scene weiterzuleiten. Übrigens ist der mit „Note“ gekennzeichnete Kommentar irreführend. Die hier abgedruckte Version funktioniert genauso.

Wenn Ihre Applikation einen „globalen Destruktor“ braucht, so implementieren Sie diesen am besten in onDestroy. Das Framework ruft diese Methode immer dann automatisch auf, wenn es eine Anwendung terminiert.

Mach’ mir (k)eine Szene

Ihre Anwendung besteht aus einer Vielzahl von Formularen. Bei Samsung heißen diese „Scene“ statt „Form“– warum das koreanische Unternehmen ausgerechnet diese, eigentlich nicht zutreffende, Ausdrucksweise wählt, ist nicht in Erfahrung zu bringen. Eine Scene besteht immer aus den folgenden vier Dateien:

  • CSS
  • HTML
  • JS
  • SCENE

 Samsungs Smart-TV-Framework enthält eine eigene GUI-Bibliothek, die dem Entwickler eine Vielzahl von für den Einsatz am Fernsehgerät optimierten Widgets anbietet. Das Erstellen der Scenes erfolgt in einem grafischen Editor, dessen Einstellungen in der .scene-Datei abgespeichert sind.

Falls Sie Scene1.scene nach dem Erstellen des Projektskeletts geschlossen haben, so öffnen Sie sie durch Doppelklick. Der – sehr langsam ladende – Editor präsentiert sich wie in Abbildung 2 gezeigt.

Abb. 2: Der GUI-Editor erleichtert das Editieren von Formularlayouts

Der karierte Bereich ist die Arbeitsfläche – sie wird zusätzlich als „Übersichtsdiagramm“ im Outline-Fenster dargestellt. Die Eigenschaften des gerade markierten Elements erscheinen in der Properties-Liste auf der Unterseite des Bildschirms. Auf der rechten Seite finden Sie die Steuerelemente, die Sie per Drag and Drop in die Arbeitsfläche bugsieren.

Als ersten Schritt wollen wir eine Liste und ein Label miteinander verdrahten. Dazu ziehen Sie ein „label“ und eine „listbox“ aus der Palette am rechten Bildschirmrand ins Formular und ordnen sie nach Belieben an. Umsteiger von früheren SDK-Versionen beachten bitte, dass sich die Höhe der Liste im neuen Editor nicht mehr anpassen lässt. Stattdessen nehmen Sie derartige Änderungen in Zukunft in Object Literal Syntax im Konstruktorcode vor – weitere Informationen dazu finden sich unter [2].

Sobald Sie ein Steuerelement ablegen, aktualisiert das SDK automatisch die .css-, .html– und .js-Dateien. Die HTML-Datei ist völlig unkritisch – sie definiert die zu realisierenden Steuerelemente durch <div>– oder <input>-Tags:

<!-- this html will be a contents of div SceneScene1 -->
<div id='svecListbox_5i4ay8rox0s04'></div>
<div id='svecLabel_5i4ay8rq8go05'></div>

Die Positionsinformationen liegen in der .css-Datei. Aus Platzgründen ist in Listing 2 nur der Anfang der Datei abgedruckt – das Beispiel zum Heft ist natürlich vollständig.

#SceneScene1 {
  position : absolute;
  left : 0px;
  top : 0px;
  width : 960px;
  height : 540px;
  background-color : #ffffff;
  background-image : url('');
}
#SceneScene1 #svecListbox_5i4ay8rox0s04{
  position : absolute;
  left : 340px;
  top : 50px;
  width : 331px;
}
. . .

 Der Rest der Intelligenz sitzt in der JavaScript-Datei. Die Funktion initialize() wird nach dem Laden des CSS aufgerufen und hat die Aufgabe, die einzelnen <div>-Elemente beim Framework anzumelden (Listing 3).

SceneScene1.prototype.initialize = function () {
  alert("SceneScene1.initialize()");
  $('#svecListbox_5i4ay8rox0s04').sfList({
    data:['item1', 'item2', 'item3']
  });
  $('#svecLabel_5i4ay8rq8go05').sfLabel({
    text:'label'
  });
}

Die mit dem Dollarzeichen beginnenden Aufrufe sind klassisches jQuery und dienen zur Ermittlung eines Zeigers auf das jeweilige Formularelement. Die Aufrufe von sfList und sfLabel sorgen dafür, dass die div-Elemente in eine Liste bzw. ein Label umgewandelt werden.

Im Rahmen des Formularlebenszyklus ruft das Framework eine Vielzahl von Funktionen auf, um ihre Anwendung über den Zustand der Benutzerschnittstelle zu informieren. Beim Anzeigen und Verstecken des Formulars ruft der Scene Manager folgende Funktionen auf (Listing 4).

SceneScene1.prototype.handleShow = function (data) {
  alert("SceneScene1.handleShow()");
  
}

SceneScene1.prototype.handleHide = function () {
  alert("SceneScene1.handleHide()");
  
}

 Der Eingabefokus hat – das haben wir schon in init.js festgestellt – nichts mit der Sichtbarkeit des Formulars zu tun. Aus diesem Grund gibt es zwei weitere Funktionen, die als „Trigger“ für die Sichtbarkeit agieren (Listing 5).

SceneScene1.prototype.handleFocus = function () {
  alert("SceneScene1.handleFocus()");
}

SceneScene1.prototype.handleBlur = function () {
  alert("SceneScene1.handleBlur()");
}

An sich gibt es auch hier nicht allzu viel zu sehen. Interessant sind nur die Aufrufe von Alert – anders als am Desktop geben sie keine MessageBox aus, sondern schreiben in die Konsole des Emulators.

JavaScript OOP?

Der Code der von Samsung implementierten Views wirkt auf Umsteiger von C++ oder Java fremdartig. Der Grund für das seltsame Aussehen liegt darin, dass JavaScript kein Klassenkonzept besitzt – ist die Sprache doch prototyporientiert. In der Praxis bedeutet das, dass es zwar Objekte, aber keine Klassen gibt. Alle Objektinstanzen basieren ausschließlich aufeinander und auf ihren „Vorgängern“. Methoden sind als „normale Variable“ angelegt, die als „Wert“ den Funktionscode enthalten.

Scene1 basiert also sowohl auf dem normalen Object-Objekt als auch auf dem Prototyp. Samsung schreibt die „generischen“ Methoden der Scenes in den Prototyp des Objekts, um bei mehreren Instanzen des Objekts nicht mehrere Kopien der Methode im Speicher zu haben.

Dabei kommt immer dieselbe Syntax zum Einsatz, die hier kurz angerissen ist:

OBJEKTNAME.prototype.FUNKTIONSNAME = function () 
{

}

Die Belebung der konkreten Instanzen erfolgt dann im „normalen“ Konstruktor, der im Rahmen des Erstellens des Objekts über das New-Schlüsselwort aufgerufen wird:

function OBJEKTNAME() 
{

}

Wer sich ernsthaft mit der Entwicklung von Anwendungen für Samsung befasst, kommt über kurz oder lang nicht an JavaScript vorbei. In der Webentwicklerszene genießt das von Addy Osmani veröffentlichte Buch „Design Patterns for JavaScript“ absoluten Kultstatus. Erfreulicherweise ist es auch als kostenloses E-Book verfügbar [3] – insbesondere der erste Teil des sehr umfangreichen Werks ist ein Must-Read.

Eingaben verarbeiten

Damit sind wir soweit fertig – es ist Zeit, unsere Anwendung in Aktion zu sehen. Erfreulicherweise brauchen wir dazu nicht einmal einen Smart-TV, da Samsung einen durchaus brauchbaren Emulator mitliefert.

Klicken Sie Ihr Projekt im Project Explorer rechts an und wählen Sie im daraufhin erscheinenden Kontextmenü die Option Samsung Smart TV SDK | Run Project in Samsung TV Emulator aus. Da der Start des Emulators bis zu eine Minute Zeit erfordert, ist etwas Geduld erforderlich. Nach dem erfolgreichen Start erscheint eine virtuelle Fernbedienung nebst ihrer Applikation. Theoretisch sollten Sie nun in der Lage sein, mit der Liste über den 5-Way-Navigator zu interagieren. In der Praxis funktioniert allerdings nur die Power-Taste, die den Emulator beendet.

Der Grund für diese Passivität liegt darin, dass Samsung das Handling des Fokus aus dem Autor unerfindlichen Gründen zur Gänze an den Entwickler abschiebt. Die eingehenden Events landen in der Methode handleKeyDown, die im vorliegenden Beispiel nur eine Meldung in die Debuggerkonsole des Emulators schreibt.

Erfreulicherweise ist es nicht allzu schwierig, grundlegende Interaktion zu realisieren. In unserem Beispiel genügt der in Listing 6 gezeigte Event Handler, um die Liste zu aktualisieren und den Index des momentan aktiven Elements in das Label zu schreiben.

SceneScene1.prototype.handleKeyDown = function (keyCode) {
  alert("SceneScene1.handleKeyDown(" + keyCode + ")");
  switch (keyCode) {
    case sf.key.LEFT:
      break;
    case sf.key.RIGHT:
      break;
    case sf.key.UP:
      var choice;
      $('#svecListbox_5i4ay8rox0s04').sfList('prev');
      choice=$('#svecListbox_5i4ay8rox0s04').sfList('getIndex');
      $('#svecLabel_5i4ay8rq8go05').sfLabel({ text: choice});
      break;
    case sf.key.DOWN:
      var choice;
      $('#svecListbox_5i4ay8rox0s04').sfList('next');
      choice=$('#svecListbox_5i4ay8rox0s04').sfList('getIndex');
      $('#svecLabel_5i4ay8rq8go05').sfLabel({ text: choice});
      break;
      break;
    case sf.key.ENTER:
      break;
  }
}

Wir reagieren in diesem Snippet sowohl auf die Nach-oben- als auch auf die Nach-unten-Taste der Fernbedienung. Der Rest der Aufgabe ist alles andere als kompliziert: Wir verschieben die Markierung des aktiven Elements und aktualisieren den Text des Labels. Interessant ist der praktische Zugriff auf das Steuerelement – er erfolgt auf Smart-TVs von Samsung immer nach demselben Schema.

Im ersten Schritt ermitteln wir per jQuery einen Zeiger auf das Formularobjekt. Jedes Widget exponiert eine einzelne Zugriffsfunktion, die für alle Interaktionen zwischen dem Steuerelement und dem Applikationscode verantwortlich ist.

Der erste Parameter ist dabei – außer bei der Erstellung eines neuen Objekts – immer ein String, der die auszuführende Option angibt. Manche Operationen verlangen einen zweiten Parameter, der weitere Informationen anliefert. Als Rückgabewert ist ein Integer definiert. Diese relativ starre Struktur der Interaktion führt zu einigen Beschränkungen im Aufbau der APIs. So ist es z. B. nicht möglich, den Text des aktuellen Listen-Items zu ermitteln – er würde ja einen String zurückliefern.

Wenn Sie die Anwendung mit dem modifizierten Event Handler starten, so können Sie die Markierung in der Liste durch die Nach-oben- und Nach-unten-Tasten der Fernbedienung bewegen. Leider erscheint die List Box nicht von Anfang an aktiv – der Benutzer würde unter Umständen nicht wissen, dass seine Eingaben von der List Box entgegengenommen und verarbeitet werden. Die Lösung dafür ist das manuelle Zuweisen des Fokus, wann immer das Formular fokussiert wird:

SceneScene1.prototype.handleFocus = function () {
  alert("SceneScene1.handleFocus()");
  $('#svecListbox_5i4ay8rox0s04').sfList('focus');
}

Damit ist das Formular soweit einsatzbereit und kann im Emulator getestet werden. Wenn Sie die Auswahl der Liste verändern, so aktualisiert sich der Inhalt des Labels automatisch – Gratulation!

Mehr Scenes!

Komplexe Programme bestehen so gut wie immer aus mehr als einem Formular. Erfreulicherweise ist das Hinzufügen einer weiteren Scene nicht allzu schwierig. Rechtsklicken Sie auf das Projekt im Project Explorer, um das Kontextmenü zu öffnen.

Wählen Sie danach die Option New | Samsung Smart TV Apps scene, um den Wizard zum Erstellen einer neuen Scene zu starten. Geben Sie der Datei danach einen Namen. In unserem Beispiel heißt die Datei SceneNeu.scene – die dazugehörigen .css, .html- und .sj-Dateien erstellt der Editor automatisch.

Unsere Aufgabe besteht darin, dem Benutzer eine Möglichkeit zum Aktivieren der neuen Scene zu geben. Dazu wollen wir Scene1 um einen Knopf erweitern. Öffnen Sie dazu die Datei Scene1.scene im grafischen Editor. Ziehen Sie danach einen Button aus der Palette in das Formular. Platzieren Sie ihn rechts von der schon vorher dort abgelegten Liste. Wenn Sie möchten, können Sie die ID und den Text des Buttons in den Properties anpassen. Wenn Sie die Anwendung nun ausführen, so sehen Sie den Knopf am Bildschirm – interagieren können Sie mit ihm noch nicht.

Da Samsungs API keine Methode zum Abfragen des Fokus-Zustands eines Steuerelements enthält, müssen wir von Hand einen Fokus-Handler realisieren. In unserem Beispiel ist das relativ einfach – die Links- und Rechts-Tasten wechseln zwischen den Steuerelementen (Listing 7).

switch (keyCode) {
  case sf.key.LEFT:
    if(this.activeControl=="b")
    {
      $('#svecButton_Scene2').sfButton('blur');
      $('#svecListbox_5i4ay8rox0s04').sfList('focus');
      this.activeControl="l";
    }
    break;
  case sf.key.RIGHT:
    if(this.activeControl=="l")
    {
      $('#svecButton_Scene2').sfButton('focus');
      $('#svecListbox_5i4ay8rox0s04').sfList('blur');
      this.activeControl="b";
    }
    break;

Das manuelle Deaktivieren der Steuerelemente ist übrigens keine Marotte des Autors. Samsungs GUI-Framework rendert bereitwillig mehrere „aktive“ Steuerelemente nebeneinander (Abb. 3).

Abb. 3: Ohne manuelles Deaktivieren sind nach einiger Zeit sowohl die Liste als auch der Button aktiv

Im nächsten Schritt müssen wir die Nach-oben- und Nach-unten-Tasten deaktivieren, wenn der Button fokussiert ist. Dazu adaptieren wir key.UP wie in Listing 8 gezeigt – die Anpassung für key.DOWN folgt aus der Analogie.

case sf.key.UP:
  if(this.activeControl=="l")
  {
    var choice;
    $('#svecListbox_5i4ay8rox0s04').sfList('prev');
    choice=$('#svecListbox_5i4ay8rox0s04').sfList('getIndex');
    $('#svecLabel_5i4ay8rq8go05').sfLabel({ text: choice});
  }
  break;

Im Konstruktor legen wir den „Initialzustand“ fest, um das Programm von Anfang an in einem konsistenten Zustand zu haben:

function SceneScene1() 
{
  this.activeControl="l";
}

Damit fehlt nur mehr das Aktivieren des zweiten Formulars. Der dazu erforderliche Code sitzt ebenfalls im Event-Handler von Scene1:

case sf.key.ENTER:
  if(this.activeControl=="b")
  {
    sf.scene.show('SceneNeu');
    sf.scene.focus('SceneNeu');
  }
Wieso Apps on TV?

Nach diesen technischen Betrachtungen sollten wir noch einen Blick auf den Gesamtmarkt werfen. Anders als Anwendungen für mobile oder stationäre PCs handelt es sich bei den Applikationen für den Fernseher nämlich um ein streng interdisziplinäres Tätigkeitsfeld. Der Druck in Richtung intelligenter Fernsehgeräte kommt mehrheitlich nicht vom Enduser. Er entsteht bei den Herstellern und den Anbietern von Inhalten – beide profitieren von den immer intelligenter werdenden Fernsehgeräten.

Beginnen wir bei den Anbietern von Inhalten. Fernsehprogramme entstehen in Europa entweder bei privaten oder staatlichen Sendern. Die Balance zwischen den regierungsnahen staatlichen und den profitorientierten kommerziellen Sendeanstalten ist seit jeher mehr als fragil, Gerichtsprozesse sind an der Tagesordnung. Ein permanenter Streitpunkt ist die Finanzierung. Während das Staatsfernsehen bei Finanzmangel auf eine (unpopuläre) Steuererhöhung zurückgreifen kann, müssen die Privaten mit Werbeeinahmen auskommen. Um eine gewisse „Waffengleichheit“ zwischen der finanzstarken Privatwirtschaft und dem Staat herzustellen, ist die maximale Anzahl der erlaubten Werbeminuten streng beschränkt.

Apps on TV bieten an dieser Stelle Abhilfe, da sie neue Wege der Produktvermarktung eröffnen. So wäre es z. B. denkbar, dass es dem Zuschauer ermöglicht wird, die vom Moderator einer Talkshow getragenen Kleidungsstücke direkt per Knopfdruck zu kaufen – auf Vorträgen zum Thema sind das die immer wieder auftretenden Fragen aus der Medienindustrie.

Hardwarehersteller erhalten durch das „Smartmachen“ ihrer Fernsehgeräte eine nur schwer nachzubauende Trumpfkarte gegen die Billigkonkurrenz aus China. Außerdem ermöglicht diese Vorgehensweise „planned obsolescence“ im Post-HD-Zeitalter: Wenn die (an sich perfekt funktionierende) Glotze keine aktuellen Programme mehr ausführt, kauft der User eine neue.

Samsung nimmt übrigens auch hier eine Pionierrolle ein. Laut Medienberichten möchte das Unternehmen seinen Kunden einmal jährlich eine „Upgrade-Platine“ anbieten, die das Fernsehgerät mit den aktuellsten Apps kompatibel macht. Dieser Service wird allerdings nur fünf Jahre lang angeboten – ein Schelm, wer dabei Böses denkt.

Fazit

Die Entwicklung von Anwendungen für Smart-TVs ist für die meisten Entwickler völliges Neuland. Die Probleme liegen in der Regel weniger im Bereich der technischen Realisierung – wer eine Desktopapplikation auf den Fernseher wirft, erleidet mit Sicherheit Schiffbruch.

Als Marktführer hat Samsung im Laufe der Jahre ein sehr attraktives Ökosystem aufgebaut. Wer im Apps-on-TV-Markt mitspielen möchte, sollte sich in jedem Fall länger mit dem Framework beschäftigen – es ist schon lange nicht mehr möglich, alle Features in einem Artikel eines Fachmagazins zu besprechen. Im nächsten Heft finden Sie an der gleichen Stelle einige weitere Highlights. Bis dahin freue ich mich über Leserbriefe Ihrerseits – teilen Sie mir bitte mit, was Sie von Apps on TV halten.

Geschrieben von
Tam Hanna
Tam Hanna
Tam Hanna befasst sich seit der Zeit des Palm IIIc mit der Programmierung und Anwendung von Handcomputern. Er entwickelt Programme für diverse Plattformen, betreibt Onlinenewsdienste zum Thema und steht unter tamhan@tamoggemon.com für Fragen, Trainings und Vorträge gern zur Verfügung.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.