Android中的蓝牙设备发现——startDiscovery()

19

目标:构建一个Android应用程序,可以发现范围内的蓝牙设备名称和地址,并将其值提交到Web服务。蓝牙设备之前未与主机设备绑定,我只是想在走动时轮询所有设备。

已完成:

  1. 详细阅读了文档。
  2. 实现了主机设备BT适配器的本地实例。
  3. 实现了通知以启用BT(如果未启用)。
  4. 注册了Broadcast Receiver和Intents来解析startDiscovery()返回的ACTION_FOUNDs
  5. 在清单中注册了BLUETOOTHBLUETOOTH_ADMIN权限。

一切正常(经过增量控制台日志测试),直到startDiscovery()函数。


挫败感:

  • startDiscovery() -- 我怀疑我没有正确传递上下文。该方法需要放置在哪个上下文中才能正常工作?

如果您已经能够使此方法正常工作,我会非常感激您的指导。

更新 - 这里是引起我困扰的代码的简化版本; 这个简化重演了我的错误。这段代码可以运行,没有cat.log错误或其他错误,但它只是没有输出任何内容。

package aqu.bttest;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.Toast;

public class BT2Activity extends Activity {

private BluetoothAdapter mBTA;
private SingBroadcastReceiver mReceiver;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

  //register local BT adapter
    mBTA = BluetoothAdapter.getDefaultAdapter();
    //check to see if there is BT on the Android device at all
    if (mBTA == null){
        int duration = Toast.LENGTH_SHORT;
        Toast.makeText(this, "No Bluetooth on this handset", duration).show();
    }
    //let's make the user enable BT if it isn't already
    if (!mBTA.isEnabled()){
        Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBT, 0xDEADBEEF);
    }
    //cancel any prior BT device discovery
    if (mBTA.isDiscovering()){
        mBTA.cancelDiscovery();
    }
    //re-start discovery
    mBTA.startDiscovery();

    //let's make a broadcast receiver to register our things
    mReceiver = new SingBroadcastReceiver();
    IntentFilter ifilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    this.registerReceiver(mReceiver, ifilter);
}

private class SingBroadcastReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction(); //may need to chain this to a recognizing function
        if (BluetoothDevice.ACTION_FOUND.equals(action)){
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // Add the name and address to an array adapter to show in a Toast
            String derp = device.getName() + " - " + device.getAddress();
            Toast.makeText(context, derp, Toast.LENGTH_LONG);
        }
    }
}

}


知道你遇到的错误会有所帮助……或者至少了解是什么让你相信 startDiscovery() 的功能存在问题。 - Alex Lockwood
1个回答

26
这个方法需要放在什么上下文中才能正常工作。
简单来说,当你想让你的应用发现本地蓝牙设备时,你应该使用startDiscovery() ...例如,如果你想实现一个ListActivity,它会扫描并动态添加附近的蓝牙设备到ListView(参见DeviceListActivity)。
你使用startDiscovery()方法应该像这样:
  1. Define a class variable representing the local Bluetooth adapter.

    BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();
    
  2. Check to see if your device is already "discovering". If it is, then cancel discovery.

    if (mBtAdapter.isDiscovering()) {
        mBtAdapter.cancelDiscovery();
    }
    
  3. Immediately after checking (and possibly canceling) discovery-mode, start discovery by calling,

    mBtAdapter.startDiscovery();
    
  4. Be very careful in general about accidentally leaving your device in discovery-mode. Performing device discovery is a heavy procedure for the Bluetooth adapter and will consume a lot of its resources. For instance, you want to make sure you check/cancel discovery prior to attempting to make a connection. You most likely want to cancel discovery in your onDestroy method too.

如果这个帮助到你了,请告诉我...如果你仍然有困难,请在回答中更新您的logcat输出和/或任何错误消息,并且也许我可以再帮助您一些。


这个帮了很大的忙。而且,将结果传递给一个 ArrayAdapter 而不是一个 Toast 也绝对起到了帮助作用。 - Lemminkainen
有没有办法在后台服务中保持连续扫描而不使用定时器或任何系统级API? - CoDe
@Shubh 我不这么认为。设置此限制的原因是确保应用程序不会在后台持续扫描 Bluetooth 以进行滥用。 - Alex Lockwood
非常老旧...我正在尝试做同样的事情,但可能是什么错误?- http://stackoverflow.com/questions/41987424/java-lang-securityexception-while-context-registerreceiver-in-uiautomator-ins - Rilwan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接