蓝牙:onReceive()和registerReceiver()从未调用过这些方法

时间:2016-12-26 17:49:25

标签: android android-studio android-bluetooth

我正在为蓝牙客户端开发应用程序,并且在此应用程序内部有一个listview,它将列出所有连接的设备。首先,应用程序将检查蓝牙的可用性,然后尝试连接到另一台设备(服务器),除此之外,我初始化了清单文件中的intent过滤器。 以下是我的代码:

public class MainActivity extends AppCompatActivity {
    ArrayAdapter<String> listAdapter;
    ListView listView;
    BluetoothAdapter mBluetoothAdapter;
    Set<BluetoothDevice> bondedDevices;
    private BluetoothSocket socket;
    Intent discoverableIntent;
    private BluetoothDevice remoteDevice;
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction().equalsIgnoreCase("android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED"))
            {
                Log.i("Connect", "Connecting.>>>>");
                unregisterReceiver(this);
                remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String Temp1 = remoteDevice.getName();
                String Temp2 = remoteDevice.getAddress();
                listAdapter.add(Temp1 + Temp2);
                listView.setAdapter(listAdapter);
                new Thread(reader).start();
            }
        }
    };

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

        init();
        IntentFilter intentFilter = new IntentFilter("com.example.jackpowell.bluetoothclient.ACTION_ACL_CONNECTED");
        registerReceiver(mReceiver,intentFilter);

        startDiscovery();

    }

    private void startDiscovery() {
        mBluetoothAdapter.cancelDiscovery();
        mBluetoothAdapter.startDiscovery();
    }

    public void init() {
        listView = (ListView)findViewById(R.id.listView);
        listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            Toast.makeText(MainActivity.this, "Bluetooth is not supported in this device", Toast.LENGTH_SHORT).show();
            finish();
        } else {
            if (!mBluetoothAdapter.isEnabled()) {
                turnOnBluetooth();
            }
        }

        bondedDevices = mBluetoothAdapter.getBondedDevices();

        discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        startActivity(discoverableIntent);

    }

    private Runnable reader = new Runnable() {
        @Override
        public void run() {
            try {
                Log.i("Connect","Connecting...........");
                android.util.Log.e("TrackingFlow", "Found: " + remoteDevice.getName());
                UUID uuid = UUID.fromString("a60f35f0-b93a-11de-8a19-03002011c456");
                socket = remoteDevice.createRfcommSocketToServiceRecord(uuid);
                socket.connect();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    private void turnOnBluetooth() {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, 1);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_CANCELED) {
            Toast.makeText(getApplicationContext(), "Bluetooth must be enabled to continue", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);
    }



}

我的清单:     

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    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>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />


<receiver android:name="bluetoothclient">
    <intent-filter>
        <action android:name="android.bluetooth.BluetoothDevice.ACTION_ACL_CONNECTED" />
    </intent-filter>
</receiver>

现在的问题是onReceive()和registerReceiver()这些方法从未被调用过,或者它已经被调用了,我只是不明白。如果调用了这些方法,则log cat应显示log命令。为什么从未调用过这些方法?提前谢谢你!

1 个答案:

答案 0 :(得分:1)

操作名称为"android.bluetooth.device.action.ACL_CONNECTED"(在清单中使用)或BluetoothDevice.ACTION_ACL_CONNECTED(在代码中使用,用于意图过滤器)。代码中的动作名称似乎有误。

注意,要在清单中注册receiver,接收者名称应该是基于BroadcastReceiver的公共类,不确定上面代码中的“bluetoothclient”是什么意思(你没有显示接收者码)。

通常你不需要活动中的清单接收器和意图过滤器接收器,一个可能就足够了。主要区别在于清单接收器可以独立于活动生命周期,即使活动未运行也可以接收。

尝试同时收听ACTION_FOUND(在启动发现你接收BluetoothDevice.ACTION_FOUND之后每documentation个)并尝试将其缩小为最小的示例。您还需要检查startDiscovery()的结果,该结果可以在失败时返回false。

以下是发现设备部分的略微修改过的示例:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    // Register for broadcasts 
    IntentFilter filter = new IntentFilter();
    filter.addAction(BluetoothDevice.ACTION_FOUND);
    filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
    filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
    filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
    registerReceiver(mReceiver, filter);
    ...
    if(!mBluetoothAdapter.startDiscovery()){
            Log.e("Bluetooth", "discovery error");
    }
}

// Create a BroadcastReceiver for bluetooth actions
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Log.i("Bluetooth", "got action " + action);
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // Discovery has found a device. Get the BluetoothDevice
            // object and its info from the Intent.
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            String deviceName = device.getName();
            String deviceHardwareAddress = device.getAddress(); // MAC address
            Log.i("Bluetooth", "got device " + deviceName );
        }
    }
};

@Override
protected void onDestroy() {
    super.onDestroy();
    ...

    // Don't forget to unregister the ACTION_FOUND receiver.
    unregisterReceiver(mReceiver);
}

另请注意,根据此question/answer,在某些设备上,发现并不总是按预期工作,并且需要解决方法。

顺便问一下,您是否检查了logcat是否存在其他错误,例如拒绝权限等?您可以尝试启用位置并添加位置权限。

以下是显示所有设备的工作示例:

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testbluetooth"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="21" />

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

MainActivity.java

package com.example.testbluetooth;

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.util.Log;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.TextView;

public class MainActivity extends Activity {

    TextView textView;
    StringBuilder text = new StringBuilder();

    private void addLine(String line)
    {
        Log.i(getClass().getSimpleName(), line);
        text.append("[bluetooth] ").append(line).append('\n');
        if(textView!=null)
            textView.setText(text);     
    }

    BluetoothAdapter mBluetoothAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        FrameLayout content = new FrameLayout(this);
        textView = new TextView(this);
        content.addView(textView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        addLine("onCreate");
        setContentView(content);

        // Register for broadcasts 
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
        registerReceiver(mReceiver, filter);

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        for(BluetoothDevice pairedDevice : mBluetoothAdapter.getBondedDevices())
        {
            addLine("got paired device " + pairedDevice.getName());
        }

        if(!mBluetoothAdapter.startDiscovery()){
            addLine("ERROR: discovery error");
        }
        else
        {
            addLine("starting discovery");          
        }

    }

 // Create a BroadcastReceiver for bluetooth actions
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            addLine("got action " + action);
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Discovery has found a device. Get the BluetoothDevice
                // object and its info from the Intent.
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String deviceName = device.getName();
                //String deviceHardwareAddress = device.getAddress(); // MAC address
                addLine("got device " + deviceName );
            }
        }
    };    
}