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 蓝牙的主要内容,如果未能解决你的问题,请参考以下文章

PC 无法发现 J2ME 蓝牙服务

使用 J2ME 读取蓝牙 RSSI 值

J2ME,InputStream 在通过蓝牙接收 40K 数据后挂断

如何在 android 和 PC 或其他 android 设备中使用蓝牙传输文件

J2ME蓝牙OBEX如何实现ACTION(移动/重命名,设置权限)操作?

手机作为蓝牙耳机