科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道J2ME蓝牙实战入门

J2ME蓝牙实战入门

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

目前,很多手机已经具备了蓝牙功能。虽然MIDP2.0没有包括蓝牙API,但是JCP定义了JSR82, Java APIs for Bluetooth Wireless Technology (JABWT).这是一个可选API,很多支持MIDP2.0的手机已经实现了,比如Nokia 6600, Nokia 6670,Nokia7610等等。

作者:中国IT实验室 来源:中国IT实验室 2007年9月22日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共2页)





ServerBox.java



import 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 {
           showInfo("初始化失败,退出");
           return;

       }

       // 生成服务端服务线程对象
       processor = new ClientProcessor();

       // ok, start accepting connections then
       while (!isClosed) {
           StreamConnection conn = null;

           try {
               conn = notifier.acceptAndOpen();
           } catch (IOException e) {
               // wrong client or interrupted - continue anyway
               continue;
           }
           processor.addConnection(conn);
       }

   }

   public void publish() {
       isClosed = false;
       this.setString(null);
       new Thread(this).start();

   }

   public void cancelService() {
       isClosed = true;
       showInfo("服务终止");
       this.removeCommand(com_cancel);
       this.addCommand(com_pub);
   }

   /*
    * (non-Javadoc)
    *  
    * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command,
    *      javax.microedition.lcdui.Displayable)
    */
   public void commandAction(Command arg0, Displayable arg1) {
       if (arg0 == com_pub) {
           //发布service
           publish();
       } else if (arg0 == com_cancel) {
           cancelService();
       } else {
           cancelService();
           midlet.showMainMenu();
       }

   }
   
   /**
    * 内部类,服务端服务线程。
    * @author Jagie
    *
    * TODO To change the template for this generated type comment go to
    * Window - Preferences - Java - Code style - Code Templates
    */
   private class ClientProcessor implements Runnable {
       private Thread processorThread;

       private Vector queue = new Vector();

       private boolean isOk = true;

       ClientProcessor() {
           processorThread = new Thread(this);
           processorThread.start();
       }

       public void run() {
           while (!isClosed) {

               synchronized (this) {
                   if (queue.size() == 0) {
                       try {
                           //阻塞,直到有新客户连接
                           wait();
                       } catch (InterruptedException e) {

                       }
                   }
               }
               
               //处理连接队列

               StreamConnection conn;

               synchronized (this) {

                   if (isClosed) {
                       return;
                   }
                   conn = (StreamConnection) queue.firstElement();
                   queue.removeElementAt(0);
                   processConnection(conn);
               }
           }
       }
       
       /**
        * 往连接队列添加新连接,同时唤醒处理线程
        * @param conn
        */

       void addConnection(StreamConnection conn) {
           synchronized (this) {
               queue.addElement(conn);
               notify();
           }
       }

   }

   /**
    * 从StreamConnection读取输入
    * @param conn
    * @return
    */
   private String readInputString(StreamConnection conn) {
       String inputString = null;

       try {

           DataInputStream dis = conn.openDataInputStream();
           inputString = dis.readUTF();
           dis.close();
       } catch (Exception e) {
           e.printStackTrace();
       }
       return inputString;
   }
   
   /**
    * debug
    * @param s
    */

   private void showInfo(String s) {
       StringBuffer sb = new StringBuffer(this.getString());
       if (sb.length() > 0) {
           sb.append("\n");
       }

       sb.append(s);
       this.setString(sb.toString());

   }
   

   /**
    * 处理客户端连接
    * @param conn
    */    
   private void processConnection(StreamConnection conn) {

       // 读取输入
       String inputString = readInputString(conn);
       //生成响应
       String outputString = inputString.toUpperCase();
       //输出响应
       sendOutputData(outputString, conn);

       try {
           conn.close();
       } catch (IOException e) {
       } // ignore
       showInfo("客户端输入:" + inputString + ",已成功响应!");
   }
   
   /**
    * 输出响应
    * @param outputData
    * @param conn
    */

   private void sendOutputData(String outputData, StreamConnection conn) {

       try {
           DataOutputStream dos = conn.openDataOutputStream();
           dos.writeUTF(outputData);
           dos.close();
       } catch (IOException e) {
       }

   }
}



  小结

  本文给出了一个简单的蓝牙服务的例子。旨在帮助开发者快速掌握JSR82.如果该文能对你有所启发,那就很好了。


  参考资料

1. http://developers.sun.com/techtopics/mobility/apis/articles/bluetoothintro/
 JSR82 API介绍(英文)
2. http://www.j2medev.com/Article/ShowArticle.asp?ArticleID=249
 JSR82 API 介绍(中文)
3. http://www.jcp.org/en/jsr/detail?id=82
 JSR82 Specification.
4.WTK22, BluetoothDemo 项目

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章