自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

BES推送應(yīng)用實(shí)例演示與分析

移動(dòng)開發(fā)
本文通過一個(gè)實(shí)際的應(yīng)用案例ECL(Emergency Contact List),來介紹經(jīng)典的BlackBerry通過BES(BlackBerry Enterprise Server)數(shù)據(jù)推送的功能.

本文通過一個(gè)實(shí)際的應(yīng)用案例ECL(Emergency Contact List),來介紹經(jīng)典的BlackBerry通過BES(BlackBerry Enterprise Server)數(shù)據(jù)推送的功能,包括了服務(wù)器端和手機(jī)端的源代碼。

主要演示的技術(shù)點(diǎn)包括:

◆服務(wù)端Java程序如何通過調(diào)用BES服務(wù)器推送功能向手機(jī)推送數(shù)據(jù)

◆手機(jī)端Java應(yīng)用如何偵聽并接收數(shù)據(jù)

◆手機(jī)端Java應(yīng)用如何變換圖標(biāo),以提醒用戶有新的數(shù)據(jù)到達(dá)該手機(jī)該代碼實(shí)例可以運(yùn)行在模擬器環(huán)境(MDS模擬器+BlackBerry手機(jī)模擬器),也可以運(yùn)行在真實(shí)的(BES+BlackBerry真機(jī))環(huán)境。本文主要介紹了在模擬器環(huán)境下代碼運(yùn)行的情況。

注:為方便開發(fā)人員學(xué)習(xí)和使用BlackBerrypush技術(shù),黑莓官方網(wǎng)站上提供了一個(gè)樣例程序Emergency Contact List(簡(jiǎn)稱ECL),包括Java/ASP.NET/Domino三種語言版本,支持瀏覽器Push和Java應(yīng)用程序Push。Java版本的程序源代碼和運(yùn)行腳本在網(wǎng)頁www.blackberry.com/go/ecl上面上可以免費(fèi)下載。在本文中,我們將分析Java版本ECL樣例程序。

各語言版本ECL程序的比較:
 


Database ( s )
Utilized( 數(shù)據(jù)來源 )
Server - Side
Technology
 
BlackBerry Client
Implementation
ECL Version
Push Inter face
 
 
 
 
Java ECL
 
 
Microsoft Excel
 
 
Java EE
 
命令行
Java Application
 
Browser Application
 
 
ASP .NET ECL
Microsoft Excel
 
Microsoft Access
 
Microsof t SQL Server
 
 
 
.NET
命令行
GUI Windows®
 
 
Java Application
 
Browser Application
 

 
 
 
 
S e rvic e
 
P ush Acce ss
P rotoc ol (PAP )
 
 
 
Domino® EC L
 
 
 
I BM L otus Note s
 
 
 
J a va EE
命令行
 
 
L otus Note s 
 
J a va Applica ti on
 
B row s e r A ppli ca ti on

模擬業(yè)務(wù)場(chǎng)景:

ECL(EmergencyContactList)實(shí)例模擬了以下業(yè)務(wù)場(chǎng)景:

1.用戶BlackBerry手機(jī)端安裝ECLJ2ME客戶端應(yīng)用

2.服務(wù)器端為一個(gè)Excel數(shù)據(jù)表(代表數(shù)據(jù)庫)

3.當(dāng)在Excel表中加入新的數(shù)據(jù)或者修改了數(shù)據(jù)后,服務(wù)器端可以發(fā)起一個(gè)推送,將更新后的Excel表內(nèi)容全部推送到BlackBerry手機(jī)

4.BlackBerry手機(jī)用戶注意到手機(jī)端應(yīng)用圖標(biāo)發(fā)生變化,表明有新數(shù)據(jù)到達(dá)手機(jī),即可在手機(jī)上打開應(yīng)用,查看數(shù)據(jù)

***部分演示環(huán)境配置

這里描述了在一臺(tái)電腦上,如何使用模擬器演示該代碼實(shí)例。需要安裝的軟件包括:

◆BlackBerry Emailand MDS Services Simulators 4.1.4

◆BlackBerry Smartphone Simulators 5.0.0(也可以使用4.5,4.6,4.7等版本,但需要通

過Eclipse修改載入不同SDK,詳細(xì)方法見附錄)

◆Eclipse SDK 3.5.1(可選,V3.4也可以,用于研究代碼用)

◆BlackBerry JDE Plug-infor Eclipse Version:1.1.1.2009 11111641-15

安裝以上軟件在一臺(tái)電腦上,一般采用缺省目錄安裝即可。

解壓縮ECL_Java.zip到c:\ECL_Java目錄下,下面解釋一下主要文件夾內(nèi)容和其作用:

◆Readme.txt:使用說明文檔

◆目錄src:代碼源文件目錄,包括手機(jī)端代碼和服務(wù)器端

◆目錄bin:可執(zhí)行文件目錄,用于實(shí)際演示用

第二部分演示過程

1.啟動(dòng)BlackBerry Emailand MDS Services Simulators 4.1.4

2.啟動(dòng)BlackBerry Smartphone Simulators 5.0.0

3.安裝ECLSample.cod文件到手機(jī)模擬器

模擬器:File=>LoadJavaProgram=>選擇5.0版本的ECLSample.cod

4.在DOS命令行下輸入命令:

C:\ECL_Java\bin\Server>runcatchersimulatoremai.txtxyzlist.xls

運(yùn)行后顯示successful push表示推送成功。

5.手機(jī)端應(yīng)用圖標(biāo)發(fā)生變化,然后進(jìn)入應(yīng)用查看信息

6.修改Excel表內(nèi)容,

到C:\ECL_Java\bin\Server目錄下修改xyzlist.xls文件,如把內(nèi)容修改一下,例如將”John Peng”改成“Petter Liang”

7.在DOS命令行下輸入命令:

C:\ECL_Java\bin\Server>runcatchersimulatoremai.txtxyzlist.xls

8.手機(jī)端應(yīng)用圖標(biāo)發(fā)生變化,然后查看更新后的信息

#p#

第三部分手機(jī)端代碼導(dǎo)入Eclipse

1.打開Eclipse,

 2.File–Import,選擇General=>Existing Projects to Workspace

第四部分核心代碼分析

BlackBerryPush架構(gòu)

在分析樣例代碼之前,首先讓我們從整體上了解BlackBerryPush架構(gòu)。

更加詳細(xì)的BlackBerry推送機(jī)制的分析和介紹,請(qǐng)參考黑莓官方網(wǎng)站,以及參考資料“BES服務(wù)器推送機(jī)制分析”。

從示意圖中,我們可以看到,在BlackBerry應(yīng)用平臺(tái)上的數(shù)據(jù)推送從整體上可以分為六步,按時(shí)間順序分別為:

1.應(yīng)用服務(wù)器向MDS/BES服務(wù)器發(fā)送推送請(qǐng)求,該請(qǐng)求為HTTPPOST請(qǐng)求。

2/3:MDS/BES服務(wù)器做必要的權(quán)限和數(shù)據(jù)監(jiān)測(cè),告知應(yīng)用服務(wù)器推送請(qǐng)求是否被接受并將被執(zhí)行。

4:MDS/BES服務(wù)器通過BlackBerryInfrastructure和無線網(wǎng)絡(luò)把數(shù)據(jù)推送到手持設(shè)備端。

5:手持設(shè)備收到數(shù)據(jù)后,向MDS/BES服務(wù)器反饋。

6:MDS/BES服務(wù)器告知應(yīng)用服務(wù)器其推送數(shù)據(jù)是否送達(dá)手持設(shè)備。

ECL系統(tǒng)架構(gòu)

從BlackBerryPush系統(tǒng)架構(gòu)上看,從服務(wù)器端Push數(shù)據(jù)到手機(jī)端,要經(jīng)過多個(gè)服務(wù)器和網(wǎng)絡(luò)甚至無線基站,整個(gè)流程相當(dāng)復(fù)雜。幸運(yùn)的是,從應(yīng)用開發(fā)的角度,程序員可以不考慮Push的復(fù)雜底層實(shí)現(xiàn),而只需簡(jiǎn)單地發(fā)送Push請(qǐng)求并監(jiān)聽Push請(qǐng)求的處理狀態(tài),客戶端監(jiān)聽并接受推送數(shù)據(jù)即可:

1.服務(wù)器程序向MDS/BES服務(wù)器發(fā)送推送請(qǐng)求,所發(fā)送的請(qǐng)求為HTTPPOST

請(qǐng)求。

2.手持設(shè)備上的Java客戶端程序接收push過來的數(shù)據(jù),做出燈光閃爍/振鈴等提示,甚至修改桌面圖標(biāo)提示用戶,用戶打開程序界面查看數(shù)據(jù)。

3.服務(wù)器程序從MDS/BES服務(wù)器獲得推送請(qǐng)求是否完成的狀態(tài)信息。

Java版本ECL服務(wù)器代碼分析

核心代碼說明,Java類列表

Java版本ECL服務(wù)器程序是一個(gè)命令行程序,根據(jù)命令行參數(shù)把指定excel表格中的聯(lián)系人列表contactlist數(shù)據(jù)推送給指定的手機(jī)上。

1.主程序:是eclTimed Update.java,這是一個(gè)包含main()方法的控制程序,根據(jù)不同參數(shù)調(diào)用兩個(gè)Pusher類做Browser Push和Customize Push。

2.核心Push代碼:由Browser Channel Pusher.java/Custom App Pusher.java/Pusher.java三個(gè)類構(gòu)成。

3.服務(wù)器配置信息:MdsProperties.java等四個(gè)類用于讀取配置文本文件,讓ECL服務(wù)器主程序獲得MDS/BES服務(wù)器IP地址端口號(hào)等信息。

4.數(shù)據(jù)訪問:DataReader.java通過JDBC-ODBC接口讀取Excel表單數(shù)據(jù)。

ECL服務(wù)器程序各個(gè)Java類的功能說明列表如下:

根據(jù)參數(shù)構(gòu)造Pusher類(Browser Channel Pusher或者Custom App Pusher)作為整個(gè)服務(wù)器端推送數(shù)據(jù)程序的入口,eclTimed Update.java是一個(gè)標(biāo)準(zhǔn)的J2SE程序。

在main()方法中首先分析***個(gè)參數(shù)。如果參數(shù)值是channel,則構(gòu)造pusher為Browser Channel Pusher類;如果參數(shù)值是catcher,則構(gòu)造pusher為Custom App Pusher類。

  1. public static void main(String[] args)  
  2.  
  3. …  
  4.  
  5. // Process command-line arguments  
  6.  
  7. if (args. length >= 1) {  
  8.  
  9. if (args[0].equalsIgnoreCase( "channel" )) {  
  10.  
  11. // Construct a pusher that sends to a browser channel.  
  12.  
  13. pusher = new BrowserChannelPusher (); //Browser push 也是一個(gè)很有 趣的話 題  
  14.  
  15. } else if (args[0].equalsIgnoreCase( "catcher" )) {  
  16.  
  17. // Construct a pusher that sends to a custom catcher.  
  18.  
  19. pusher = new CustomAppPusher ();  
  20.  
  21. }  
  22.  
  23. }  

根據(jù)參數(shù)從文本文件中讀取BlackBerry手機(jī)PIN碼列表

例如從simulatoremail.txt文件中讀取到的PIN碼為黑莓模擬器的PIN碼2100000a。

提示:BlackBerryMDS/BES服務(wù)器支持以手機(jī)PIN碼和email地址識(shí)別要推送的目標(biāo)手機(jī)。在ECL樣例程序中是使用手機(jī)PIN碼。

  1. if (args.length >= 2) {  
  2.  
  3. emailListFile = args[1];  
  4.  
  5. }  
  6.  
  7. … …  
  8.  
  9. // Get the list of emails to push to.  
  10.  
  11. List recipientEmails = getRecipients(emailListFile);  

根據(jù)參數(shù)從excel表格文件中讀取ECL聯(lián)系人列表

在這里調(diào)用Data Reader類訪問Excel表,讀取每個(gè)組和每個(gè)人的聯(lián)系方式,并通過pusher.add Contact(dataFields);方法把數(shù)據(jù)傳遞給pusher,***調(diào)用pusher.finished Construction();方法告訴pusher數(shù)據(jù)全部讀取完畢。Pusher會(huì)把所有聯(lián)系人方式構(gòu)造成一個(gè)xml字符串保存起來以備下一步調(diào)用pusher.send To Hand held(curRecipient);進(jìn)行發(fā)送。

  1. // Fetch the group names from the spreadsheet.  
  2.  
  3. Vector groupDescription = dataReader.getGroupList();  
  4.  
  5. // Assemble the data of all contacts (from all groups) that we  
  6.  
  7. // will push to handhelds.  
  8.  
  9. for ( int i = 0; i < groupDescription.size(); i++) {  
  10.  
  11. // Define the current group.  
  12.  
  13. pusher.beginGroup((String)groupDescription.elementAt(i));  
  14.  
  15. // Add all its members.  
  16.  
  17. Vector groupContactList = dataReader.getContactList(  
  18.  
  19. (String)groupDescription.elementAt(i));  
  20.  
  21. for ( int j = 0; j < groupContactList.size(); j++) {  
  22.  
  23. String[] dataFields = dataReader.getContactData(  
  24.  
  25. (String)groupContactList.elementAt(j));  
  26.  
  27. pusher.addContact(dataFields);  
  28.  
  29. }  
  30.  
  31. }  
  32.  
  33. // Indicate that we're done building the contacts list. After,  
  34.  
  35. // the pusher is ready to send the message multiple times.  
  36.  
  37. pusher.finishedConstruction();  

調(diào)用pusher.send To Handheld()推送數(shù)據(jù)到每一部黑莓手機(jī)上面做一個(gè)For循環(huán),多次調(diào)用pusher.send To Handheld(cur Recipient)通過BES/MDS服務(wù)器把數(shù)據(jù)發(fā)送到各個(gè)手機(jī)上面。

  1. // Push the message we just built to all recipients.  
  2.  
  3. for ( int i = 0; i < recipientEmails.size(); i++) {  
  4.  
  5. String curRecipient = (String)recipientEmails.get(i);  
  6.  
  7. try {  
  8.  
  9. System. out .print( "Contacting BES for " + curRecipient);  
  10.  
  11. pusher.sendToHandheld(curRecipient); System. out .println( " - successful push." );  
  12.  
  13. } catch (Pusher.MDSConnectionException ex) {  
  14.  
  15. // Unable to connect to MDS. The condition is unlikely  
  16.  
  17. // to be temporary so abort.  
  18.  
  19. System. out .println( " - " + ex.getMessage());  
  20.  
  21. Pusher.java代碼分析  
  22.  
  23. break ;  
  24.  
  25. } catch (Pusher.MDSResponseException ex) {  
  26.  
  27. // Connected OK but MDS responded with error. Log it and  
  28.  
  29. // try the next email.  
  30.  
  31. System. out .println( " - MDS responded with "  
  32.  
  33. + ex.getMessage());  
  34.  
  35. } catch (Exception ex) {  
  36.  
  37. // Unexpected error. Log a full stack trace and try the  
  38.  
  39. // next email.  
  40.  
  41. System. out .println( " - unexpected error:" );  
  42.  
  43. ex.printStackTrace();  
  44.  
  45. }  
  46.  
  47. }  

Pusher.java代碼實(shí)際上包括兩部分內(nèi)容,一部分是準(zhǔn)備要推送的數(shù)據(jù),一部分是真正的推送操作。

Begin Group(),add Contact(),finished Construction()三個(gè)方法是用來準(zhǔn)備要推送的數(shù)據(jù)。主邏輯程序多次調(diào)用這三個(gè)方法告訴Pusher有哪些聯(lián)系人數(shù)據(jù)要推送。Pusher會(huì)把這些數(shù)據(jù)拼裝成一個(gè)html或者是一個(gè)大文本,并最終推送給手機(jī)瀏覽器或者手機(jī)客戶端程序。writeTo(OutputStream)方法用來把前面三個(gè)方法構(gòu)造出來的數(shù)據(jù)寫到輸出流中。

注意:以上4個(gè)方法和push無關(guān),更好的做法應(yīng)該是把他們分離出去做一個(gè)獨(dú)立的數(shù)據(jù)構(gòu)造類。

Pusher.java代碼的核心方法是send To Handheld(Stringrecipient Email)。該方法構(gòu)造標(biāo)準(zhǔn)的http POST請(qǐng)求給MDS/BES服務(wù)器,通過參數(shù)DESTINATION指定要把數(shù)據(jù)push給哪些人(參數(shù)值可以是email地址或者是手機(jī)PIN碼),參數(shù)PORT告知要把數(shù)據(jù)推送到手機(jī)上面哪個(gè)端口(例子代碼中是端口911)。

  1. /**  
  2.  
  3. * Pushes the already - constructed message to the indicated recipient. May  
  4.  
  5. * be used many times, but only in the "sending" state.  
  6.  
  7. */  
  8.  
  9. public void sendToHandheld(String recipientEmail)  
  10.  
  11. throws IOException, MDSConnectionException, MDSResponseException  
  12.  
  13. {  
  14.  
  15. HttpURLConnection conn = null ;  
  16.  
  17. OutputStream out = null ;  
  18.  
  19. try {  
  20.  
  21. // Build the URL to define our connection to the BES.  
  22.  
  23. URL url = new URL( "http" , _props .getBesHostName(),  
  24.  
  25. _props .getBesPushPort(),  
  26.  
  27. "/push?DESTINATION=" + recipientEmail  
  28.  
  29. + "&PORT=" + getDevicePort()  
  30.  
  31. + "&REQUESTURI=/" );  
  32.  
  33. conn = (HttpURLConnection)url.openConnection();  
  34.  
  35. conn.setDoOutput(true ); //to post data  
  36.  
  37. conn.setRequestMethod("POST" );  
  38.  
  39. establishRequestHeaders(conn);  
  40.  
  41. //write the data to the http connection  
  42.  
  43. out = conn.getOutputStream();  
  44.  
  45. writeTo(out);  
  46.  
  47. // Check the MDS's response so that we report an error if the push  
  48.  
  49. // was unsuccessful.  
  50.  
  51. int responseCode = conn.getResponseCode();  
  52.  
  53. if (responseCode != HttpURLConnection. HTTP_OK ) {  
  54.  
  55. String serverMessage = conn.getResponseMessage();  
  56.  
  57. throw new MDSResponseException(  
  58.  
  59. "HTTP-" + responseCode + ": " + serverMessage);  
  60.  
  61. }  

核心代碼說明,Java類列表

客戶端代碼由三個(gè)Java類,兩個(gè)圖標(biāo)文件,BlackBerry應(yīng)用描述文件構(gòu)成。

ECL客戶端程序三個(gè)Java類的功能說明列表如下:

Java Class
 
 
 
 
Pushe d D a t a Lis t ener
在指定端口 911 上監(jiān)聽 push 過來的數(shù)據(jù)。收到后調(diào)用 Da taSt or e  改手機(jī)上應(yīng)用的圖標(biāo)以提 示用戶有更新過的聯(lián)系人列表。
 
 
 
 
EC LApplic a t i on
客戶端主程序,通過配置,最終會(huì)在客戶端啟動(dòng)兩個(gè) J a va 進(jìn)程:后臺(tái)運(yùn)行的
P ushed Da ta L ist e ne r  來監(jiān)聽   push 過來的數(shù)據(jù);
前臺(tái)   GU I 界面   EC L App li ca ti on 和內(nèi)部類
Ec lS c re e n 用于展現(xiàn) 到的 push 數(shù)據(jù)  聯(lián)系人列 表。
 
Da taSt or e
使用
net.rim.device.api.system.PersistentStore
保存最 的 ECL 聯(lián) 人員 表數(shù)據(jù)。

 

ECL客戶端程序的兩個(gè)入口點(diǎn)(AlternateEntryPoints)

ECL客戶端程序是如何自動(dòng)啟動(dòng)監(jiān)聽程序的?又是如何區(qū)分點(diǎn)擊icon啟動(dòng)GUI界面程序的呢?答案在應(yīng)用描述文件BlackBerry_App_Descriptor.xml和主程序的main()方法上。

打開BlackBerry_App_Descriptor.xml,在Application標(biāo)簽欄目里面,你會(huì)看到Auto-runonstartup被選中。這樣,ECLSample程序會(huì)在手機(jī)啟動(dòng)過程中自動(dòng)地啟動(dòng),產(chǎn)生一個(gè)后臺(tái)Java進(jìn)程監(jiān)聽Push數(shù)據(jù)。

在Alternate Entry Points欄目中,設(shè)置了一個(gè)參數(shù)Applicationargument為gui,并單獨(dú)設(shè)置了程序Title和Icon,因此程序安裝后在“下載”目錄里面出現(xiàn)一個(gè)應(yīng)用圖標(biāo)。點(diǎn)擊圖標(biāo)將產(chǎn)生一個(gè)前臺(tái)GUI進(jìn)程來讀取并顯示Push過來的數(shù)據(jù)。

#p#

ECL Application客戶端主程序說明

在ECL Application的main()方法中,如果沒有任何參數(shù)傳進(jìn)來,那么就是說程序是在手機(jī)啟動(dòng)的時(shí)候被初始化調(diào)用的,啟動(dòng)Pushed Data Listener線程在后臺(tái)運(yùn)行,監(jiān)聽push來的數(shù)據(jù)。

  1. class ECLApplication extends UiApplication {  
  2.  
  3. private MenuItem _copyItem ;  
  4.  
  5. /******************************************************************************************  
  6.  
  7. * main() - controls the startup of the application...thread will start i n the background  
  8.  
  9. * and the GUI starts when user clicks from main menu  
  10.  
  11. ******************************************************************************************/  
  12.  
  13. public static void main(String[] args) {  
  14.  
  15. if ( args != null && args. length > 0) { //entry point 是有參數(shù) 的,那么 打開 GUI 窗口  
  16.  
  17. ECLApplication theApp = new ECLApplication();  
  18.  
  19. theApp.enterEventDispatcher();  
  20.  
  21. }  
  22.  
  23. else { //entry point 是沒有參 數(shù)的, 那么啟 動(dòng) Pu sh ed Da ta Li st en er 線程在后 臺(tái)運(yùn) 行,監(jiān)聽 push 來的數(shù) 據(jù)  
  24.  
  25. PushedDataListener.waitForSingleton ().start();  
  26.  
  27. }  
  28.  
  29. }  

在ECL Application的main()方法中,如果發(fā)現(xiàn)有參數(shù)傳進(jìn)來,那么說是有用戶點(diǎn)擊了應(yīng)用圖標(biāo),想打開GUI界面查看數(shù)據(jù)。

  1. class ECLApplication extends UiApplication {  
  2.  
  3. public static void main(String[] args) {  
  4.  
  5. if ( args != null && args. length > 0) { //entry point 是有參數(shù) 的,那么 打開 GUI 窗口  
  6.  
  7. ECLApplication theApp = new ECLApplication();  
  8.  
  9. theApp.enterEventDispatcher();  
  10.  
  11. }  
  12.  
  13. else { //entry point 是沒有參 數(shù)的, 那么啟 動(dòng) Pu sh ed Da ta Li st en er 線程在后 臺(tái)運(yùn) 行,監(jiān)聽 push 來的數(shù) 據(jù)  
  14.  
  15. PushedDataListener.waitForSingleton ().start();  
  16.  
  17. }  
  18.  
  19. }  

在ECLApplication構(gòu)造方法中,首先把應(yīng)用的圖標(biāo)從未讀狀態(tài),修改為已讀狀態(tài);然后調(diào)用DataStore類讀取PersistentStore里面的數(shù)據(jù),***彈出EclScreen窗口以樹狀組件顯示數(shù)據(jù)。

DataStore和EclScreen代碼因?yàn)楹蚉ush操作無關(guān),這里就不再做代碼分析了。

  1. public ECLApplication () {  
  2.  
  3. …  
  4.  
  5. Bitmap icon=Bitmap.getBitmapResource("icon/read.gif");  
  6.  
  7. net.rim.blackberry.api.homescreen.HomeScreen.updateIcon(icon);  
  8.  
  9. //call the datastore class  
  10.  
  11. DataStore dataStore = new DataStore();  
  12.  
  13. //opens the persistent store and loads in the group list dataStore.loadGroupListFromStore();  
  14.  
  15. EclScreen screen = new EclScreen(dataStore);  
  16.  
  17. pushScreen(screen);  
  18.  
  19. }  

Pushed Data Listener代碼說明

Push監(jiān)聽代碼是客戶端最核心的代碼。Push.java首先是使用wait For Singleton()方法達(dá)到手機(jī)上只有一個(gè)Pushed Data Listener對(duì)象在運(yùn)行的目的,然后構(gòu)建并啟動(dòng)Listener Thread類開始監(jiān)聽。

wait For Singleton()方法把唯一的Pushed Data Listener對(duì)象實(shí)例保存到Runtime Store對(duì)象中,從而實(shí)現(xiàn)singleton模式。Runtime Store在黑莓手機(jī)中是程序間共享的存儲(chǔ)空間,或者說所有程序都可以訪問其他程序保存在Runtime Store里面的數(shù)據(jù)。在手機(jī)重新啟動(dòng)后,Runtime Store被清空。

  1. class PushedDataListener extends UiApplication {  
  2.  
  3. ime  
  4.  
  5. public static final long RTSID_MY_APP = 0x56b19e51d45ff827L;  
  6.  
  7. private static final String LISTEN_URL = "http://:911" ; //the listen port  
  8.  
  9. private ListenerThread myThread ;  
  10.  
  11. public PushedDataListener() {  
  12.  
  13. myThread = new ListenerThread();  
  14.  
  15. }  
  16.  
  17. public static PushedDataListener waitForSingleton (){  
  18.  
  19. Push.java Pushed Data Listener的監(jiān)聽代碼放在Listener Thread類中。Listener Thread類擴(kuò)展  
  20.  
  21. //make sure this is a singleton instance  
  22.  
  23. RuntimeStore store = RuntimeStore.getRuntimeStore ();  
  24.  
  25. Object o = store.get( RTSID_MY_APP );  
  26.  
  27. if (o == null ){  
  28.  
  29. store.put( RTSID_MY_APP , new PushedDataListener());  
  30.  
  31. return (PushedDataListener)store.get( RTSID_MY_APP );  
  32.  
  33. } else {  
  34.  
  35. return (PushedDataListener)o;  
  36.  
  37. }  
  38.  
  39. }  

Thread線程類,調(diào)用(Stream Connection Notifier)Connector.open(LISTEN_URL)方法和stream=notify.acceptAndOpen();代碼開始監(jiān)聽911端口上push過來的數(shù)據(jù)。

收到數(shù)據(jù)后調(diào)用Data Store方法保存數(shù)據(jù)到持久存儲(chǔ)中,工ECLGUI進(jìn)程顯示數(shù)據(jù);然后調(diào)用Home Screen.update Icon(icon,1)代碼更新ECL圖標(biāo)為未讀提示。

  1. class ListenerThread extends Thread {  
  2.  
  3. public void run() {  
  4.  
  5. System. out .println( "eclBackGroundThread -- running" ); StreamConnectionNotifier notify = null ;  
  6.  
  7. StreamConnection stream = null ; InputStream input = null ;  
  8.  
  9. try {  
  10.  
  11. sleep (1000);  
  12.  
  13. }  
  14.  
  15. catch (Exception e){}  
  16.  
  17. try {  
  18.  
  19. notify = (StreamConnectionNotifier)Connector. open ( LISTEN_URL );  
  20.  
  21. for (;;) {  
  22.  
  23. //NOTE: the following will block until data is received  
  24.  
  25. stream = notify.acceptAndOpen();  
  26.  
  27. input = stream.openInputStream();  

后記:

  1. //Extract the data from the input stream  
  2.  
  3. StringBuffer sb = new StringBuffer();  
  4.  
  5. int datum = -1;  
  6.  
  7. while ( -1 != (datum = input.read()) )  
  8.  
  9. {  
  10.  
  11. sb.append(( char )datum);  
  12.  
  13. }  
  14.  
  15. stream.close();  
  16.  
  17. stream = null ;  
  18.  
  19. String contactData = sb.toString(); DataStore dataStore = new DataStore(); dataStore.saveData(contactData);  
  20.  
  21. Bitmap icon=Bitmap.getBitmapResource ( "icon/unread.gif" );  
  22.  
  23. net.rim.blackberry.api.homescreen.HomeScreen. updateIcon (icon,1);  
  24.  
  25. bytes) \n" );  
  26.  
  27. System. err .println( "Push message received...(" +contactData.length()+ "  
  28.  
  29. System. err .println(contactData);  

常見運(yùn)行錯(cuò)誤處理

1.模擬器無法收到Push數(shù)據(jù)

解決辦法:使用***的BlackberryPluginforeclipse1.1版本,運(yùn)行項(xiàng)目的時(shí)

候選擇啟動(dòng)MDS模擬器。啟動(dòng)模擬器后,確認(rèn)模擬器的網(wǎng)絡(luò)連接是好的,方法是打開瀏

覽器訪問任意外網(wǎng)網(wǎng)站。

2.服務(wù)器端和客戶端程序各自的端口不匹配

解決辦法:在ECL例子程序中兩個(gè)端口都是911,注意查看。如果你參考ECL代碼編寫自己的Push程序,那么建議你把服務(wù)器和客戶端的端口都修改為非911的端口,以避免在手機(jī)上參數(shù)監(jiān)聽端口沖突。

3.客戶端程序沒有autostart,因而沒能啟動(dòng)監(jiān)聽程序

解決辦法:在ECL例子程序中,編輯BlackBerry_App_Descriptor.xml,選擇Auto-runonstartup,并在代碼的main()方法中相應(yīng)處理,啟動(dòng)listenerthread在后臺(tái)開始監(jiān)聽。

4.客戶端收到的文字中文亂碼解決辦法:首先,服務(wù)器端代碼在提出Push請(qǐng)求時(shí)候要通過Http URL Connection.set Request Property(("Content-Type",…)方法告訴BES/MDS服務(wù)器,它將發(fā)送什么樣的內(nèi)容。如果是Content-Type是text/plain,那么服務(wù)器將以gb2312編碼發(fā)送數(shù)據(jù);為代碼清晰起見,建議設(shè)置Content-Type為text/plain;charset=utf-8。

  1. public void sendToHandheld(String recipientEmail) … {  
  2.  
  3. HttpURLConnection conn = null;  
  4.  
  5. …  
  6.  
  7. establishRequestHeaders(conn);  
  8.  
  9. …  
  10.  
  11. }  
  12.  
  13. protected void establishRequestHeaders(HttpURLConnection conn) {  
  14.  
  15. conn.setRequestProperty("Content-Type", "text/plain ; charset=utf-8 ");  
  16.  
  17. }  

其次,客戶端接收數(shù)據(jù)的時(shí)候,建議讀取byte[],然后按照服務(wù)器Content-Type相同的編碼進(jìn)行轉(zhuǎn)碼獲得字符串String。

  1. stream = notify.acceptAndOpen();  
  2.  
  3. input = stream.openInputStream();  
  4.  
  5. //Extract the data from the input stream byte[] bytes = loadBytesFromStream(input); stream.close();  
  6.  
  7. stream = null;  
  8.  
  9. String contactData = new String(bytes , “UTF-8” );  

英文縮寫說明

BES–BlackBerry Enterprise Server,是BlackBerry解決方案的核心服務(wù)器之一,架設(shè)在企業(yè)內(nèi)網(wǎng)。

MDS–BlackBerryMobileDataSystem,是BES服務(wù)器的一個(gè)重要組件。在Push技術(shù)中,

MDS接受Push請(qǐng)求,然后通過BES其他組件把數(shù)據(jù)推送出去。

參考資料

1.BES服務(wù)器推送機(jī)制分析

http://www.searchcio.com.cn/whitepaper_1161.htm

2.What Is-Sample applications demonstrating BlackBerry pushtechnology:Emergency ContactList

http://www.blackberry.com/go/ecl

附錄:

一.如何更換不同版本的BlackBerry SDK?

由于不同BlackBerry手機(jī)使用不同版本的OS,所以在應(yīng)用編譯的時(shí)候,需要使用不同的

BlackBerry SDK。

首先可以在Eclipse中獲取所有版本的BlackBerry SDK,目前有的包括4.5,4.6和5.0版本:Eclipse=>Help=>InstallNewSoftware=>輸入U(xiǎn)RL:

http://www.blackberry.com/go/eclipseUpdate/3.5/java

然后進(jìn)行更新即可。

二.如何選擇不同版本的BlackBerry SDK?

在上圖中選擇Edit

然后再次編譯即可:

或者:在JRE System Library右擊鼠標(biāo),屬性中選擇不同的SDK即可。

三.ECLsampleBrowserpush中文問題的解決

現(xiàn)象:xyzlist.xls數(shù)據(jù)源里面有中文,通過MDS服務(wù)器push到手機(jī)里面的網(wǎng)頁,中文是亂碼,顯示不正常。

step1.編輯ECL_Java\src\Server\BrowserChannelPusher.java把con.set Request Property('Content-Type','text/html');

修改為con.setRequestProperty('Content-Type','text/html;charset=gb2312');

step2.重新編譯生成ECL_Java\bin\Server\ecl.jar執(zhí)行ECL_Java\src\Server\build.bat

step3.重新運(yùn)行pushserver/client測(cè)試即可

責(zé)任編輯:佚名 來源: BBturials
相關(guān)推薦

2009-11-06 15:02:47

WCF契約查詢

2010-09-09 22:41:18

2009-08-18 13:30:01

C#安裝與部署

2020-06-04 12:15:08

Pythonkafka代碼

2010-06-02 11:34:23

MySQL 數(shù)據(jù)庫導(dǎo)入

2020-04-22 09:33:41

數(shù)據(jù)護(hù)欄行為分析數(shù)據(jù)庫安全

2009-07-17 17:16:48

Spring iBAT

2010-06-04 10:40:55

AJAX MySQL

2009-08-13 18:26:35

C#繼承構(gòu)造函數(shù)

2015-10-09 10:19:48

大數(shù)據(jù)醫(yī)療健康

2009-09-14 17:03:32

LINQ模糊查詢

2009-11-05 13:54:07

WCF Service

2024-04-07 07:49:05

C#Switch模式匹配

2010-06-01 14:42:55

連接MySQL數(shù)據(jù)庫

2009-09-01 18:29:10

C#繼承C#多態(tài)

2010-04-14 12:51:04

Oracle動(dòng)態(tài)

2010-05-18 09:02:55

MySQL條件查詢

2010-04-21 15:02:50

Oracle使用游標(biāo)

2010-04-20 08:53:42

Oracle左連接

2009-08-18 10:17:25

C#枚舉類型
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)