蓝牙ACTION_FOUND broadcastReceiver无法正常工作

时间:2016-07-21 19:39:41

标签: android bluetooth

我试图计算蓝牙RSSI并找到了一些示例,但 broadcastReceiver 无效。代码是这样的:

select   FT_TIME = convert(time, 
            convert(varchar(2), T1.FM_TIME / 10000) + 
            ':' +
                    convert(varchar(2), (T1.FM_TIME % 10000) / 100) + 
            ':' +
            convert(varchar(2), T1.FM_TIME % 100)           
        )  
from     MyTable T1

通过此注册:

private final BroadcastReceiver receiver = new BroadcastReceiver(){

    @Override
    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();
        if(BluetoothDevice.ACTION_FOUND.equals(action)) {
            int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
            String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
            TextView rssi_msg = (TextView) findViewById(R.id.textView1);
            rssi_msg.setText(rssi_msg.getText() + name + " => " + rssi + "dBm\n");
        }
    }
};

单击按钮时,BTAdapter.startDiscovery();工作中。 但是在textview中没有任何改变。

你能为我提一些建议吗?

再次编辑: 我改变了我的代码,我将展示我的整个代码。

registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));

接收器类是

public class Blutooth extends Activity {

private BluetoothAdapter BTAdapter = BluetoothAdapter.getDefaultAdapter();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_blutooth);

    Button boton = (Button) findViewById(R.id.button1);
    boton.setOnClickListener(new OnClickListener(){
        public void onClick(View v) {
            BTAdapter.startDiscovery();
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.blutooth, menu);
    return true;
  }
}

我尝试Toast public class TestReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String name = intent.getAction(); String device = intent.getStringExtra(BluetoothDevice.EXTRA_NAME); String rssi_msg = Integer.toString(intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE)); Toast.makeText(context, name, Toast.LENGTH_SHORT).show(); } } ,但什么也没发生。 我认为intent.getAction();不是广播。

再次编辑: 我使用的是Android 6.0版本。 而我的全部表现是:

BluetoothDevice.ACTION_FOUND

我听说超过6.0版本需要使用<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.blutooth" android:versionCode="1" android:versionName="1.0" > <uses-feature android:name="android.hardware.bluetooth" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".Blutooth" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".TestReceiver"> <intent-filter> <action android:name="BluetoothDevice.ACTION_FOUND"> </action></intent-filter> </receiver> </application> </manifest> 的额外权限。 所以,我添加了ACTION_FOUNDACCESS_FINE_LOCATION。 我在我的活动中添加了ACCESS_COARSE_LOCATION代码。 filter.addAction(BluetoothDevice.ACTION_NAME_CHANGED);工作正常,我可以ACTION_NAME_CHANGED。 但BluetoothDevice.EXTRA_NAME无效。 它打印默认值-32768。 仍然BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE无效。

4 个答案:

答案 0 :(得分:6)

我终于找到了答案。 Android 6.0需要额外的权限,但只是向Manifest添加使用权限不起作用。 您必须检查用户的权限。 我写这样的代码:

int permissionCheck = ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.ACCESS_COARSE_LOCATION);

        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!bluetoothAdapter.isEnabled())
          bluetoothAdapter.enable();
        leScanner = bluetoothAdapter.getBluetoothLeScanner();

        Button boton = (Button) findViewById(R.id.button1);
        boton.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {
                leScanner.startScan(scanCallback);
            }
        });

此代码显示您的权限弹出。 谢谢你的答案。

答案 1 :(得分:3)

您需要ACCESS_COARSE_LOCATION权限的强制请求:


if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE);
}

BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
...

位于https://www.sitepoint.com/requesting-runtime-permissions-in-android-m-and-n

答案 2 :(得分:2)

我通过物理打开设备上的位置服务或您可以通过编程来实现这一点。

只需在运行您的应用之前打开它,您就可以看到设备列表。

如果位置服务关闭,蓝牙 API 将无法工作。

答案 3 :(得分:0)

感谢您的帖子,一旦我请求适当的权限,它就可以正常工作。

科特林

我创建了一个ID为button的按钮;单击它时,您应该在Logcat

中看到设备列表

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.picture_it" >
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.kt

class MainActivity : AppCompatActivity() {
    companion object {
        const val REQUEST_ENABLE_BT = 42
//        val REQUEST_QUERY_DEVICES = 142
    }

    private var bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (bluetoothAdapter == null) {
            // Device doesn't support Bluetooth
            Toast.makeText(applicationContext, "Device doesn't support Bluetooth", Toast.LENGTH_SHORT).show()
        } else if (bluetoothAdapter?.isEnabled == false) {
            val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
        }

        val permission1 = ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH)
        val permission2 = ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN)
        val permission3 = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
        val permission4 = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        if (permission1 != PackageManager.PERMISSION_GRANTED
            || permission2 != PackageManager.PERMISSION_GRANTED
            || permission3 != PackageManager.PERMISSION_GRANTED
            || permission4 != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                arrayOf(
                    Manifest.permission.BLUETOOTH,
                    Manifest.permission.BLUETOOTH_ADMIN,
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION),
                642)
        } else {
            Log.d("DISCOVERING-PERMISSIONS", "Permissions Granted")
        }

        val button = findViewById<Button>(R.id.button)
            button.setOnClickListener {
                if (bluetoothAdapter?.isDiscovering == true) {
                    bluetoothAdapter?.cancelDiscovery()
                }
                var filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
                this.registerReceiver(receiver, filter)
                filter = IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED)
                this.registerReceiver(receiver, filter)
                filter = IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
                this.registerReceiver(receiver, filter)
                bluetoothAdapter?.startDiscovery()
        }
    }

    // Create a BroadcastReceiver for ACTION_FOUND.
    private val receiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                BluetoothDevice.ACTION_FOUND -> {
                    // Discovery has found a device. Get the BluetoothDevice
                    // object and its info from the Intent.
                    val device: BluetoothDevice =
                        intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                    val deviceName = device.name
                    val deviceHardwareAddress = device.address // MAC address
                    var msg = ""
                    if (deviceName.isNullOrBlank())
                    {
                        msg = deviceHardwareAddress
                    } else {
                        msg = "$deviceName $deviceHardwareAddress"
                    }
                    Log.d("DISCOVERING-DEVICE", msg)
                }
                BluetoothAdapter.ACTION_DISCOVERY_STARTED -> {
                    Log.d("DISCOVERING-STARTED", "isDiscovering")
                }
                BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
                    Log.d("DISCOVERING-FINISHED", "FinishedDiscovering")
                }
            }
        }
    }

    override fun onDestroy() {
        unregisterReceiver(receiver)
        super.onDestroy()
    }
}