J2ME蓝牙程序开发实战入门

苑智源天

苑智源天

2016-02-19 19:32

有了下面这个J2ME蓝牙程序开发实战入门教程,不懂J2ME蓝牙程序开发实战入门的也能装懂了,赶紧get起来装逼一下吧!
  概述 目前,很多手机已经具备了蓝牙功能。虽然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.javaimport javax.microedition.lcdui.Alert; import javax.microedition.lcdui.AlertType; import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.List; import javax.microedition.midlet.MIDlet; import javax.microedition.midlet.MIDletStateChangeException; /**  * @author Jagie  *   *  MIDlet  */ public class StupidBTMIDlet extends MIDlet implements CommandListener {     List list;     ServerBox sb;     ClientBox cb;     /*      * (non-Javadoc)      *       * @see javax.microedition.midlet.MIDlet#startApp()      */     protected void startApp() throws MIDletStateChangeException {         list = new List("傻瓜蓝牙入门", List.IMPLICIT);
           list.append("Client", null);         list.append("Server", null);         list.setCommandListener(this);         Display.getDisplay(this).setCurrent(list);     }          /**      * debug方法      * @param s 要显示的字串      */     public void showString(String s) {         Displayable dp = Display.getDisplay(this).getCurrent();         Alert al = new Alert(null, s, null, AlertType.INFO);         al.setTimeout(2000);         Display.getDisplay(this).setCurrent(al, dp);     }          /**      * 显示主菜单      *      */     public void showMainMenu() {         Display.getDisplay(this).setCurrent(list);     }          protected void pauseApp() {         // TODO Auto-generated method stub     }     public void commandAction(Command com, Displayable disp) {         if (com == List.SELECT_COMMAND) {             List list = (List) disp;             int index = list.getSelectedIndex();             if (index == 1) {                 if (sb == null) {                     sb = new ServerBox(this);
                   }                 sb.setString(null);                 Display.getDisplay(this).setCurrent(sb);             } else {                 //每次都生成新的客户端实例                 cb = null;                 System.gc();                 cb = new ClientBox(this);                 Display.getDisplay(this).setCurrent(cb);             }         }     }     protected void destroyApp(boolean arg0) throws MIDletStateChangeException {         // TODO Auto-generated method stub     } }   ClientBox.javaimport java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Vector; import javax.microedition.io.Connector; import javax.microedition.io.StreamConnection; import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; import javax.microedition.lcdui.Gauge; import javax.microedition.lcdui.StringItem; import javax.microedition.lcdui.TextField; //jsr082 API import javax.bluetooth.BluetoothStateException; import javax.bluetooth.DeviceClass; import javax.bluetooth.DiscoveryAgent; import javax.bluetooth.DiscoveryListener; import javax.bluetooth.LocalDevice; import javax.bluetooth.RemoteDevice; import javax.bluetooth.ServiceRecord;
   import javax.bluetooth.UUID; /**  * 客户端GUI  * @author Jagie  *  * TODO To change the template for this generated type comment go to  * Window - Preferences - Java - Code Style - Code Templates  */ public class ClientBox extends Form implements Runnable, CommandListener,         DiscoveryListener {          //字串输入框     TextField input = new TextField(null, "", 50, TextField.ANY);     //loger     StringItem result = new StringItem("结果:", "");     private DiscoveryAgent discoveryAgent;          private UUID[] uuidSet;     //响应服务的UUID     private static final UUID ECHO_SERVER_UUID = new UUID(             "F0E0D0C0B0A000908070605040302010", false);     //设备集合     Vector devices = new Vector();     //服务集合     Vector records = new Vector();          //服务搜索的事务id集合     int[] transIDs;     StupidBTMIDlet midlet;     public ClientBox(StupidBTMIDlet midlet) {         super("");         this.midlet=midlet;                  this.append(result);                  this.addCommand(new Command("取消",Command.CANCEL,1));         this.setCommandListener(this);                  new Thread(this).start();     }
            public void commandAction(Command arg0, Displayable arg1) {         if(arg0.getCommandType()==Command.CANCEL){             midlet.showMainMenu();         }else{             //匿名内部Thread,访问远程服务。             Thread fetchThread=new Thread(){                 public void run(){                     for(int i=0;irecords.size();i++){                         ServiceRecord sr=(ServiceRecord)records.elementAt(i);                         if(AccessService(sr)){                             //访问到一个可用的服务即可                             break;                         }                     }                 }             };             fetchThread.start();         }              }               private boolean  accessService(ServiceRecord sr){         boolean result=false;          try {             String url = sr.getConnectionURL(
                       ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);             StreamConnection    conn = (StreamConnection) Connector.open(url);                          DataOutputStream dos=conn.openDataOutputStream();             dos.writeUTF(input.getString());             dos.close();             DataInputStream dis=conn.openDataInputStream();             String echo=dis.readUTF();             dis.close();             showInfo("反馈结果是:"+echo);             result=true;                      } catch (IOException e) {                      }         return result;     }     public synchronized void run() {         //发现设备和服务的过程中,给用户以Gauge         Gauge g=new Gauge(null,false,Gauge.INDEFINITE,Gauge.CONTINUOUS_RUNNING);         this.append(g);         showInfo("蓝牙初始化...");         boolean isBTReady = false;         try {             LocalDevice localDevice = LocalDevice.getLocalDevice();             discoveryAgent = localDevice.getDiscoveryAgent();             isBTReady = true;         } catch (Exception e) {
               e.printStackTrace();         }         if (!isBTReady) {             showInfo("蓝牙不可用");             //删除Gauge             this.delete(1);             return;         }         uuidSet = new UUID[2];         //标志我们的响应服务的UUID集合         uuidSet[0] = new UUID(0x1101);         uuidSet[1] = ECHO_SERVER_UUID;                  try {             discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);         } catch (BluetoothStateException e) {         }         try {             //阻塞,由inquiryCompleted()回调方法唤醒             wait();         } catch (InterruptedException e1) {                          e1.printStackTrace();         }         showInfo("设备搜索完毕,共找到"+devices.size()+"个设备,开始搜索服务");         transIDs = new int[devices.size()];         for (int i = 0; i  devices.size(); i++) {             RemoteDevice rd = (RemoteDevice) devices.elementAt(i);             try {                 //记录每一次服务搜索的事务id                 transIDs[i] = discoveryAgent.searchServices(null, uuidSet,
                           rd, this);             } catch (BluetoothStateException e) {                 continue;             }         }                  try {             //阻塞,由serviceSearchCompleted()回调方法在所有设备都搜索完的情况下唤醒             wait();         } catch (InterruptedException e1) {             e1.printStackTrace();         }                  showInfo("服务搜索完毕,共找到"+records.size()+"个服务,预备发送请求");         if(records.size()0){             this.append(input);             this.addCommand(new Command("发送",Command.OK,0));         }                  //删除Gauge         this.delete(1);              }          /**      * debug      * @param s      */          private void showInfo(String s){         StringBuffer sb=new StringBuffer(result.getText());         if(sb.length()0){             sb.append("");         }         sb.append(s);         result.setText(sb.toString());     }
            /**      * 回调方法      */     public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {         if (devices.indexOf(btDevice) == -1) {             devices.addElement(btDevice);         }     }     /**      * 回调方法,唤醒初始化线程      */     public void inquiryCompleted(int discType) {         synchronized (this) {             notify();         }     }     /**      * 回调方法      */     public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {         for (int i = 0; i  servRecord.length; i++) {             records.addElement(servRecord[i]);         }     }          /**      * 回调方法,唤醒初始化线程      */     public void serviceSearchCompleted(int transID, int respCode) {                  for (int i = 0; i  transIDs.length; i++) {             if (transIDs[i] == transID) {                 transIDs[i] = -1;                 break;             }         }                  //假如所有的设备都已经搜索服务完毕,则唤醒初始化线程。
           boolean finished = true;         for (int i = 0; i  transIDs.length; i++) {             if (transIDs[i] != -1) {                 finished = false;                 break;             }         }         if (finished) {             synchronized (this) {                 notify();             }         }     } }   ServerBox.javaimport java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Vector; import javax.bluetooth.DiscoveryAgent; import javax.bluetooth.LocalDevice; import javax.bluetooth.ServiceRecord; import javax.bluetooth.UUID; import javax.microedition.io.Connector; import javax.microedition.io.StreamConnection; import javax.microedition.io.StreamConnectionNotifier; import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.TextBox; import javax.microedition.lcdui.TextField; /**  * 服务端GUI  * @author Jagie  *  * TODO To change the template for this generated type comment go to  * Window - Preferences - Java - Code Style - Code Templates  */ public class ServerBox extends TextBox implements Runnable, CommandListener {     Command com_pub = new Command("开启服务", Command.OK, 0);
       Command com_cancel = new Command("终止服务", Command.CANCEL, 0);     Command com_back = new Command("返回", Command.BACK, 1);     LocalDevice localDevice;     StreamConnectionNotifier notifier;     ServiceRecord record;     boolean isClosed;     ClientProcessor processor;     StupidBTMIDlet midlet;     //响应服务的uuid     private static final UUID ECHO_SERVER_UUID = new UUID(             "F0E0D0C0B0A000908070605040302010", false);     public ServerBox(StupidBTMIDlet midlet) {         super(null, "", 500, TextField.ANY);         this.midlet = midlet;         this.addCommand(com_pub);         this.addCommand(com_back);         this.setCommandListener(this);     }     public void run() {         boolean isBTReady = false;         try {             localDevice = LocalDevice.getLocalDevice();             if (!localDevice.setDiscoverable(DiscoveryAgent.GIAC)) {                 showInfo("无法设置设备发现模式");                 return;             }             // prepare a URL to create a notifier             StringBuffer url = new StringBuffer("btspp://");             // indicate this is a server
               url.append("localhost").append(':');             // add the UUID to identify this service             url.append(ECHO_SERVER_UUID.toString());             // add the name for our service             url.append(";name=Echo Server");             // request all of the client not to be authorized             // some devices fail on authorize=true             url.append(";authorize=false");             // create notifier now             notifier = (StreamConnectionNotifier) Connector                     .open(url.toString());             record = localDevice.getRecord(notifier);             // remember we've reached this point.             isBTReady = true;         } catch (Exception e) {             e.printStackTrace();                      }         // nothing to do if no bluetooth available         if (isBTReady) {             showInfo("初始化成功,等待连接");             this.removeCommand(com_pub);             this.addCommand(com_cancel);         } 
   else {
展开更多 50%)
分享

猜你喜欢

J2ME蓝牙程序开发实战入门

编程语言 网络编程
J2ME蓝牙程序开发实战入门

J2ME开发入门专题系列之一:J2ME概述

编程语言 网络编程
J2ME开发入门专题系列之一:J2ME概述

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

J2ME开发经验:J2ME应用程序内存优化三招

编程语言 网络编程
J2ME开发经验:J2ME应用程序内存优化三招

J2ME程序开发新手入门九大要点

编程语言 网络编程
J2ME程序开发新手入门九大要点

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

Eclipse开发J2ME程序之Hello World

编程语言 网络编程
Eclipse开发J2ME程序之Hello World

J2ME中使用Socket开发联网程序

编程语言 网络编程
J2ME中使用Socket开发联网程序

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

WPS演示2024轻松完成字体的替换

WPS演示2024轻松完成字体的替换

如何在delphi5中实现对word文档页眉的设置?

如何在delphi5中实现对word文档页眉的设置?
下拉加载更多内容 ↓