目前,很多手机已经具备了蓝牙功能。虽然midp2.0没有包括蓝牙api,但是jcp定义了jsr82, java apis for bluetooth wireless technology (jabwt).这是一个可选api,很多支持midp2.0的手机已经实现了,比如nokia 6600, nokia 6670,nokia7610等等。对于一个开发者来说,如果目标平台支持jsr82的话,在制作联网对战类型游戏或者应用的时候,蓝牙是一个相当不错的选择。
本文给出了一个最简单的蓝牙应用的j2me程序,用以帮助开发者快速的掌握jsr82。该程序分别在2台蓝牙设备上安装后,一台设备作为服务端先运行,一台设备作为客户端后运行。在服务端上我们发布了一个服务,该服务的功能是把客户端发过来的字符串转变为大写字符串。客户端起动并搜索到服务端的服务后,我们就可以从客户端的输入框里输入任意的字符串,发送到服务端去,同时观察服务端的反馈结果。
实例代码
该程序包括3个java文件。一个是midlet,另外2个为服务端gui和客户端gui。该程序已经在wtk22模拟器和nokia 6600,nokia 6670两款手机上测试通过。
stupidbtmidlet.java
import 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.java
import 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;i<records.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];
闽公网安备 35060202000074号