Android <-> J2ME 蓝牙
Posted
技术标签:
【中文标题】Android <-> J2ME 蓝牙【英文标题】:Android <-> J2ME Bluetooth 【发布时间】:2010-12-16 13:50:14 【问题描述】:我想将支持蓝牙 (jsr082) 的通用 midp2 j2me 设备连接到 android 设备,运行我正在编写的类似自定义应用程序。 Android 设备似乎只能“看到”附近的其他 Android 蓝牙设备?
这可能吗?
【问题讨论】:
您成功完成任务了吗?我有同样的问题 抱歉耽搁了费尔南多 - 下面的理查德是我们团队的蓝牙专家,他设法让这一切工作得很好,见下文。 是的,我达到了相同的解决方案 【参考方案1】:我最近不得不这样做。我使用 api 8 所以只有
BluetoothAdapter.listenUsingRfcommWithServiceRecord(String,UUID);
方法正式可用。
由于 Android 不允许永久可见,我使用了我的应用程序保存的设备列表。
这是我的代码的简化,它将 Android 设置为服务器,使用侦听套接字并将 j2me 手机(我使用诺基亚 N95)作为客户端来创建 RFCOMM 连接。
这里是 Android 的东西:
int bytes = 0, offset = 0;
byte[] buffer;
BluetoothServerSocket btServerSocket = btAdapter.listenUsingRfcommWithServiceRecord("serv",myUUID);
BluetoothSocket btSocket = btServerSocket.accept();
OutputStream out = btSocket.getOutputStream();
InputStream in = btSocket.getInputStream();
bytes = in.read();
buffer = new byte[bytes];
out.write(0);
out.flush();
while (true)
bytes = in.read(buffer, offset, buffer.length - offset);
offset += bytes;
if (bytes == -1 || offset >= buffer.length)
Log.d("MyBT", "message: " + new String(buffer));
break;
out.close();
in.close();
btSocket.close();
btServerSocket.close();
这里是 J2ME 的东西:
class ARemoteDevice extends javax.bluetooth.RemoteDevice
public ARemoteDevice(String btaddr)
super(btaddr);
RemoteDevice targetDevice = new ARemoteDevice("00FF00FF00FF");
String message = "Hello my dear android device";
UUID[] uuidSet = new UUID("yourUUIDHERE",false);
Vector URLS = new Vector();
int ENCRYPTMODE = ServiceRecord.AUTHENTICATE_ENCRYPT;
final Object serviceSearchCompletedEvent = new Object();
DiscoveryListener listener = new DiscoveryListener()
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
public void inquiryCompleted(int discType)
public void servicesDiscovered(int transID, ServiceRecord[] servRecord)
for (int i = 0; i < servRecord.length; i++)
String connectionURL = servRecord[i].getConnectionURL(ENCRYPTMODE, false);
if (connectionURL != null)
URLS.addElement(connectionURL);
public void serviceSearchCompleted(int transID, int respCode)
synchronized (serviceSearchCompletedEvent)
serviceSearchCompletedEvent.notifyAll();
;
synchronized (serviceSearchCompletedEvent)
discAgent.searchServices(null, uuidSet, targetDevice, listener);
serviceSearchCompletedEvent.wait();
if (URLS.isEmpty())
System.out.println("no connectionurl found");
return;
try
for (int i = 0; i < URLS.size(); ++i)
System.out.println("Trying: " + (String) URLS.elementAt(i));
try
sc = (StreamConnection) Connector.open((String) URLS.elementAt(i));
in = sc.openInputStream();
out = sc.openOutputStream();
out.write(length);
out.flush();
in.read();
try
Thread.sleep(50);
catch (Exception e)
e.printStackTrace();
break;
catch (Exception e)
sc = null;
System.out.println("Failed BT COnn");
// TODO: handle case if all URLS fail
int bytesSent = 0;
int bytesToSend = 0;
int length=message.length();
int MTU=256;//or whatever..?
while (true)
if ((length - bytesSent) > MTU)
bytesToSend = MTU;
else
bytesToSend = length - bytesSent;
out.write(message.getBytes(), bytesSent, bytesToSend);
out.flush();
bytesSent += bytesToSend;
if (bytesSent >= length)
Thread.sleep(200);
break;
if (in != null)
in.close();
in = null;
if (out != null)
out.close();
out = null;
if (sc != null)
sc.close();
sc = null;
这让我的 android 设备接受从 j2me 发送的消息。我从我的代码中复制了重要部分,所以我不确定它是否一切正常,因为我没有尝试过内联执行它,因为我在这里展示它,但你应该能够填写我在复制粘贴时犯的任何错误。
祝你好运!
【讨论】:
这个解决方案不是只适用于连接到 droid 服务器的 j2me 客户端吗?问题是关于看到 j2me 设备的机器人设备 - @Richard Brough 上面的回答确实如此。 你说得对,这仅适用于 j2me -> android 服务器。在我自己的“寻求”让两个方向都工作并假设两个方向“”被寻求的情况下阅读标题,我一定误读了关于只想看到 j2me 设备的部分。由于我在网上找到的信息很少,我认为这里适合发布我自己的发现。如果它分散了主题,请告诉我。【参考方案2】:是的,有可能,您需要使用反射来访问几个方法(不是documented)以获得与 j2me 相同的行为。
createRfcommSocket(int channel)
在android.bluetooth.BluetoothDevice
喜欢
Class cls = Class.forName("android.bluetooth.BluetoothDevice");
java.lang.reflect.Method meth = cls.getMethod("createRfcommSocket", new Class[] Integer.TYPE);
BluetoothSocket iBluetoothSocket = (BluetoothSocket) meth.invoke(theBTDevice,new Object[] new Integer(channel));
和
// getUuids() also in android.bluetooth.BluetoothDevice
// i.e.
Class cls = Class.forName("android.bluetooth.BluetoothDevice");
java.lang.reflect.Method meth = cls.getMethod("getUuids", new Class[0]);
ParcelUuid[] uuidlist = (ParcelUuid[]) meth.invoke(theBTDevice);
可以在here找到一些使用信息:
这些方法在早期版本的 android 中可用(我认为是从 2.0 开始),但它们是私有的,因此需要反射(也许它们未经测试因此被隐藏)。
【讨论】:
以上是关于Android <-> J2ME 蓝牙的主要内容,如果未能解决你的问题,请参考以下文章
J2ME,InputStream 在通过蓝牙接收 40K 数据后挂断
如何在 android 和 PC 或其他 android 设备中使用蓝牙传输文件