/** * FMRadioDemoScreen.java * * Copyright � 1998-2011 Research In Motion Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Note: For the sake of simplicity, this sample application may not leverage * resource bundles and resource strings. However, it is STRONGLY recommended * that application developers make use of the localization features available * within the BlackBerry development platform to ensure a seamless application * experience across a variety of languages and geographies. For more information * on localizing your application, please refer to the BlackBerry Java Development * Environment Development Guide associated with this release. */ package com.rim.samples.device.fmradiodemo; import javax.microedition.media.Player; import net.rim.device.api.command.Command; import net.rim.device.api.command.CommandHandler; import net.rim.device.api.command.ReadOnlyCommandMetadata; import net.rim.device.api.media.MediaActionHandler; import net.rim.device.api.system.Application; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.component.ButtonField; import net.rim.device.api.ui.component.LabelField; import net.rim.device.api.ui.component.SeparatorField; import net.rim.device.api.ui.component.StandardTitleBar; import net.rim.device.api.ui.component.TextField; import net.rim.device.api.ui.container.HorizontalFieldManager; import net.rim.device.api.ui.container.MainScreen; import net.rim.device.api.ui.container.VerticalFieldManager; /** * The UI screen for the FM Radio Demo */ public class FMRadioDemoScreen extends MainScreen { private static final int INITIAL_FREQUENCY = 990000; private FMRadioDemoPlayer _fmRadioDemoPlayer; private ButtonField _setFrequencyButton; private ButtonField _seekUpButton; private ButtonField _seekDownButton; private ButtonField _increaseRSSIButton; private ButtonField _decreaseRSSIButton; private ButtonField _playButton; private LabelField _rssiLabel; private TextField _rdsTextField; private TextField _frequencyTextField; private TextField _logTextField; private final MediaHandler _mediaHandler; /** * Creates a new FMRadioDemoScreen object */ public FMRadioDemoScreen() { initializePlayer(); final StandardTitleBar standardTitleBar = new StandardTitleBar(); standardTitleBar.addTitle("FM Radio Demo"); standardTitleBar.addNotifications(); standardTitleBar.addSignalIndicator(); setTitleBar(standardTitleBar); _mediaHandler = new MediaHandler(); Application.getApplication().addMediaActionHandler(_mediaHandler); initializeUiComponents(); createLayout(); } /** * Initializes the Player */ void initializePlayer() { _fmRadioDemoPlayer = new FMRadioDemoPlayer(this); } /** * Updates the RDS data after an event has indicated that there is new data * available */ void updateRDS() { final StringBuffer rdsBuffer = new StringBuffer(); rdsBuffer.append("RDS_PS:"); rdsBuffer.append(_fmRadioDemoPlayer.getRdsPS()); rdsBuffer.append(" PTY:"); rdsBuffer.append(_fmRadioDemoPlayer.getRdsPty()); _rdsTextField.setText(rdsBuffer.toString()); } /** * Initializes the screen's UI elements and defines the button actions */ private void initializeUiComponents() { _frequencyTextField = new TextField("Frequency [MHz]: ", ""); _setFrequencyButton = new ButtonField("Set Frequency"); _seekUpButton = new ButtonField("Seek >"); _seekDownButton = new ButtonField("< Seek"); _increaseRSSIButton = new ButtonField("RSSI +"); _decreaseRSSIButton = new ButtonField("- RSSI"); _playButton = new ButtonField("Play"); _rssiLabel = new LabelField(_fmRadioDemoPlayer.getRSSI()); _rdsTextField = new TextField(Field.NON_FOCUSABLE); _rdsTextField.setLabel("RDS: "); _logTextField = new TextField(Field.NON_FOCUSABLE); _logTextField.setLabel("Log: "); _playButton.setCommand(new Command(new CommandHandler() { public void execute(final ReadOnlyCommandMetadata data, final Object context) { // Check whether the Player has already been started if (_fmRadioDemoPlayer.getPlayerState() == Player.STARTED) { _fmRadioDemoPlayer.switchRbds(false); _fmRadioDemoPlayer.stopPlayer(); _playButton.setLabel("Play"); } else { _fmRadioDemoPlayer.startPlayer(); _fmRadioDemoPlayer.switchRbds(true); _playButton.setLabel("Stop"); } } })); _seekDownButton.setCommand(new Command(new CommandHandler() { public void execute(final ReadOnlyCommandMetadata data, final Object context) { try { final int frequency = stringToFrequency(_frequencyTextField.getText()); _fmRadioDemoPlayer.seek(frequency, false); _frequencyTextField .setText(frequencyToString(_fmRadioDemoPlayer .getFrequency())); } catch (final NumberFormatException n) { // If the TextField cannot be parsed as a valid frequency, // set the TextField text to a valid frequency. _frequencyTextField .setText(frequencyToString(INITIAL_FREQUENCY)); } } })); _seekUpButton.setCommand(new Command(new CommandHandler() { public void execute(final ReadOnlyCommandMetadata data, final Object context) { try { final int frequency = stringToFrequency(_frequencyTextField.getText()); _fmRadioDemoPlayer.seek(frequency, true); _frequencyTextField .setText(frequencyToString(_fmRadioDemoPlayer .getFrequency())); } catch (final NumberFormatException n) { // If the TextField cannot be parsed as a valid frequency, // set the TextField text to a valid frequency. _frequencyTextField .setText(frequencyToString(INITIAL_FREQUENCY)); } } })); _increaseRSSIButton.setCommand(new Command(new CommandHandler() { public void execute(final ReadOnlyCommandMetadata data, final Object context) { // Increase the internally stored value // for RSSI that is used for seeking. _fmRadioDemoPlayer.increaseRSSI(); _rssiLabel.setText(_fmRadioDemoPlayer.getRSSI()); } })); _decreaseRSSIButton.setCommand(new Command(new CommandHandler() { public void execute(final ReadOnlyCommandMetadata data, final Object context) { // Decrease the internally stored value // for RSSI that is used for seeking. _fmRadioDemoPlayer.decreaseRSSI(); _rssiLabel.setText(_fmRadioDemoPlayer.getRSSI()); } })); _setFrequencyButton.setCommand(new Command(new CommandHandler() { public void execute(final ReadOnlyCommandMetadata data, final Object context) { try { final String text = _frequencyTextField.getText(); if (text.indexOf(".") > -1) { // Convert String to an integer frequency value final int frequency = stringToFrequency(_frequencyTextField.getText()); if (_fmRadioDemoPlayer.checkFrequencyInRange(frequency)) { // Send the given frequency to the API for tuning _fmRadioDemoPlayer.tuneTo(frequency); } } } catch (final NumberFormatException n) { FMRadioDemo.errorDialog("Integer.parseInt() threw: " + n.toString()); } finally { String text; if (_fmRadioDemoPlayer.getPlayerState() == Player.STARTED) { text = frequencyToString(_fmRadioDemoPlayer .getFrequency()); } else { text = frequencyToString(INITIAL_FREQUENCY); } _frequencyTextField.setText(text); } } })); _frequencyTextField.setMaxSize(5); _frequencyTextField.setText(frequencyToString(INITIAL_FREQUENCY)); } /** * Lays out the UI elements on the screen */ private void createLayout() { final VerticalFieldManager verticalFieldManager = new VerticalFieldManager(Field.FIELD_HCENTER); final HorizontalFieldManager horizontalFieldManager1 = new HorizontalFieldManager(Field.FIELD_HCENTER); final HorizontalFieldManager horizontalFieldManager2 = new HorizontalFieldManager(Field.FIELD_HCENTER); final HorizontalFieldManager horizontalFieldManager3 = new HorizontalFieldManager(Field.FIELD_HCENTER); final HorizontalFieldManager horizontalFieldManager4 = new HorizontalFieldManager(Field.FIELD_HCENTER); horizontalFieldManager1.add(_setFrequencyButton); horizontalFieldManager2.add(_seekDownButton); horizontalFieldManager2.add(_seekUpButton); horizontalFieldManager3.add(_decreaseRSSIButton); horizontalFieldManager3.add(_rssiLabel); horizontalFieldManager3.add(_increaseRSSIButton); horizontalFieldManager4.add(_playButton); verticalFieldManager.add(_frequencyTextField); verticalFieldManager.add(horizontalFieldManager1); verticalFieldManager.add(horizontalFieldManager2); verticalFieldManager.add(horizontalFieldManager3); verticalFieldManager.add(horizontalFieldManager4); verticalFieldManager.add(new SeparatorField()); verticalFieldManager.add(_rdsTextField); verticalFieldManager.add(_logTextField); add(verticalFieldManager); } /** * @see net.rim.device.api.ui.Screen#close() */ public void close() { try { Application.getApplication() .removeMediaActionHandler(_mediaHandler); _fmRadioDemoPlayer.closePlayer(); } finally { super.close(); } } /** * @see net.rim.device.api.ui.Screen#onSavePrompt() */ protected boolean onSavePrompt() { // Supress the save dialog return true; } /** * Formats a frequency in KHz to a String in MHz with a dot after the MHz * number and one digit after the dot to represent the 100kHz value. * * @param frequency * Frequency in KHz units * @return A String representing the frequency in MHz (e.g. "102.5") */ private String frequencyToString(final int frequency) { // The frequency should have a maximum of 5 digits in MHz final StringBuffer buffer = new StringBuffer(5); // Append MHz buffer.append(frequency / 10000); buffer.append("."); // Append digit after the dot buffer.append(frequency % 10000 / 1000); return buffer.toString(); } /** * Utility method to convert a frequency in String format and MHz into a * frequency in 100kHz. * * @param frequncy * The frequency representation in MHz with following dot and * digit for kHz * @return The frequency in 100Hz */ private int stringToFrequency(final String frequency) { // Parse MHz int f = Integer.parseInt(frequency.substring(0, frequency.indexOf('.'))) * 10000; // Parse value after the dot f += Integer.parseInt(frequency .substring(frequency.indexOf('.') + 1)) * 1000; return f; } /** * Retrieves frequency indicated in the frequency text field * * @return Currently set frequency as an integer */ public int getFrequency() { return stringToFrequency(_frequencyTextField.getText()); } /** * Logs information to the screen * * @param log * Information of interest */ void updateLog(final String log) { _logTextField.setText(log); } /** * A MediaActionHandler implementation */ class MediaHandler implements MediaActionHandler { /** * @see net.rim.device.api.media.MediaActionHandler#mediaAction(int, * int, Object) */ public boolean mediaAction(final int action, final int src, final Object context) { switch (action) { case MEDIA_ACTION_PLAYPAUSE_TOGGLE: case MEDIA_ACTION_MUTE: case MEDIA_ACTION_UNMUTE: case MEDIA_ACTION_MUTE_TOGGLE: break; case MEDIA_ACTION_NEXT_TRACK: // Use the next-track-button as a seek-up function _fmRadioDemoPlayer .seek(_fmRadioDemoPlayer.getFrequency(), true); // Display the new frequency _frequencyTextField .setText(frequencyToString(_fmRadioDemoPlayer .getFrequency())); break; case MEDIA_ACTION_PREV_TRACK: // Use the prev-track-button as a seek-down function _fmRadioDemoPlayer.seek(_fmRadioDemoPlayer.getFrequency(), false); // Display the new frequency _frequencyTextField .setText(frequencyToString(_fmRadioDemoPlayer .getFrequency())); break; case MEDIA_ACTION_VOLUME_DOWN: _fmRadioDemoPlayer.decreaseVolume(); break; case MEDIA_ACTION_VOLUME_UP: _fmRadioDemoPlayer.increaseVolume(); break; default: break; } return false; } } }