BlackBerry 应用程序开发者指南 第一卷:基础--第5章 支持的媒体内容(Media Content)...
作者:Confach 發表于April 23,2006 15:02 pm
版權信息:可以任意轉載, 轉載時請務必以超鏈接形式標明文章原始出處 和作者信息.
http://www.cnblogs.com/confach/articles/387902.html
5
第5章 支持的媒體內容(Media Content)
| PME內容
播放媒體內容
監聽媒體內容事件
創建定制的連接 |
PME內容
BlackBerry設備支持PME格式的富(rich)媒體內容。
開發者可以使用Plazmic Content Developer’s Kit for BlackBerry來創建PME內容。這個工具,以及附帶的文檔可以在Plazmic網站(www.plazmic.com)找到。
Media Engine API(在net.rim.plazmic.mediaengine 和 net.rim.plazmic.mediaengine.io包中)允許應用程序獲取和播放存儲在BlackBerry設備上或網絡上的PME內容.
Media Engine API支持媒體格式application/x-vnd.rim.pme. Web服務器必須為application/x-vnd.rim.pme設置MIME類型。
PME API概覽
下面3個主要類(在net.rim.plazmic.mediaengine包里)提供了加載和播放PME媒體內容的能力。
| 類 | 描述 |
| MediaManager | 提供從本地或網絡上加載媒體內容的方法。 |
| MediaPlayer | 提供播放PME媒體的方法。 |
| MediaException | 為獲取或播放媒體的錯誤提供異常代碼。 |
媒體加載
Media Engine API允許應用程序使用下面4種協議種的一種加載媒體內容:
| 協議 | 描述 |
| http:// | http協議從一個使用HTTP連接網絡Web服務器下載內容。這個協議需要一個帶有BlackBerry MDS服務的BES(BlackBerry Enterprise Server,BlackBerry企業服務器). |
| https:// | https協議從一個使用HTTPS連接網絡Web服務器下載內容。這個協議需要一個帶有BlackBerry MDS服務的BES(BlackBerry Enterprise Server,BlackBerry企業服務器). |
| Jar:///<pme_file> | jar協議加載存儲在本地BlackBerry設備上的jar文件。 jar:///sample.pme 注意:開始的斜線(/)是需要的。 在BlackBerry IDE中,.jar文件必須加入到調用應用程序或應用程序依賴的庫的相同項目中。 |
| cod://<module><pme_file> | cod協議加載存儲在本地BlackBerry設備上的cod文件。 cod://mediasample/sample.pme |
為使用其他協議,實現定制的Connector。為獲得更多信息,參看91頁的“創建定制的Connector”.
播放狀態(Playback states)
為了獲取MediaPlayer的當前狀態,調用MediaPlayer.getState().
| 狀態 | 描述 |
| UNREALIZED | MediaPlayer未準備播放媒體。為了轉到REALIZED狀態,調用MediaPlayer.setMedia(). |
| REALIZED | MediaPlayer準備好播放媒體。為了開始播放,并轉到STARTED狀態,調用MediaPlayer.start(). |
| STARTED | MediaPlayer正在播放媒體。為了停止播放和返回到REALIZED狀態,調用MediaPlayer.stop(). |
異常
MediaEngine和MediaManager類的方法拋出一個MediaException異常,這個異常包含了一個標準的HTTP響應代碼或者下面異常代碼之一。為了獲取與異常相聯系的錯誤代碼,調用MediaException.getCode().
| 異常代碼 | 描述 |
| INVALID_HEADER | 媒體格式無效。 |
| REQUEST_TIMED_OUT | 請求超時。 |
| INTERRUPTED_DOWNLOAD | 應用程序調用MediaManager.cancel()來取消下載。 |
| UNSUPPORTED_TYPE | 媒體類型(MIME類型)不支持。 |
| UPGRADE_PALYER | 媒體引擎的版本和請求的內容不兼容。 |
| UPGRADE_MEDIA | 媒體引擎的版本不在支持請求的內容。 |
| CHECKSUM_MISMACTH | 求和校驗失敗,因此媒體內容不能讀取。 |
| OUT_OF_BOUNDS | 數組出界,或應用程序試圖訪問一個文件結尾后的輸入流。 |
事件
MediaListener接口允許應用程序接受或響應下面的事件:
| 事件 | 描述 |
| MEDIA_REQUEST | 媒體已請求加載,當animation自動請求新內容或當用戶點擊媒體內容的超連接時,事件發生。 |
| MEDIA_REALIZED | 媒體已經創建播放了。當MediaManager.createMediaManager()已經調用時發生。 |
| MEDIA_COMPLETE | 媒體已經加載,并成功播放。 |
| MEDIA_TO | 媒體正在加載。 |
為獲得更多信息,參考85頁的“監聽Media Engine事件”.
播放媒體內容
為了獲取BlackBerry設備或網絡上的PME內容,使用MediaManager的方法。為了播放已經下載到BlackBerry設備的PME內容,使用MediaPlayer類的方法。
下載內容
為下載PME內容,創建一個MediaManager對象,然后調用MediaManager.createMedia().
| try ?{ ??? Object media = manager.createMedia("http://webserver/sample.pme"); ?} ?catch (IOException ioe) ?{ ??? ?System.out.println("Error: requested content was not downloaded."); ?} ?catch (MediaException me) ?{ ??? ?System.out.println("Error: “ + me.getCode()); ?} |
注:下面缺省的協議會被支持:http://,https://.jar://,和cod://.為獲得更多信息,參看81頁的“媒體加載”。
第一次調用MediaManager.createMedia(),URL必須是絕對路徑,除非首先調用MediaManager.setProperty(“URI_BASE”,<base_url>)設置基URL路徑。當你之后調用createMedia()時,前面的URL作為基URL。
?
播放PME內容
為播放設置PME對象
調用MedialPlayer.setMedia().
| MediaPlayer player = new MediaPlayer(); try { ?player.setMedia(media); } catch (MediaException me) { ? System.out.println("Error: requested content type is not supported.”); } ? |
獲取一個顯示PME內容的UI對象
調用MediaPlayer.getUI()。轉化getUI()返回的一個作為Field的對象,然后將之加入到屏幕來顯示。
| add((Field)player.getUI()); |
開始播放下載的PME內容
調用MediaPlayer.start()。
| if(player.getState() == MediaPlayer.REALIZED) { ?try ?{ ? player.start(); ?} ?catch(MediaException me) { ??? ?System.out.println("Error occurred during media playback: " + ?????????? ?me.getCode() + me.getMessage()); ?} } |
注:在調用MediaPlayer.start()前檢查MediaPlayer的狀態,如果媒體播放器不是REALIZED狀態,start()方法拋出一個異常。
代碼實例
MediaSample.java實例從一個Web服務器獲取一個PME文件,然后顯示它。
例:MediaSample.java
?
/**
* MediaSample.java
* Copyright (C) 2001-2005 Research In Motion Limited. All rights reserved.
*/
package com.rim.samples.docs.mediasample;
import java.io.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
import net.rim.plazmic.mediaengine.*;
?
public class MediaSample extends UiApplication {
??? public static void main(String[] args) {
?????? MediaSample app = new MediaSample();
?????? app.enterEventDispatcher();
??? }
??? public MediaSample() {
?????? pushScreen(new MediaSampleScreen());
??? }
?
final static class MediaSampleScreen extends MainScreen {
??? public MediaSampleScreen() {
?????? super();
?????? LabelField title = new LabelField(“Media Sample”, LabelField.ELLIPSIS| LabelField.USE_ALL_WIDTH);
?????? setTitle(title);
?????? MediaPlayer player = new MediaPlayer();
?????? MediaManager manager = new MediaManager();
?????? try {
?????????? Object media = manager.createMedia(“http://webserver/SVGFILE.pme”);
?????????? player.setMedia(media);
?????? } ?
?????? catch (IOException ioe) {
?????? }
?????? catch (MediaException me) {
?????????? System.out.println(“Error during media loading: “);
?????????? System.out.println(me.getCode());
?????????? System.out.println(me.getMessage());
?????? }
?????? add((Field)player.getUI());
?????? try {
?????????? player.start();
?????? }
?????? catch(MediaException me) {
?????????? System.out.println(“Error occured during media playback: “);
?????????? System.out.println(me.getCode());
?????????? System.out.println(me.getMessage());
?????????? }
?????? }
??? }
}
監聽媒體引擎事件
MediaListener接口允許應用程序注冊接收媒體引擎事件。應用程序可以在注冊MediaPlayer和MediaEngine對象上注冊監聽者。
當應用程序實現監聽者時,它可以完成以下的動作:
- 提供內容下載狀態的信息。
- ?在后臺下載內容,當完成時播放它。
- 下載一個animation自動請求的內容。
MediaListener接口包含一個方法,listen方法。
public void mediaEvent(Object sender,
int event,
int eventParam,
Object data);
| 參數 | 描述 |
| sender | 本參數引用了發送事件的對象,如MediaPlayer或MediaManager對象。 |
| event | 參數可以是下列事件之一:
|
| eventParam | 不要使用這個參數,因為它可能接收一個任意值。它存在是為了為額外的事件提供一個一致的接口。 |
| data | 當data參數是MEDIA_REQUESTED,data把請求的URL作為一個String對象。 當data參數是MEDIA_REALIZED,data引用了創建的媒體對象。 當data參數是MEDIA_IO,data引用了一個net.rim.plazmic.mediaengine.io.LoadingStatus對象。 |
監聽媒體引擎事件
MediaListener接口的實現允許你的應用程序監聽一個媒體引擎事件。mediaEvent()的實現應該處理所有可能的媒體事件。下面的例子使用了一個switch語句來處理可能媒體事件。
| public final class MediaListenerImpl implements MediaListener { ??? public void mediaEvent(Object sender, int event, int eventParam, Object data) { ?????? switch(event) { ?????? ? case MEDIA_REQUESTED: ?????????? ? // Perform action. ?????????? ? break; ?????? ? case MEDIA_COMPLETE: ?????????? ? // Perform action. ?????????? ? break; ?????? ? case MEDIA_REALIZED: ?????????? ? // Perform action. ?????????? ?break; ?????? ? case MEDIA_IO: ?????????? ? // Perform action. ?????????? ? break; ?????????? ?} ?????? } } |
注冊監聽者
為了注冊你的監聽者,調用MediaPlayer和MediaManager對象上的addMediaListener()方法。
| private MediaListenerImpl _listener = new MediaListenerImpl(); private MediaPlayer player = new MediaPlayer(); private MediaManager manager = new MediaManager(); player.addMediaListener(_listener); manager.addMediaListener(_listener); |
在后臺加載內容
當實現MediaListener時,你可以在背后下載PME內容,并且當下載完成后播放內容。
調用MediaManager.createMediaListener()為將來的播放下載內容。
注:和createMedia()不一樣,createMediaLater()不返回一個媒體內容的對象。
在MediaListener.mediaEvent()中,當請求的內容下載時,加入代碼來處理MEDIA_REALIZED事件。為了注冊在data參數里指定的內容,調用MediaPlayer.setMedia(data)。為了開始播放,調用MediaPlayer.start()。
| manager.createMediaLater("http://webserver/sample.pme"); ? public void mediaEvent(Object sender, int event, ?????? ????????????? int eventParam, Object data) { ??? switch(event) { ??? ... ??? case MEDIA_REALIZED: ???? try { ??? ?player.setMedia(data); ??? ?player.start(); ??? ?} ???? catch(MediaException me) { ??? ?System.out.println("Error playing media” + me.getCode() +" + ??? ?????? "?? me.getMessage()); ???? } ?? break; ?} } ? |
跟蹤下載進度
為得到下載進度的信息,使用net.rim.plazmic.mediaengine.io.LoadingStatus類。這個類包含了一些方法來允許你獲得媒體內容類型,字節總數,字節讀取數,以及內容的源URL。
| 狀態 | 描述 |
| LOADING_STARTED | 加載開始。 |
| LOADING_READING | 數據流正在解析。 |
| LOADING_FINISHED | 加載媒體成功。 |
| LOADING_FAILED | 媒體記載失敗.
|
在mediaEvent()的實現里,當MEDIA_IO事件發生時,將data參數里的Object轉化為一個LoadingStatus對象。
調用LoadingStatus.getStatus()來獲取下載的狀態,然后處理每個狀態。
對每個正常的狀態,打印一個消息到控制臺。
對LOADING_FAILED狀態,完成下面的動作:
- 調用LoadingStatus.getCode()獲得錯誤代碼。
- 調用LoadingStatus.getMessage()獲得詳細的消息。
- 調用LoadingStatus.getSource()獲得內容的URL字符串。
| public void mediaEvent(Object sender, int event, ?????? ?????????????? int eventParam, Object data) { ??? switch(event) { ??? ?? ... ??? ? case MEDIA_IO: { ??? ? } ??? ? ... ??? ? break; ??? } ??? break; ??? ... ? switch(s.getStatus()) { ??? case LoadingStatus.LOADING_STARTED: ??? ?? System.out.println("Loading in progress"); ??? ?? break; ??? case LoadingStatus.LOADING_READING: ??? ?? System.out.println("Parsing in progress"); ??? ?? break; ??? case LoadingStatus.LOADING_FINISHED: ??? ?? System.out.println("Loading completed"); ??? ?? break; ??? case LoadingStatus.LOADING_FAILED: ??? ? String errorName = null; ??? ? int code = s.getCode(); ??? ? switch (code) { ??? ???? case MediaException.INVALID_HEADER: ?????? ?? errorName = "Invalid header" + "\n" + s.getSource(); ?????? ?? break; ??? ???? case MediaException.REQUEST_TIMED_OUT: ?????? ?? errorName = "Request timed out" + "\n" + ?????? ?? s.getSource(); ?????? ?? break; ??? ???? case MediaException.INTERRUPTED_DOWNLOAD: ?????? ?? break; ??? ???? case MediaException.UNSUPPORTED_TYPE: ?????? ?? errorName = "Unsupported type" + s.getMessage() + "\n" + s.getSource(); ?????? ?? break; ??? ???? default: { ?????? ?? if (code > 200) { ?????? ???? // A code > 200 indicates an HTTP error ?????? ???? errorName = "URL not found"; ?????? ?? } ?????? ?? else { ?????? ??? // default unidentified error ?????? ???? errorName = "Loading Failed"; ?????? ??? } ?????? ?errorName += "\n" + s.getSource() + "\n" + s.getCode()+ ": " + s.getMessage(); ?????? ?break; ??? ? } ??? } ??? System.out.println(errorName); ??? break; ? } // End switch s.getStatus(). ?break; } |
代碼實例
MediaSample2.java 實例實現了一個監聽者在后臺下載媒體內容,并顯示下載的狀態到控制臺。
例:MediaSample2.java
/**
* MediaSample2.java
* Copyright (C) 2001-2005 Research In Motion Limited. All rights reserved.
*/
package com.rim.samples.docs.mediasample;
import java.io.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.system.*;
?
import net.rim.plazmic.mediaengine.*;
import net.rim.plazmic.mediaengine.io.*;
?
public class MediaSample2 extends UiApplication {
??? private MediaPlayer player = new MediaPlayer();
??? private MediaManager manager = new MediaManager();
??? private MediaListenerImpl _listener = new MediaListenerImpl();
??? private MediaSample2Screen _screen;
???
??? public static void main(String[] args) {
?????? MediaSample2 app = new MediaSample2();
?????? app.enterEventDispatcher();
?????? }
???
??? public MediaSample2() {
?????? _screen = new MediaSample2Screen();
?????? pushScreen(_screen);
?????? }
?
??? public final class MediaListenerImpl implements MediaListener {
?????? public void mediaEvent(Object sender, int event,
????????????? int eventParam, Object data) {
?????????? switch(event) {
?????????? case MEDIA_REQUESTED:
????????????? System.out.println(“Media requested”);
????????????? break;
?????????? case MEDIA_COMPLETE:
????????????? System.out.println(“Media completed”);
????????????? break;
?????????? case MEDIA_REALIZED:
????????????? try {
????????????????? player.setMedia(data);
????????????????? player.start();
????????????????? }
????????????? catch(MediaException me) {
????????????????? System.out.println(“Error during media loading: “ +
???????????????????????? me.getCode() + me.getMessage());
????????????????? }
????????????? break;
?????????? case MEDIA_IO: {
????????????? LoadingStatus s = (LoadingStatus)data;
????????????? switch(s.getStatus()) {
????????????? case LoadingStatus.LOADING_STARTED:
????????????????? System.out.println(“Loading in progress”);
????????????????? break;
????????????? case LoadingStatus.LOADING_READING:
????????????????? System.out.println(“Parsing in progress”);
????????????????? break;
????????????? case LoadingStatus.LOADING_FINISHED:
????????????????? System.out.println(“Loading completed”);
????????????????? break;
????????????? case LoadingStatus.LOADING_FAILED:
????????????????? String errorName = null;
????????????????? int code = s.getCode();
????????????????? switch (code) {
????????????????? case MediaException.INVALID_HEADER:
???????????????????? errorName = “Invalid header” + “\n” + s.getSource();
???????????????????? break;
????????????????? case MediaException.REQUEST_TIMED_OUT:
???????????????????? errorName = “Request timed out” + “\n” + s.getSource();
???????????????????? break;
????????????????? case MediaException.INTERRUPTED_DOWNLOAD:
???????????????????? break;
????????????????? case MediaException.UNSUPPORTED_TYPE:
???????????????????? errorName = “Unsupported type” + s.getMessage()
???????????????????? + “\n” + s.getSource();
???????????????????? break;
????????????????? default: {
???????????????????? if (code > 200) {
???????????????????????? // A code > 200 indicates an HTTP error.
???????????????????????? errorName = “URL not found”;
???????????????????????? }
???????????????????? else {
???????????????????????? // Default unidentified error.
???????????????????????? errorName = “Loading Failed”;
???????????????????????? }
????????????????? errorName += “\n” + s.getSource() + “\n”+
????????????????? s.getCode() + “: “ + s.getMessage();
????????????????? break;
????????????? }
?????????? }
?????? System.out.println(errorName);
?????? break;
??? } // End switch s.getStatus().
??? break;
??? }
?? }
? }
}
?
final class MediaSample2Screen extends MainScreen {
?? public MediaSample2Screen() {
???? super();
???? LabelField title = new LabelField(“Media Sample”, LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
???? setTitle(title);
???? manager.addMediaListener(_listener);
??? // Change this to the location of a test .pme file.
??? manager.createMediaLater(“http://test.rim.com/SVGBS0001.pme”);
??? add((Field)player.getUI());
}
}
}
創建一個定制的連接
MediaManager使用一個Connector對象加載媒體,并打開輸入流。缺省的Connector支持下列協議:http://.https://,jar://,以及cod://。為了增加支持一個定制的協議或者為了覆寫缺省的行為,通過實現net.rim.plazmic.mediaengine.io.Connector接口創建一個定制的Connector
| 方法簽名 | 實現 |
| InputStream getInputStream(String, ConnectionInfo) | 實現本方法返回一個輸入流從指定URI讀取內容。 |
| void releaseConnection(ConnectionInfo) | 實現本方法釋放連接。MediaManager調用本方法來通知Connector可以釋放連接了。 |
| void setProperty(String, String) | 實現本方法設置連接指定的屬性。 |
實現一個定制的connector
為了完成處理一個定制的協議,實現Connector接口,包含getInputStream()。為了處理一個標準的協議,調用缺省的Connector。
setProperty(String name, String value)的實現設置了指定的屬性。在本例中,connector不必設置任何指定的屬性,因此setProperty()的實現調用了Connector上的setProperty()。
public class SampleConnector implements Connector {
??? Connector delegate; // The default Connector.
??? SampleConnector(Connector delegate) {
?????? this.delegate = delegate;
?????? }
???
??? public InputStream getInputStream(String uri, ConnectionInfo info)
??? throws IOException, MediaException {
?????? InputStream input = null;
?????? if (uri.startsWith("myprotocol://")) {
?????????? // Perform special tasks.
?????????? info.setConnection(new MyProtocolConnection());
?????????? info.setContentType("application/x-vnd.rim.pme");
??????????
?????????? // openMyInputStream() is a custom method that opens
?????????? //stream for "myprotocol://".
?????????? input = openMyInputStream(uri);
?????????? }
?????? else {
?????????? input = delegate.getInputStream(uri, info);
?????????? }
?????? return input;
??? }
???
??? public void releaseConnection(ConnectionInfo info)
??? throws IOException, MediaException {
?????? Object o = info.getConnection();
?????? if (o instanceof MyProtocolConnection) {
?????????? ((MyProtocolConnection)o).close(); // Perform cleanup.
?????????? }
?????? else
?????? {
?????????? delegate.releaseConnection(info);
?????? }
??? }
???
??? public void setProperty(String property, String value) {
?????? delegate.setProperty(property, value);
?????? }
??? }
注冊一個定制的連接器
在你的主要方法里,調用MediaManager.setConnector()注冊你的定制的連接器。
| MediaManager manager = new MediaManager(); manager.setConnector(new CustomPMEConnector(manager.getDefaultConnector())); |
代碼實例
CustomPMEConnector.java實例為實現一個定制的連接器提供了一個框架。
?
例:CustomPMEConnector.java
/*
* CustomPMEConnector.java
* Copyright (C) 2003-2005 Research In Motion Limited. All rights reserved.
*/
package com.rim.samples.docs.mediasample;
import java.io.*;
import net.rim.plazmic.mediaengine.*;
import net.rim.plazmic.mediaengine.io.*;
?
public class CustomPMEConnector implements Connector {
??? private Connector delegate;
??? private InputStream input;
???
??? CustomPMEConnector(Connector delegate)
??? {
?????? this.delegate = delegate;
??? }
???
???
??? public InputStream getInputStream(String uri, ConnectionInfo info)
??? ????????? throws IOException, MediaException
??? {
?????? if (uri.startsWith("myprotocol://"))
?????? {
?????????? // Perform special tasks.
?????????? info.setConnection(new MyProtocolConnection());
?????????? info.setContentType("application/x-vnd.rim.pme");
??????????
?????????? // OpenMyInputStream() is a custom method that opens
?????????? //stream for “myprotocol://”
?????????? input = openMyInputStream(uri);
?????? }
?????? else
?????? {
?????????? input = delegate.getInputStream(uri, info);
?????????? return input;
?????? }
??????
?????? private InputStream openMyInputStream(String uri)
?????? {
?????????? InputStream input = null;
?????? }
??????
????????? // @todo: open stream here
?????? return input;
?????? }
???
??? public void releaseConnection(ConnectionInfo info)
??? throws IOException, MediaException
??? {
?????? Object o = info.getConnection();
?????? if (o instanceof MyProtocolConnection)
?????? {
?????????? ((MyProtocolConnection)o).close(); // Perform cleanup.
?????? }
?????? else
?????? {
?????????? delegate.releaseConnection(info);
?????? }
??? }
???
???
??? public void setProperty(String property, String value) {
?????? delegate.setProperty(property, value);
?????? }
???
???
??? // Inner class that defines the connection class.
??? public static class MyProtocolConnection {
?????? public MyProtocolConnection()
?????? {
?????????? // ...
?????? }
???
?????? public void close()
?????? {
?????????? // ...
?????? }
??? }
}
- Last Updated:2008年4月18日
- Last Updated:2007年1月10日
Last Updated:2006年4月28日
轉載于:https://www.cnblogs.com/confach/articles/387902.html
總結
以上是生活随笔為你收集整理的BlackBerry 应用程序开发者指南 第一卷:基础--第5章 支持的媒体内容(Media Content)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做梦梦到亲人死了是什么意思
- 下一篇: 做梦梦到吃蜈蚣是什么意思