亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

J2ME藍牙程序開發實戰入門

2019-11-17 05:55:53
字體:
來源:轉載
供稿:網友
  概述 目前,很多手機已經具備了藍牙功能。雖然MIDP2.0沒有包括藍牙API,但是JCP定義了JSR82, java APIs for Bluetooth Wireless Technology (JABWT).這是一個可選API,很多支持MIDP2.0的手機已經實現了,比如Nokia 6600, Nokia 6670,Nokia7610等等。對于一個開發者來說,假如目標平臺支持JSR82的話,在制作聯網對戰類型游戲或者應用的時候,藍牙是一個相當不錯的選擇。本文給出了一個最簡單的藍牙應用的J2ME程序,用以幫助開發者快速的把握JSR82。該程序分別在2臺藍牙設備上安裝后,一臺設備作為服務端先運行,一臺設備作為客戶端后運行。在服務端上我們發布了一個服務,該服務的功能是把客戶端發過來的字符串轉變為大寫字符串??蛻舳似饎硬⑺阉鞯椒斩说姆蘸?,我們就可以從客戶端的輸入框里輸入任意的字符串,發送到服務端去,同時觀察服務端的反饋結果。

    本文并不具體講述藍牙的運行機制和JSR82的API結構,關于這些知識點,請參考本文的參考資料一節,這些參考資料會給你一個權威的精確的解釋。

  實例代碼


  該程序包括3個java文件。一個是MIDlet,另外2個為服務端GUI和客戶端GUI。該程序已經在wtk22模擬器和Nokia 6600,Nokia 6670兩款手機上測試通過。

  StupidBTMIDlet.java

  1. import javax.microedition.lcdui.Alert;
  2. import javax.microedition.lcdui.AlertType;
  3. import javax.microedition.lcdui.Command;
  4. import javax.microedition.lcdui.CommandListener;
  5. import javax.microedition.lcdui.Display;
  6. import javax.microedition.lcdui.Displayable;
  7. import javax.microedition.lcdui.List;
  8. import javax.microedition.midlet.MIDlet;
  9. import javax.microedition.midlet.MIDletStateChangeException;
  10. /**
  11.  * @author Jagie
  12.  * 
  13.  *  MIDlet
  14.  */
  15. public class StupidBTMIDlet extends MIDlet implements CommandListener {
  16.     List list;
  17.     ServerBox sb;
  18.     ClientBox cb;
  19.     /*
  20.      * (non-Javadoc)
  21.      * 
  22.      * @see javax.microedition.midlet.MIDlet#startApp()
  23.      */
  24.     PRotected void startApp() throws MIDletStateChangeException {
  25.         list = new List("傻瓜藍牙入門", List.IMPLICIT);
  26.         list.append("Client", null);
  27.         list.append("Server", null);
  28.         list.setCommandListener(this);
  29.         Display.getDisplay(this).setCurrent(list);
  30.     }
  31.     
  32.     /**
  33.      * debug方法
  34.      * @param s 要顯示的字串
  35.      */
  36.     public void showString(String s) {
  37.         Displayable dp = Display.getDisplay(this).getCurrent();
  38.         Alert al = new Alert(null, s, null, AlertType.INFO);
  39.         al.setTimeout(2000);
  40.         Display.getDisplay(this).setCurrent(al, dp);
  41.     }
  42.     
  43.     /**
  44.      * 顯示主菜單
  45.      *
  46.      */
  47.     public void showMainMenu() {
  48.         Display.getDisplay(this).setCurrent(list);
  49.     }
  50.     
  51.     protected void pauseApp() {
  52.         // TODO Auto-generated method stub
  53.     }
  54.     public void commandAction(Command com, Displayable disp) {
  55.         if (com == List.SELECT_COMMAND) {
  56.             List list = (List) disp;
  57.             int index = list.getSelectedIndex();
  58.             if (index == 1) {
  59.                 if (sb == null) {
  60.                     sb = new ServerBox(this);
  61.                 }
  62.                 sb.setString(null);
  63.                 Display.getDisplay(this).setCurrent(sb);
  64.             } else {
  65.                 //每次都生成新的客戶端實例
  66.                 cb = null;
  67.                 System.gc();
  68.                 cb = new ClientBox(this);
  69.                 Display.getDisplay(this).setCurrent(cb);
  70.             }
  71.         }
  72.     }
  73.     protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
  74.         // TODO Auto-generated method stub
  75.     }
  76. }

  ClientBox.java

  1. import java.io.DataInputStream;
  2. import java.io.DataOutputStream;
  3. import java.io.IOException;
  4. import java.util.Vector;
  5. import javax.microedition.io.Connector;
  6. import javax.microedition.io.StreamConnection;
  7. import javax.microedition.lcdui.Command;
  8. import javax.microedition.lcdui.CommandListener;
  9. import javax.microedition.lcdui.Displayable;
  10. import javax.microedition.lcdui.Form;
  11. import javax.microedition.lcdui.Gauge;
  12. import javax.microedition.lcdui.StringItem;
  13. import javax.microedition.lcdui.TextField;
  14. //jsr082 API
  15. import javax.bluetooth.BluetoothStateException;
  16. import javax.bluetooth.DeviceClass;
  17. import javax.bluetooth.DiscoveryAgent;
  18. import javax.bluetooth.DiscoveryListener;
  19. import javax.bluetooth.LocalDevice;
  20. import javax.bluetooth.RemoteDevice;
  21. import javax.bluetooth.ServiceRecord;
  22. import javax.bluetooth.UUID;
  23. /**
  24.  * 客戶端GUI
  25.  * @author Jagie
  26.  *
  27.  * TODO To change the template for this generated type comment go to
  28.  * Window - Preferences - Java - Code Style - Code Templates
  29.  */
  30. public class ClientBox extends Form implements Runnable, CommandListener,
  31.         DiscoveryListener {
  32.     
  33.     //字串輸入框
  34.     TextField input = new TextField(null, "", 50, TextField.ANY);
  35.     //loger
  36.     StringItem result = new StringItem("結果:", "");
  37.     private DiscoveryAgent discoveryAgent;
  38.     
  39.     private UUID[] uuidSet;
  40.     //響應服務的UUID
  41.     private static final UUID ECHO_SERVER_UUID = new UUID(
  42.             "F0E0D0C0B0A000908070605040302010", false);
  43.     //設備集合
  44.     Vector devices = new Vector();
  45.     //服務集合
  46.     Vector records = new Vector();
  47.     
  48.     //服務搜索的事務id集合
  49.     int[] transIDs;
  50.     StupidBTMIDlet midlet;
  51.     public ClientBox(StupidBTMIDlet midlet) {
  52.         super("");
  53.         this.midlet=midlet;
  54.         
  55.         this.append(result);
  56.         
  57.         this.addCommand(new Command("取消",Command.CANCEL,1));
  58.         this.setCommandListener(this);
  59.         
  60.         new Thread(this).start();
  61.     }
  62.     
  63.     public void commandAction(Command arg0, Displayable arg1) {
  64.         if(arg0.getCommandType()==Command.CANCEL){
  65.             midlet.showMainMenu();
  66.         }else{
  67.             //匿名內部Thread,訪問遠程服務。
  68.             Thread fetchThread=new Thread(){
  69.                 public void run(){
  70.                     for(int i=0;i<records.size();i++){
  71.                         ServiceRecord sr=(ServiceRecord)records.elementAt(i);
  72.                         if(accessService(sr)){
  73.                             //訪問到一個可用的服務即可
  74.                             break;
  75.                         }
  76.                     }
  77.                 }
  78.             };
  79.             fetchThread.start();
  80.         }
  81.         
  82.     }
  83.     
  84.     
  85.     private boolean  accessService(ServiceRecord sr){
  86.         boolean result=false;
  87.          try {
  88.             String url = sr.getConnectionURL(
  89.                     ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
  90.             StreamConnection    conn = (StreamConnection) Connector.open(url);
  91.             
  92.             DataOutputStream dos=conn.openDataOutputStream();
  93.             dos.writeUTF(input.getString());
  94.             dos.close();
  95.             DataInputStream dis=conn.openDataInputStream();
  96.             String echo=dis.readUTF();
  97.             dis.close();
  98.             showInfo("反饋結果是:"+echo);
  99.             result=true;
  100.             
  101.         } catch (IOException e) {
  102.             
  103.         }
  104.         return result;
  105.     }
  106.     public synchronized void run() {
  107.         //發現設備和服務的過程中,給用戶以Gauge
  108.         Gauge g=new Gauge(null,false,Gauge.INDEFINITE,Gauge.CONTINUOUS_RUNNING);
  109.         this.append(g);
  110.         showInfo("藍牙初始化...");
  111.         boolean isBTReady = false;
  112.         try {
  113.             LocalDevice localDevice = LocalDevice.getLocalDevice();
  114.             discoveryAgent = localDevice.getDiscoveryAgent();
  115.             isBTReady = true;
  116.         } catch (Exception e) {
  117.             e.printStackTrace();
  118.         }
  119.         if (!isBTReady) {
  120.             showInfo("藍牙不可用");
  121.             //刪除Gauge
  122.             this.delete(1);
  123.             return;
  124.         }
  125.         uuidSet = new UUID[2];
  126.         //標志我們的響應服務的UUID集合
  127.         uuidSet[0] = new UUID(0x1101);
  128.         uuidSet[1] = ECHO_SERVER_UUID;
  129.         
  130.         try {
  131.             discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
  132.         } catch (BluetoothStateException e) {
  133.         }
  134.         try {
  135.             //阻塞,由inquiryCompleted()回調方法喚醒
  136.             wait();
  137.         } catch (InterruptedException e1) {
  138.             
  139.             e1.printStackTrace();
  140.         }
  141.         showInfo("設備搜索完畢,共找到"+devices.size()+"個設備,開始搜索服務");
  142.         transIDs = new int[devices.size()];
  143.         for (int i = 0; i < devices.size(); i++) {
  144.             RemoteDevice rd = (RemoteDevice) devices.elementAt(i);
  145.             try {
  146.                 //記錄每一次服務搜索的事務id
  147.                 transIDs[i] = discoveryAgent.searchServices(null, uuidSet,
  148.                         rd, this);
  149.             } catch (BluetoothStateException e) {
  150.                 continue;
  151.             }
  152.         }
  153.         
  154.         try {
  155.             //阻塞,由serviceSearchCompleted()回調方法在所有設備都搜索完的情況下喚醒
  156.             wait();
  157.         } catch (InterruptedException e1) {
  158.             e1.printStackTrace();
  159.         }
  160.         
  161.         showInfo("服務搜索完畢,共找到"+records.size()+"個服務,預備發送請求");
  162.         if(records.size()>0){
  163.             this.append(input);
  164.             this.addCommand(new Command("發送",Command.OK,0));
  165.         }
  166.         
  167.         //刪除Gauge
  168.         this.delete(1);
  169.         
  170.     }
  171.     
  172.     /**
  173.      * debug
  174.      * @param s
  175.      */
  176.     
  177.     private void showInfo(String s){
  178.         StringBuffer sb=new StringBuffer(result.getText());
  179.         if(sb.length()>0){
  180.             sb.append("/n");
  181.         }
  182.         sb.append(s);
  183.         result.setText(sb.toString());
  184.     }
  185.     
  186.     /**
  187.      * 回調方法
  188.      */
  189.     public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
  190.         if (devices.indexOf(btDevice) == -1) {
  191.             devices.addElement(btDevice);
  192.         }
  193.     }
  194.     /**
  195.      * 回調方法,喚醒初始化線程
  196.      */
  197.     public void inquiryCompleted(int discType) {
  198.         synchronized (this) {
  199.             notify();
  200.         }
  201.     }
  202.     /**
  203.      * 回調方法
  204.      */
  205.     public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
  206.         for (int i = 0; i < servRecord.length; i++) {
  207.             records.addElement(servRecord[i]);
  208.         }
  209.     }
  210.     
  211.     /**
  212.      * 回調方法,喚醒初始化線程
  213.      */
  214.     public void serviceSearchCompleted(int transID, int respCode) {
  215.         
  216.         for (int i = 0; i < transIDs.length; i++) {
  217.             if (transIDs[i] == transID) {
  218.                 transIDs[i] = -1;
  219.                 break;
  220.             }
  221.         }
  222.         
  223.         //假如所有的設備都已經搜索服務完畢,則喚醒初始化線程。
  224.         boolean finished = true;
  225.         for (int i = 0; i < transIDs.length; i++) {
  226.             if (transIDs[i] != -1) {
  227.                 finished = false;
  228.                 break;
  229.             }
  230.         }
  231.         if (finished) {
  232.             synchronized (this) {
  233.                 notify();
  234.             }
  235.         }
  236.     }
  237. }

  ServerBox.java

  1. import java.io.DataInputStream;
  2. import java.io.DataOutputStream;
  3. import java.io.IOException;
  4. import java.util.Vector;
  5. import javax.bluetooth.DiscoveryAgent;
  6. import javax.bluetooth.LocalDevice;
  7. import javax.bluetooth.ServiceRecord;
  8. import javax.bluetooth.UUID;
  9. import javax.microedition.io.Connector;
  10. import javax.microedition.io.StreamConnection;
  11. import javax.microedition.io.StreamConnectionNotifier;
  12. import javax.microedition.lcdui.Command;
  13. import javax.microedition.lcdui.CommandListener;
  14. import javax.microedition.lcdui.Displayable;
  15. import javax.microedition.lcdui.TextBox;
  16. import javax.microedition.lcdui.TextField;
  17. /**
  18.  * 服務端GUI
  19.  * @author Jagie
  20.  *
  21.  * TODO To change the template for this generated type comment go to
  22.  * Window - Preferences - Java - Code Style - Code Templates
  23.  */
  24. public class ServerBox extends TextBox implements Runnable, CommandListener {
  25.     Command com_pub = new Command("開啟服務", Command.OK, 0);
  26.     Command com_cancel = new Command("終止服務", Command.CANCEL, 0);
  27.     Command com_back = new Command("返回", Command.BACK, 1);
  28.     LocalDevice localDevice;
  29.     StreamConnectionNotifier notifier;
  30.     ServiceRecord record;
  31.     boolean isClosed;
  32.     ClientProcessor processor;
  33.     StupidBTMIDlet midlet;
  34.     //響應服務的uuid
  35.     private static final UUID ECHO_SERVER_UUID = new UUID(
  36.             "F0E0D0C0B0A000908070605040302010", false);
  37.     public ServerBox(StupidBTMIDlet midlet) {
  38.         super(null, "", 500, TextField.ANY);
  39.         this.midlet = midlet;
  40.         this.addCommand(com_pub);
  41.         this.addCommand(com_back);
  42.         this.setCommandListener(this);
  43.     }
  44.     public void run() {
  45.         boolean isBTReady = false;
  46.         try {
  47.             localDevice = LocalDevice.getLocalDevice();
  48.             if (!localDevice.setDiscoverable(DiscoveryAgent.GIAC)) {
  49.                 showInfo("無法設置設備發現模式");
  50.                 return;
  51.             }
  52.             // prepare a URL to create a notifier
  53.             StringBuffer url = new StringBuffer("btspp://");
  54.             // indicate this is a server
  55.             url.append("localhost").append(':');
  56.             // add the UUID to identify this service
  57.             url.append(ECHO_SERVER_UUID.toString());
  58.             // add the name for our service
  59.             url.append(";name=Echo Server");
  60.             // request all of the client not to be authorized
  61.             // some devices fail on authorize=true
  62.             url.append(";authorize=false");
  63.             // create notifier now
  64.             notifier = (StreamConnectionNotifier) Connector
  65.                     .open(url.toString());
  66.             record = localDevice.getRecord(notifier);
  67.             // remember we've reached this point.
  68.             isBTReady = true;
  69.         } catch (Exception e) {
  70.             e.printStackTrace();
  71.             
  72.         }
  73.         // nothing to do if no bluetooth available
  74.         if (isBTReady) {
  75.             showInfo("初始化成功,等待連接");
  76.             this.removeCommand(com_pub);
  77.             this.addCommand(com_cancel);
  78.         } 
    else {


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美大片免费看| 一区二区三区视频免费在线观看| 在线免费看av不卡| 欧美xxxwww| 午夜精品久久久久久久久久久久久| 亚洲男人的天堂网站| 91美女福利视频高清| 亚洲欧美日韩一区在线| 亚洲国产精品免费| 欧美放荡办公室videos4k| 国产中文字幕91| 欧美大片va欧美在线播放| 深夜精品寂寞黄网站在线观看| 亚洲国产成人av在线| 亚洲2020天天堂在线观看| 国产精品久久久久久久天堂| 91精品久久久久久久久久久| 欧美成年人视频| 亚洲a中文字幕| 成人福利网站在线观看11| 欧美黑人xxxx| www.亚洲男人天堂| 亚洲电影成人av99爱色| 欧美精品在线观看| 亚洲国产精久久久久久| 亚洲成人久久电影| 欧美亚洲视频在线看网址| 欧美精品www在线观看| 亚洲精品视频在线播放| 中文字幕亚洲一区在线观看| 久久精品国产免费观看| 亚洲人成电影网站色…| 一区二区福利视频| 国内精品视频一区| 日韩免费不卡av| 欧美国产日韩一区| 日韩视频在线免费观看| 91在线精品播放| 国产美女主播一区| 久久国产精品久久久| 国产精品海角社区在线观看| 97碰碰碰免费色视频| 久久6免费高清热精品| 欧美日韩在线视频一区二区| 精品女厕一区二区三区| 日韩欧美高清在线视频| 97国产精品免费视频| 一区二区欧美亚洲| 午夜精品久久久久久久男人的天堂| 亚洲视频网站在线观看| 国产成人在线播放| 亚洲精品欧美日韩| 国产日韩欧美成人| 欧美国产精品va在线观看| 欧美性xxxx极品hd欧美风情| 欧美一级黑人aaaaaaa做受| 日韩精品在线免费观看| 精品福利视频导航| 一区二区欧美亚洲| 精品日韩视频在线观看| 欧美国产在线视频| 午夜剧场成人观在线视频免费观看| 国产精品av在线播放| 久久久国产精彩视频美女艺术照福利| 伊人av综合网| 91国内精品久久| 亚洲国产婷婷香蕉久久久久久| 亚洲精品久久久久久久久久久| 国产亚洲精品一区二区| 大桥未久av一区二区三区| 成人在线小视频| 国产精品久久久久久久久久ktv| 中文国产亚洲喷潮| 亚洲欧美资源在线| 91精品免费视频| 亚洲国产精品久久久久久| 国内成人精品视频| 国产91精品久久久久久久| 亚洲一区999| 亚洲欧美成人精品| 亚洲护士老师的毛茸茸最新章节| 日韩成人在线免费观看| 亚洲色图激情小说| 最新69国产成人精品视频免费| 国产欧美日韩综合精品| 亚洲精品一区二三区不卡| 国产成人极品视频| 亚洲人高潮女人毛茸茸| 亚洲国产成人精品久久| 欧美成人精品一区二区| 亚洲精品成a人在线观看| 日韩av在线免费看| 国产欧美精品在线播放| 国产成人精品电影久久久| 国产精品自在线| 日韩精品在线视频| 欧美日韩午夜激情| 一本大道久久加勒比香蕉| 久久成人精品电影| 亚洲最大av网站| 美女啪啪无遮挡免费久久网站| 久久久久国色av免费观看性色| 亚洲国产成人一区| 亚洲老头同性xxxxx| 美女av一区二区三区| 亚洲人成亚洲人成在线观看| 97久久精品人搡人人玩| 亚洲精品视频免费| 午夜精品久久久久久99热| 青青久久av北条麻妃黑人| 国产伦精品一区二区三区精品视频| 久久这里只有精品视频首页| 国内成人精品一区| 欧美日韩一区二区在线| 日韩福利视频在线观看| 久久精品精品电影网| 日韩精品中文字| 欧美成人sm免费视频| 国产精品福利在线观看| 国产91对白在线播放| 成人免费网站在线| 亚洲精品一区二区三区不| 日韩电影免费在线观看| 亚洲午夜未满十八勿入免费观看全集| 国产精品三级在线| 欧美成人精品一区二区三区| 精品调教chinesegay| 欧美电影免费观看高清完整| 亚洲精品视频在线播放| 欧美日韩在线免费观看| 久久99久久99精品中文字幕| 青青草99啪国产免费| 国产精品久久久久久亚洲影视| 黑人巨大精品欧美一区二区免费| 91亚洲精品一区| 亚洲欧美国产精品久久久久久久| 日韩在线播放一区| 国产成人在线一区二区| 亚洲精品在线观看www| 欧美综合激情网| 国产亚洲精品久久久久久777| 97超级碰碰人国产在线观看| 97在线视频观看| 国产精品视频专区| 国产精品成人一区二区三区吃奶| 78色国产精品| 国产91精品不卡视频| 热久久免费视频精品| 欧美极品少妇xxxxⅹ裸体艺术| 最近日韩中文字幕中文| 欧美成人精品激情在线观看| 欧洲成人免费aa| 成人h视频在线观看播放| 亚洲在线一区二区| 欧美精品videosex极品1| 亚洲无线码在线一区观看| 51久久精品夜色国产麻豆| 中国人与牲禽动交精品| 欧美成人h版在线观看| 久久精品99久久久久久久久| 亚洲一二三在线| 国内精品久久久久久久久| 91国产精品电影| 国产精品999999|