首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >蓝牙低能:未检测到RFDuino

蓝牙低能:未检测到RFDuino
EN

Stack Overflow用户
提问于 2016-04-15 14:50:52
回答 2查看 252关注 0票数 0

我正在尝试编写一个应用程序,以便在安卓手机和RFDuino之间建立一个基本的BLE通信。RFDuino仅仅是广告,可以被"BLE扫描仪“应用程序检测到。下面是该活动的代码草稿,用于检测BLE设备。

问题是,没有检测到任何设备。调试日志显示,方法"onLeScan“甚至一次都不被调用.

我的想法快用完了,我会感激每一个提示:-)

代码语言:javascript
复制
package de.tuhh.et5.serialcommunicator;

import (...)

public class BLEActivity extends AppCompatActivity {
    private static final long SCAN_PERIOD = 10000;
    private int REQUEST_ENABLE_BT = 1;
    public final static String TAG = "BLE_Activity"; // Tag for the LOG

    private BluetoothAdapter ble_adapter;
    private boolean scanning;
    private Handler ble_handler;
    private BLE_DeviceListAdapter BLE_DeviceListAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        d("on Create");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ble);          

        TabHost tabHost=(TabHost)findViewById(R.id.tabHost);
        tabHost.setup();

        TabHost.TabSpec t1=tabHost.newTabSpec("Tab1");
        t1.setContent(R.id.tab1_layout);
        t1.setIndicator("Devices");
        tabHost.addTab(t1);

        BLE_DeviceListAdapter = new BLE_DeviceListAdapter();

       ListView ble_list = (ListView)findViewById(R.id.BLE_DeviceListView);
        ble_list.setAdapter(BLE_DeviceListAdapter);

        ble_handler = new Handler();
        // get a bluetooth adapter from the bluetooth manager
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        ble_adapter = bluetoothManager.getAdapter();

        // Check if BLE is supported by the Android device
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, "BLE Not Supported",
                    Toast.LENGTH_SHORT).show();
            finish();
        }

        // Enable bluetooth
        if (ble_adapter == null || !ble_adapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }

    }


    // menu stuff
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        d("menu inflates");
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.ble_menu, menu);

        if (scanning) {
            menu.findItem(R.id.scanning_start).setVisible(false);
        } else {
            menu.findItem(R.id.scanning_start).setVisible(true);
        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.scanning_start:
                d("scan pressed");
                BLE_DeviceListAdapter.clear();
                ble_scan(true);
                break;
        }
        return true;
    }

    private void ble_scan(final boolean en){
        d("Scan start");
        // stopLeScan and startLeScan are deprecated since Android 5.0, but still work.
        // to offer a compatibility down to Android 4.3 the old methods are used
        if (en){
            ble_handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    d("scan timer finished");
                    scanning = false;
                    ble_adapter.stopLeScan(ble_callback);
                    invalidateOptionsMenu();
                }
            },SCAN_PERIOD);
            scanning = true;
            ble_adapter.startLeScan(ble_callback);
        }else{
            scanning = false;
            ble_adapter.stopLeScan(ble_callback);
        }
        invalidateOptionsMenu();
    }

    private BluetoothAdapter.LeScanCallback ble_callback = new BluetoothAdapter.LeScanCallback(){

        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord){
            d("onLeScan");
            runOnUiThread(new Runnable(){
                @Override
                public void run(){

                    BLE_DeviceListAdapter.addDevice(device);
                    BLE_DeviceListAdapter.notifyDataSetChanged();

                }
            });
        }
    };


    // This class lists the elements in an ble device entry as defined in "ble_device_entry.cml"
    // It is needed in the BLE_DeviceListAdapter class
    private class ViewHolder {
        TextView name;
        TextView device_id;
        TextView device_adress;
    }

    // #####################################################
    // private Class BLE_DeviceListAdapter
    //
    // Adapter to handle found BLE Devices
    // #####################################################

    private class BLE_DeviceListAdapter extends BaseAdapter{

        private ArrayList<BluetoothDevice> ble_devices; // holds found devices
        private LayoutInflater ble_inflater;            // layout inflater

        public BLE_DeviceListAdapter(){
            super();
            // Init
            ble_devices = new ArrayList<>();
            ble_inflater = BLEActivity.this.getLayoutInflater();
        }

        // method to add a device
        public void addDevice(BluetoothDevice ble_device){
            // device is added, if it is not already in the list
            if (!ble_devices.contains(ble_device)){
                ble_devices.add(ble_device);
            }
        }

        // Mandatory, returns device at position ...
        @Override
        public BluetoothDevice getItem(int position){
            return ble_devices.get(position);
        }

        // clear list..
        public void clear(){
            ble_devices.clear();
        }

        // Mandatory: Not needed, therefore just a dummy
        @Override
        public long getItemId(int i) {
            return i;
        }

        // Mandatory: returns size of list
        @Override
        public int getCount() {
            return ble_devices.size();
        }

        // Mandatory: creates and returns view with a device entry
        @Override
        public View getView(int i, View view, ViewGroup viewGroup ){

            ViewHolder viewHolder; // create view holder

            // if the view does not already exist:
            if (view == null){

                view = ble_inflater.inflate(R.layout.ble_device_entry, null);// inflate view
                viewHolder = new ViewHolder(); // create a ViewHolder
                // Connenct the ViewHolder elements to layout elements
                viewHolder.name = (TextView)findViewById(R.id.BLE_sName);
                viewHolder.device_adress = (TextView)findViewById(R.id.BLE_sAdress);
                viewHolder.device_id = (TextView)findViewById(R.id.BLE_sID);
                view.setTag(viewHolder); // Add the ViewHolder as a Tag to the view
            }else{
                // if the view already exists
                viewHolder = (ViewHolder) view.getTag(); // get Tag from view to populate ViewHolder
            }
            // get BLE Device
            Log.d("test", "hier so....");
            BluetoothDevice device = ble_devices.get(i);
            // get device name
            final String deviceName = device.getName();
            // assign device name to ViewHolder Object
            if (deviceName != null && deviceName.length() > 0){
                viewHolder.device_id.setText(deviceName);
            }else viewHolder.device_id.setText(R.string.unknown_ble_device);
            // assign more values
            viewHolder.device_adress.setText(device.getAddress());
            viewHolder.name.setText(R.string.unknown_ble_device);
            d("before return view");
            return view;
        }

    }
    // #####################################################
    // End Adapter
    // #####################################################

    public void d(Object msg) {
        Log.d(TAG, ">==< " + msg.toString() + " >==<");
    }

    public void e(Object msg) {
        Log.e(TAG, ">==< " + msg.toString() + " >==<");
    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-15 17:39:40

在我看来扫描代码看起来没问题。

有些事情需要检查:

您是否调试/日志以检查选项菜单是否有效,并且ble_scan()是否被调用?

您是否调试/日志以检查startLeScan()是否返回true

如果没有找到设备,则不调用onLeScan()回调。

由于您正在扫描10秒,RFDuino应该经常/在足够长的时间内为自己做广告,至少在10秒窗口内总是有一个广告周期。

所有Android版本都需要这些权限:

代码语言:javascript
复制
android.permission.BLUETOOTH

android.permission.BLUETOOTH_ADMIN

此外,Android6.x (Marhsmallow)和以后还需要:

代码语言:javascript
复制
android.permission.ACCESS_COARSE_LOCATION

如果您只编写针对6.x或更高版本的代码,则需要使用新的运行时权限模型,而不是基于旧的清单文件。

在一些运行Android6.x的设备上,必须打开系统宽的“位置”设置。请参阅:onLeScan from BluetoothAdapter.LeScanCallback not called in Android Marshmallow

当然,some of the older discussions可能有一些有用的提示。

票数 0
EN

Stack Overflow用户

发布于 2016-04-17 08:27:31

好吧,我好像把权限搞砸了。我没有该位置的运行时权限。我认为,如果不使用exclusevliy的目标是Android6.xx,基于清单的权限就足够了。现在,我在视图持有人和其他方面有问题,但这是另一个故事:-)。

无论如何,谢谢你的解决方案@MarkusKauppinen!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36650403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档