Recent Apps Sample Overview

The Recent Apps sample application demonstrates how to manage running applications using the Tizen Application API.

The following figure illustrates the main screens of the Recent Apps.

Figure: Recent Apps screens

RecentApps screen RecentApps screen

The application opens with the main screen that shows the CLOSE ALL button and information on the running applications:

  • When swiped left or right, the screen changes to the next or previous running application.

    If there is no application running, the No recent apps screen is displayed.

  • When the delete icon button is clicked or the screen is swiped down, the section item is deleted and the application is killed.

    The section item is an HTML element consisting of 3 parts: the application name, icon, and delete icon button.

    If there is no application running after killing the application, the Recent Apps application itself is closed.

  • When the CLOSE ALL button is clicked, all running applications are closed, including the Recent Apps application.

Prerequisites

To ensure proper application execution, the following privileges must be set:

  • http://tizen.org/privilege/application.info
  • http://tizen.org/privilege/application.launch
  • http://tizen.org/privilege/appmanager.kill

Source Files

You can create and view the sample application project including the source files in the IDE.

Table: Source files
File name Description
config.xml This file contains the application information for the platform to install and launch the application, including the view mode and the icon to be used in the device menu.
css/style.css This file contains the CSS styling for the application UI.
index.html This is a starting file from which the application starts loading. It contains the layout of the application screens.
js/app.js This file starts the application and gets information about the applications running on the target or the emulator.
js/pageindicator.js This file contains the page indicator and the section changer winset of the TAU (Tizen Advanced UI) code.

Implementation

Application Layout

The application has 2 screens, the main screen and the No recent apps screen. Their content is defined in the index.html file:

  1. The main screen displays information about the running applications.

    The TAU winsets for page indicator, section changer, and bottom button are used to construct the page.

    <!--index.html-->
    <div id="main" class="ui-page" data-enable-page-scroll="false">
       <!--Main page: Page indicator-->
       <div id="main-page-indicator" class="ui-page-indicator" data-layout="circular"></div>
    
       <!--Main page: Section changer-->
       <div id="main-section-changer" class="ui-content">
          <!--Section changer has only one child-->
          <div id="section-container"></div>
       </div>
    
       <!--Main Page: Bottom button-->
       <footer class="ui-footer ui-bottom-button">
          <button id="main-footer-button" class="ui-btn">CLOSE ALL</button>
       </footer>
    </div>
    

    The section items are generated from the template.

    <!--index.html-->
    <section id="section-template">
       <!--Section: App name-->
       <div class="section-appname"></div>
       <!--Section: Delete button-->
       <div class="section-delbtn">
          <div class="delbtn-icon"></div>
          <div class="delbtn-background"></div>
          <div class="delbtn-shadow"></div>
       </div>
       <!--Section: Icon-->
       <div class="section-icon">
          <div class="icon-background-mask"></div>
          <div class="icon-background-effect1"></div>
          <div class="icon-background-effect2"></div>
       </div>
    </section>
    

    The width of each section item is fixed, as shown in the following figure.

    <!--css/style.css-->
    section 
    {
       width: 241px !important;
    }
    

    Section Changer Layout

  2. The No recent apps screen is displayed when there are no running applications.

    <!--index.html-->
    <div id="no-recent-apps">
       <div id="no-recent-apps-title">Recent apps</div>
       <div id="no-recent-apps-background"></div>
       <div id="no-recent-apps-icon"></div>
       <div id="no-recent-apps-text">No recent apps</div>
    </div>
    

Displaying Information of Running Applications on the Screen

This sample application manages applications running on the target device and emulator. It gets the information using the Application API:

  1. Use the application.getAppsContext() method with the following parameters to find content that satisfies the conditions set by a filter:

    • successCallback(): The method to call when the invocation ends successfully.
    • errorCallback [optional] [nullable]: The method to call when an error occurs.
    /* js/app.js */
    function init()
    {
       bindEvents();
       tizen.application.getAppsContext(createSections);
    }
    
  2. When the application.getAppsContext() method is completed successfully, the createSections() method is called.

    It calls the createSection() method for each context. When the createSection() method returns a section item, push it to the section container.

    /* js/app.js */
    function createSections(contexts)
    {
       var appInfo,
           section;
    
       sectionContainer.innerHTML = "";
       for (var i = 0; i < contexts.length; i++)
       {
          appInfo = tizen.application.getAppInfo(contexts[i].appId);
          /* ApplicationInformation.show property indicates whether the application should be shown */
          /* For displaying without Recent Apps, check Application ID */
          if (appInfo.show === true && appInfo.id !== currentAppId)
          {
             section = createSection(contexts[i]);
             sectionContainer.appendChild(section);
          }
       }
       if (sectionContainer.children.length === 0)
       {
          setNoRecentAppsPage();
       }
       else
       {
          setMainPage();
          pageIndicator.update();
       }
    }
    

    Use the createSection() method to create the section item:

    /* js/app.js */
    function createSection(context)
    {
       var contextId = context.id,
           appInfo = tizen.application.getAppInfo(context.appId),
           appName = appInfo.name,
           iconPath = appInfo.iconPath,
           section;
    
       section = document.createElement("section");
    
       /* Saves ApplicationContext ID and Application ID for launch, close each application */
       section.setAttribute("contextId", contextId);
       section.setAttribute("appId", appInfo.id);
    
       /* Gets content from template */
       section.innerHTML = document.getElementById("section-template").innerHTML;
    
       section.querySelector(".section-appname").innerHTML = appName;
       section.querySelector(".section-delbtn").addEventListener("click", function(e)
       {
          deleteSection(section);
          e.stopPropagation();
       });
       section.querySelector(".section-icon").style.backgroundImage = "url(" + iconPath + ")";
    
       return section;
    }
    
  3. After creating the section items, the pageIndicator.update() method is called to update the page indicator and the section changer accordingly.

    /* js/pageindicator.js */
    pageIndicator.update = function()
    {
       sections = document.querySelectorAll("section");
    
       if (indicator !== null)
       {
          indicator.destroy();
       }
    
       /* Sets number of sections without template */
       if (sections.length > 1)
       {
          indicator = tau.widget.PageIndicator(elPageIndicator,
          {
             numberOfPages: sections.length - 1
          });
    
          if (sectionChanger === null)
          {
             sectionChanger = new tau.widget.SectionChanger(changer,
             {
                circular: false,
                orientation: "horizontal",
                useBouncingEffect: true
             });
          }
          sectionChanger.refresh();
          indicator.setActive(sectionChanger.getActiveSectionIndex());
       }
    };
    

Launching the Application

Bind the click event in the pageIndicator.init() method.

Call the application.launch() method to launch the application when the section item is clicked.

/* js/pageindicator.js */
changer.addEventListener("click", function()
{
   /* sectionChanger.getActiveSectionIndex() method returns index of section on the screen */
   var index = sectionChanger.getActiveSectionIndex(),
       /* eventTarget is section object of selected index in section container */
       eventTarget = container.children[index],
       appId = eventTarget.getAttribute("appId");

   tizen.application.launch(appId);
});

Killing the Application

When the delete icon button is touched or a section is swiped down, the section item is deleted and the application is killed.

When the CLOSE ALL button is touched, all section items are deleted and all applications are killed as well.

The http://tizen.org/privilege/appmanager.kill privilege is a partner level privilege. To use a partner level privilege, a partner level signing key is required.

  1. Bind the delete icon button click event in the createSection() method:

    /* js/apps.js */
    section.querySelector(".section-delbtn").addEventListener("click", function(e)
    {
       deleteSection(section);
       e.stopPropagation();
    });
    
    function deleteSection(section)
    {
       var contextId = section.getAttribute("contextId");
    
       tizen.application.kill(contextId);
       sectionContainer.removeChild(section);
       if (sectionContainer.children.length === 0)
       {
          tizen.application.getCurrentApplication().exit();
       } 
       else
       {
          pageIndicator.update();
       }
    }
    
  2. Bind the swipe event in the pageIndicator.init() method:

    /* js/pageindicator.js */
    changer.addEventListener("swipe", swipeEventHandler);
    
    function swipeEventHandler(event)
    {
       var direction = event.detail.direction,
           index = sectionChanger.getActiveSectionIndex(),
           eventTarget = container.children[index],
           contextId = eventTarget.getAttribute("contextId");
    
       if (direction === "down")
       {
          tizen.application.kill(contextId);
          container.removeChild(eventTarget);
          if (container.children.length === 0)
          {
             tizen.application.getCurrentApplication().exit();
          }
          else
          {
             pageIndicator.update();
          }
       }
    }
    
  3. Bind the CLOSE ALL button click event in the bindEvents() method:

    /* js/app.js */
    document.getElementById("main-footer-button").addEventListener("click", function()
    {
       closeAll();
    });
    
    function closeAll()
    {
       var length = sectionContainer.children.length;
    
       for (var i = 0; i < length; i++)
       {
          deleteSection(sectionContainer.firstChild);
       }
       tizen.application.getCurrentApplication().exit();
    }
    

Controlling Rotary Events

Bind the rotary event in the pageIndicator.init() method.

The rotaryEventHandler() method changes the active section item to the previous or next one.

The screen is scrolled to the left or right according to the rotary direction.

/* js/pageindicator.js */
document.addEventListener('rotarydetent', rotaryEventHandler);

function rotaryEventHandler(event)
{
   var direction = event.detail.direction,
       length = container.children.length,
       sectionIndex;

   if (length > 0)
   {
      sectionIndex = sectionChanger.getActiveSectionIndex();

      if (direction === "CW")
      {
         if (sectionIndex < (length - 1))
         {
            sectionIndex = sectionIndex + 1;
         }
      }
      else if (direction === "CCW")
      {
         if (sectionIndex > 0)
         {
            sectionIndex = sectionIndex - 1;
         }
      }
      /* Change selected section during 100 milliseconds */
      sectionChanger.setActiveSection(sectionIndex, 100);
   }
}