java - 具有特定 UUID 的所有服务的蓝牙发现

标签 java android sockets bluetooth

Android 应用程序能否获取远程设备上 SDP 注册到特定 UUID 的可用套接字列表?我可以看到如何连接到具有给定 UUID 的单个套接字,但我找不到迭代共享该 UUID 的所有套接字的方法。

我知道我的代码很糟糕。我知道我不应该在 Activity 中执行阻塞操作,并且这里的所有内容都完全是黑客行为。我只是想在正确构建此架构之前运行概念验证。

也就是说,这是我的代码。我采取了一种行不通的方法。

package {intentionally removed};

import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
import java.util.UUID;

import android.os.Bundle;
import android.app.Activity;
import android.bluetooth.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {

    private static final int REQUEST_ENABLE_BT = 1;
    private String MY_TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            // Device does not support Bluetooth
        }
        if (!mBluetoothAdapter.isEnabled()) {
            //Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            //startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            Toast error = Toast.makeText(getApplicationContext(), "Enable BT and try again", Toast.LENGTH_LONG);
            error.show();
            Log.e(MY_TAG, "BT not enabled. Quitting.");
        }

        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        Log.i(MY_TAG, "Found " + pairedDevices.size() + " bonded devices");
        // If there are paired devices
        if (pairedDevices.size() > 0) {

            // Loop through paired devices
            for (BluetoothDevice device : pairedDevices) {
                int i = 1;
                while (true) {
                    Log.i(MY_TAG, "Device " + device.getAddress() + " with name " + device.getName());
                    //Repeatedly try to connect to the SDP UUID; move to the next device when this fails.
                    BluetoothSocket s = null;
                    try {
                        s = device.createRfcommSocketToServiceRecord(UUID.fromString("{intentionally removed}"));
                        Thread.sleep(1000);
                        try{
                            s.connect();
                        }
                        catch (Exception e) {
                            Log.i(MY_TAG, "could not connect to socket.");
                            break;
                        }
                        Log.i(MY_TAG, "Connected to a socket! Whee! " + i + " found.");
                        InputStream is = s.getInputStream();
                        Log.i(MY_TAG, "got the stream");
                        while (true) {
                            Log.i(MY_TAG, "began read loop");
                            int j = -1;
                            try {
                                j = is.read();
                            }
                            catch (Exception e)
                            {
                                //RESUME NEXT...mwahahaha
                            }
                            if (j == -1) {
                                Log.i(MY_TAG, "ran out of ibytes");
                                break;
                            }
                            Log.i(MY_TAG, "ibyte: " + is.read());
                        }
                        i++;
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        Log.e(MY_TAG, "Unable to connect.", e);
                        break;
                    }
                }
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);

    }

}

(我提取的 UUID 是因为我不想透露自己在做什么。这是别人的。)

我知道另一端有多个套接字服务于相同的 UUID。我刚刚给出的代码尝试连接到每个套接字,强制 createRfcommSocketToServiceRecord 获取另一个套接字。但是,我无法连接其中一个套接字...使我无法迭代到下一个套接字(因为 createRfcommSocketToServiceRecord 仅在下一次迭代中返回相同的套接字)。

有没有更明智的方法来做到这一点?我想要一个可以调用的好函数,它列出了我可以使用给定 UUID 连接的所有套接字。这样的事情存在吗?

谢谢

最佳答案

是的,它存在。它是如何工作的:

  1. 您创建一个类,即包含已知 UUID 的 GattAttributes。
  2. 发现您的服务类别中的服务和特征
  3. 循环浏览您的 Activity 中发现的服务和特征(您可以选择填充列表以供用户查看)

这会在列表中为您提供可用的服务和特征。

Look at this Google Bluetooth LE example to see the code.

该示例允许用户选择特征,但如果您想连接到您事先知道的具体特征(就像我所做的那样):

  • 在您的 Service 类中,在 onServicesDiscovered 中放置:

    BluetoothGattCharacteristic characteristic = gatt.getService(SERVICE_UUID).getCharacteristic(CHARACTERISTIC_UUID);
    
  • 如果您还想添加通知并利用 onCharacteristicChanged(),请使用以下代码:
// Enable notifications for this characteristic locally
gatt.setCharacteristicNotification(characteristic, true);

// Write on the config descriptor to be notified when the value changes
 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
 descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
 gatt.writeDescriptor(descriptor);
需要定义

CLIENT_CHARACTERISTIC_CONFIG,请参阅上面引用的 Google 代码。

关于java - 具有特定 UUID 的所有服务的蓝牙发现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22746196/

相关文章:

java - 如何更改RecyclerView中每个项目的值

java - 在 JPA 中使用继承来实现数据类型目的

java - Android内部类中EditText转int

java - Java中的多线程服务器程序

C++ HTTP Winsock : "Banned URL" at school, 即使是允许的网站

java - 如何在 Intellij 中为 Java 格式化类似 C# 样式的代码?

java - 在 jsp 中使用 Scriptlet

android - PhoneGap 应用程序需要互联网连接吗?

java - 在 Android 上显示保存的接近警报?

php - YouTube API-直接上传-413请求实体太大