1. Identifying the underlying bearer, ESG spec used in the implementation:

import javax.microedition.broadcast.esg;

    ServiceGuide esg = ServiceGuide.getDefaultServiceGuide();
    MetadataSet spec;
    MetadataSet[] speclist = esg.getSupportedMetadataSets();

    for (int i = 0; i < speclist.length; i++) {
        System.out.println("Metadata Specification: " + 
    		    speclist[i].getDescription());
        // Check the class for the different types of spec; DVBH in this case.
        if (speclist[i] instanceof CommonMetadataSet) {
    	// ....
        }
    }

2. Enumerate all the valid attributes in the specs:


    ServiceGuide esg = ServiceGuide.getDefaultServiceGuide();
    MetadataSet spec;
    MetadataSet[] speclist = esg.getSupportedMetadataSets();

    for (int i = 0; i < speclist.length; i++) {
        Attribute[] attrs = speclist[i].getValidAttributes();
        for (int j = 0; j < attrs.length; j++) {
            // Eumerate the attributes and print out their long (proper) names.
            System.out.println("Attribute: " + attrs[j].getName());
        }
    }

3. Find all the programs of a particular genre, then display it:


    // Form the query
    ServiceGuide esg = ServiceGuide.getDefaultServiceGuide();
    Query q = QueryComposer.equivalent(CommonMetadataSet.PROGRAM_CONTENT_GENRE, "News");

    // Because some programs of our interest may be updated asynchronously,
    // we should also add a listener to make sure that we get updated
    // on all the programs we are interested in.
    // We'll go through this in Example 4.
    try {
    	esg.addListener(new ProgramMonitor(), q);
    } catch (QueryException qe) {
    	// invalid query
    }

    ProgramEvent programs[];
    try {
        // Find the programs
        programs = esg.findPrograms(q);
        for (int i = 0; i < programs.length; i++) {
            // A custom function to display the program info
            // Example 5.
            displayProgramInfo(programs[i]);
        }
    } catch (QueryException e) {
    }

4. Listen to program updates:


    // Define my own program change listener for monitoring
    // program updates.
    class ProgramMonitor implements ServiceGuideListener {

        public void serviceGuideUpdated(String event, ServiceGuideData esgdata, Object data) {
    	if (event == NEW_PROGRAM_LISTED || event == PROGRAM_CHANGED) {
                // Display the new program
                displayProgramInfo(esgdata);
    	}
    	else if (event == SERVICE_GUIDE_BULK_CHANGED || event == PROGRAM_DELETED) {
    	    // We'll need to redo the queries and redisplay
    	    // the programs.  See Example 3.
    	}
        }
    }

5. Display "Generic" program information:


    void displayProgramInfo(ProgramEvent p) {

        Attribute[] attrs = CommonMetadataSet.getInstance().getValidAttributes();

        for (int i = 0; i < attrs.length; i++) {
    	    // Since we do not know ahead of time what the type
    	    // of the attributes are, we will need to test for
    	    // them one by one with "instanceof".
                // The following format* methods format and display the 
                // values in some meaningful ways in the GUI.  They are
                // left as exercise for the readers.
                formatAttribute(attrs[i].getName());
                if (attrs[i] instanceof StringAttribute) {
                    formatString(p.getValue((StringAttribute)attrs[i]));
                }
                else if (attrs[i] instanceof DateAttribute) {
                    formatDate(p.getValue((DateAttribute)attrs[i]));
                }
                // More...
        }
    }

6. Display the Electronic Service Guide in the traditional time listing format:


    ServiceGuide esg;

    // Listen for all incoming programs.
    // Listener to be defined later.
    try {
    	esg.addListener(new ProgramMonitor(), null);
    } catch(QueryException qe) {}

    void displayServiceGuide() {
        Attribute[] sortBy = new Attribute[] {
                                              CommonMetadataSet.SERVICE_ID,
                                              CommonMetadataSet.PROGRAM_START_TIME
                                          };
        try {
            // Select all programs and sort them first by their service ids,
            // then the scheduled start time.
            ProgramEvent[] programs = esg.findPrograms(null, sortBy, 0, 0);
            for (int i = 0; i < programs.length; i++)
                displayProgramInfo(programs[i]);
        } catch (QueryException e) {
        }
    }

    public class ProgramMonitor implements ServiceGuideListener {

        public void serviceGuideUpdated(String event, ServiceGuideData esgdata, Object data) {
    	if (event == NEW_PROGRAM_LISTED || event == PROGRAM_DELETED ||
    	    event == SERVICE_GUIDE_UPDATE_COMPLETED) {
    	    // It is easier to simply update the entire list
                // and get the display sorted properly.
                displayServiceGuide();
    	}
    	else if (event == PROGRAM_CHANGED) {
                // Display the changed program
                displayProgramInfo(esgdata);
    	}
        }
    }

7. Create query to get all programs today on PRO7 between 6 pm and 10 pm:


// calculate the dates for 6 pm and 10 pm today 

Calendar c = Calendar.getInstance(); 

// use 17:59:59 instead of 18:00:00 to get programs starting 6 pm exactly 
c.set(Calendar.HOUR, 17); 
c.set(Calendar.MINUTE, 59); 
c.set(Calendar.SECOND, 59); 
Date startTime = c.getTime(); 

c.set(Calendar.HOUR, 22); 
c.set(Calendar.MINUTE, 00); 
c.set(Calendar.SECOND, 00); 
Date endTime = c.getTime(); 

// create queries 
Query qChannel = QueryComposer.equivalent(CommonMetadataSet.SERVICE_NAME, "PRO7"); 

Query qAfter = QueryComposer.after(CommonMetadataSet.PROGRAM_START_TIME, startTime); 
Query qBefore = QueryComposer.before(CommonMetadataSet.PROGRAM_END_TIME, endTime); 

// combine queries to one 
Query q = QueryComposer.and(qChannel, QueryComposer.and(qAfter, qBefore)); 

ServiceGuide esg = ServiceGuide.getDefaultServiceGuide();

ProgramEvent programs[]; 
try { 
    // Find the programs 
    programs = esg.findPrograms(q); 
    for (int i = 0; i < programs.length; i++) { 
         displayProgramInfo(programs[i]); 
    } 
} catch (QueryException e) { } 

8. Create query to get all programs on YLE in Finnish or Swedish


// find all multilingual programs, both in Finnish and Swedish, on YLE
Query qChannel = QueryComposer.equivalent(CommonMetadataSet.SERVICE_NAME, "YLE");
Query qFinnish = QueryComposer.equivalent(CommonMetadataSet.SERVICE_COMPONENT_LANGUAGE, "fin");
Query qSwedish = QueryComposer.equivalent(CommonMetadataSet.SERVICE_COMPONENT_LANGUAGE, "swe");

// combine queries to one 
Query q = QueryComposer.and(qChannel, QueryComposer.and(qFinnish, qSwedish)); 

ServiceGuide esg = ServiceGuide.getDefaultServiceGuide();

ProgramEvent programs[]; 
try { 
    // Find the programs 
    programs = esg.findPrograms(q); 
    for (int i = 0; i < programs.length; i++) { 
         displayProgramInfo(programs[i]); 
    } 
} catch (QueryException e) { } 

9. Changing the current service of the context where the calling application belong:

    ServiceGuide esg = ServiceGuide.getDefaultServiceGuide();
    try {
        Service[] current = esg.findServices(QueryComposer.currentProgram());
        ServiceContext sc = ServiceContext.getDefaultContext();
        sc.select(current[0]);
    } catch (Exception e) { }

10. Selecting a service based on the ESG:

    ServiceGuide esg = ServiceGuide.getDefaultServiceGuide();
    Query q = QueryComposer.equivalent(CommonMetadataSet.SERVICE_NAME, "BBC");
    try {
        Service[] services = esg.findServices(q);
        if (services.length > 0) {
            ServiceContext sc = ServiceContext.getDefaultContext();
            sc.select(services[0]);
        }
    } catch (Exception e) { }

11. Selecting a service and fetch the Players for presentation

import javax.microedition.broadcast.*;
import javax.microedition.broadcast.esg.*;
import javax.microedition.media.*;
import javax.microedition.media.control.*;

    ServiceContext sc = ServiceContext.getDefaultContext();

    /**
     * Add a listener to be notified of the creation of the Players.
     * Initialize and start the Players as they are created.
     */
    sc.addListener(new ServiceContextListener() {
        public void contextUpdate(ServiceContext s, String event, Object data) {
		    	if (event == ServiceContextListener.PLAYERS_REALIZED) {
		    	    Player players[] = (Player [])data;
		    	    // The players should all be realized at this point.
		    	    // Initialize and display them.
		    	    for (int i = 0; i < players.length; i++) {
				    		VideoControl vc = (VideoControl)players[i].getControl("VideoControl");
				    		if (vc != null) {
				    		    vc.initDisplayMode(vc.USE_DIRECT_VIDEO, canvas /* a GUI canvas created ahead of time */);
				    		    vc.setVisible(true);
				    		}
		    		}
		    	}
     	}
    });

    // Select a service.
    ServiceGuide esg = ServiceGuide.getDefaultServiceGuide();
    try {
    	Service[] current = esg.findServices(QueryComposer.currentProgram());
	    sc.select(current[0]);
    } catch (QueryException qe) {}

12. Using AMMS controls

import javax.microedition.broadcast.*;
import javax.microedition.media.*;
import javax.microedition.amms.control.audioeffect.*;
import javax.microedition.amms.control.imageeffect.*;


// Fetch EqualizerControl from a realized Player that was fetched
// from ServiceContext as in example 11.
EqualizerControl eq = (EqualizerControl)player.getControl("javax.microedition.amms.control.audioeffect.EqualizerControl");
if (eq != null) {
    // Equalizer is supported.
    // Let's boost the bass a little bit:
    eq.setBass(70);
    eq.setEnabled(true);
}

// Similarly , fetch an ImageTonalityControl.
ImageTonalityControl it = (ImageTonalityControl)player.getControl("javax.microedition.amms.control.audioeffect.ImageTonalityControl");
if (it != null) {
    // Image tonality settings are supported.
    // Let's increase image contrast:
    it.setContrast(75);
    it.setEnabled(true);
}

13. Working with Broadcast Objects: Retrieving typed packet streams

import javax.microedition.broadcast.*;
import javax.microedition.broadcast.connection.*;
import java.util.*;

/**
 * Return all packet streams found in this service.
 * This example excludes files and directories and includes
 * available raw data from A/V components.
 *
 * @return a list of all available packet streams
 */
public Vector getTypedPacketStreams() {
  // request the default service context
  ServiceContext serviceContext = ServiceContext.getDefaultContext();
  // get all selected components
  ServiceComponent[] components = serviceContext.getSelectedComponents();
  Vector connections = new Vector();
  for (int i = 0; i < components.length; i++) {
    try {
      BroadcastConnection connection = serviceContext.getBroadcastDatagramConnection(components[i]);
      // only add datagram connections to the list
      connections.addElement(components[i]);
    } catch (BroadcastServiceException e) {
      // ignore connections that cannot be retrieved from the context
    }
  }
  return connections;
}

/**
 * Return all auxiliary packet data connections of a certain type.
 */
public Vector getPacketStream(String mimeType) {
  Vector packetStreams = getPacketStreams();
  Vector typedPacketStreams = new Vector();
  Enumeration packetStreamEnum = packetStreams.elements();
  while(packetStreamEnum.hasMoreElements()) {
    BroadcastDatagramConnection connection = (BroadcastDatagramConnection)packetStreamEnum.nextElement();
    // selectively add only connections of a certain mime type
    if(connection.getMimeType().startsWith(mimeType)) {
      typesPacketStreams.addElement(connection);
    }
  }
  return typedPacketStreams;
}

14. Working with Auxiliary Data: Getting an Auxiliary Service Logo

import javax.microedition.broadcast.*;
import javax.microedition.broadcast.esg.*;
import javax.microedition.broadcast.connection.*;
import javax.microedition.io.*;
import java.io.*;

/**
 * This method retrieves the logo associated with a service.
 */
public InputConnection getServiceLogo() throws IOException, QueryException {
  // request the default service context
  ServiceContext serviceContext = ServiceContext.getDefaultContext();
  // Retrieve content logo uri
  String logoUri = serviceContext.getService().getStringValue(CommonMetadataSet.PROGRAM_CONTENT_AUX_LOGO);
  // Open the URI.  The URI could be http, file or carousel-based.  
  // So we'll cast and use it as an InputConnection.
  if (logoUri == null)
    return null;
  Connection logoConnection = Connector.open(logoUri, Connector.READ);
  if (logoConnection instanceof InputConnection) {
    return (InputConnection) logoConnection;
  }
  return null;
}

/**
 * Just a skeleton to handle the service logo.
 */
public void handleServiceLogo() {
  try {
    InputConnection ic = getServiceLogo();
    // We may want to specialize the code here.
    if (ic instanceof HttpConnection) {
        // Do something specific for http.
    } else if (ic instanceof BroadcastFileConnection) {
        // Do something specific for carousel. 
	BroadcastFileConnection bfc = (BroadcastFileConnection)ic;
	if (!bfc.isAvailable())
	  bfc.addListener(myLogoListener);
        else {
	  // Get additional information like mimetype and load image.
	}
    }
  } catch (Exception e) {
  }
}

15. Subscribe to a "premium movie service"

ServiceGuide db = ServiceGuide.getDefaultServiceGuide(); 
Query q = QueryComposer.equivalent(CommonMetadataSet.SERVICE_NAME, "PremiumMovies"); 
try { 
    Service[] services = db.findServices(q); 
    if (services.length > 0) { 
        Service premium = services[0]; 
        String premiumServiceID = services[0].getStringValue(CommonMetadataSet.SERVICE_ID); 
        PurchaseObjects[] purchaseObjects = SubscriptionManager.getPurchaseObjects(serviceId); 
	if(purchaseObjects.length > 0) { 
	     // show the content of the purchaseObjects to the user and 
	     // and let him choose 
             // let's assume that the first purhchaseObject was selected by the user 
             if (purchaseObjects[0].isPurchased()) { 
                 // user has already subscribed to the service, no need to buy it again 
                 return; 
             } 
             purchaseObjects[0].addPurchaseListener(this);

						 // assume that the options are known to the user requestPriceOptions() is not needed
             PriceOption[] options = purchaseObjects[0].getPriceOptions();
             
             // at this point the different options should be presented to the user
             
             purchaseObjects[0].purchase(options[0]); 
             // purchase transaction has been started. 
             // implementation pops up a dialog to get confirmation from the user 
             // application can now just wait for it to complete 
        } 
    } 
} catch (Exception e) { } 

void purchaseResponse(PurchaseObject source, java.lang.String event, java.lang.Object object) { 
    if (event.equals(PURCHASE_STARTED)) { 
        // purchase process started 
	return; 
    } 
    if (event.equals(PURCHASE_DENIED)) { 
        // user denied the purchasing 
        return; 
    } 
    if (event.equals(PURCHASE_APPROVED)) { 
        // user denied the purchasing 
        return; 
    } 
    if (event.equals(PURCHASE_COMPLETED)) { 
        // user denied the purchasing 
        return; 
    } 
    if (event.equals(PURCHASE_FAILED)) { 
        // user denied the purchasing 
        return; 
    } 
} 



Overview JavaDoc API Presentation & Recording Security & DRM Purchasing Examples