使用特定UUID的所有服务的蓝牙发现

时间:2014-03-30 15:58:12

标签: java android sockets bluetooth

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

我知道我的代码是垃圾。我知道我不应该在Activity中进行阻塞操作,而且这里的一切都是完全hacky。在我正确构建之前,我只是试图获得概念验证。

那就是说,这是我的代码。我采取了一种无效的方法。

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 个答案:

答案 0 :(得分:0)

是的,它存在。工作原理:

  1. 您创建了一个类,即包含已知UUID的GattAttributes。
  2. 发现服务类中的服务和特征
  3. 遍历您的活动中发现的服务和特征(可选地,您可以填充列表供用户查看)
  4. 这为您提供了列表中的可用服务和特征。

      

    请查看此Google Bluetooth LE example以查看代码。

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

    • 在您的Service类中,在onServicesDiscovered put:

      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代码。

相关问题