Bluetooth:onReceive()和registerReceiver()这些方法从未被调用 [英] Bluetooth:onReceive() and registerReceiver() these method never been called

查看:109
本文介绍了Bluetooth:onReceive()和registerReceiver()这些方法从未被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个用于蓝牙客户端的应用程序,该应用程序内部具有一个列表视图,该列表将列出所有已连接的设备.首先,应用程序将检查蓝牙的可用性,然后尝试连接到另一个设备(服务器),此外,我在清单文件中初始化了意图过滤器. 下面是我的代码:

I am developing an application for a Bluetooth client side, and inside this application has a listview that will list out all the connected devices. First, the application will check for the availability of the Bluetooth and then try to connect to another device(Server) , beside that, I initialised the intent filter in the manifest file. Below is my code :

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);
    }



}

我的清单:

my manifest:

<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命令.为什么从未调用这些方法?预先谢谢你!

The problem now is onReceive() and registerReceiver() these method never been called, or maybe it already called, I just dont get it. If these method were called, the log cat should be displaying the log command. Why are these method never been called? thank you in advance!

推荐答案

操作名称为"android.bluetooth.device.action.ACL_CONNECTED"(用于清单)或BluetoothDevice.ACTION_ACL_CONNECTED(用于代码,用于意图过滤器).您代码中的动作名称似乎不正确.

The action name is "android.bluetooth.device.action.ACL_CONNECTED" (to use in manifest) or BluetoothDevice.ACTION_ACL_CONNECTED (to use in code, for intent filter). Action names in your code seem wrong.

注意,要在清单接收方中注册接收方名称应该是基于 BroadcastReceiver 的公共类,不确定什么是上面的代码中的"bluetoothclient"含义(您未显示接收方代码).

Note, to register receiver in manifest the receiver name should be public class based on BroadcastReceiver, not sure what is the "bluetoothclient" meaning in the code above (you didn't show the receiver code).

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

Usually you don't need both manifest receiver and intent filter receiver in activity, one may be sufficient. The main difference is that manifest receiver can be independent from activity life cycle and receive even when activity is not running.

尝试也听ACTION_FOUND(根据startDiscovery之后的文档您将收到BluetoothDevice.ACTION_FOUND)和其他内容,并尝试将其简化为最小的示例.您还需要检查startDiscovery()的结果,该结果在失败时可以返回false.

Try to listen also for ACTION_FOUND (per documentation after startDiscovery you'll receive BluetoothDevice.ACTION_FOUND) and others and try to reduce into minimal example. You need also check result of startDiscovery() which can return false on failure.

这里是发现设备部分中的经过稍微修改的示例:

Here is slightly modified sample from Discovering devices section:

@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);
}

还请注意,根据此问题/答案,在某些设备上发现并不会始终可以按预期工作,因此需要变通办法.

Also note, per this question/answer, on some devices discovery does not always work as expected and there is a need for workarounds.

顺便说一句,您是否检查了logcat中是否有其他错误,例如权限被拒绝等?您可以尝试启用位置并添加位置权限.

By the way, did you check the logcat for other errors, for example denied permissions etc.? You may try to enable location and add location permission.

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

Here is a working sample to display all devices:

AndroidManifest.xml

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

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 );
            }
        }
    };    
}

这篇关于Bluetooth:onReceive()和registerReceiver()这些方法从未被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆