不调用BLE功能

时间:2018-06-21 23:47:26

标签: android list nullpointerexception bluetooth-lowenergy

我的代码是:

public class DeviceScanActivity extends AppCompatActivity/*ListActivity*/ {
    //private LeDeviceListAdapter mLeDeviceListAdapter;
    private BluetoothAdapter mBluetoothAdapter;
    private boolean mScanning;
    private Handler mHandler;
    ArrayList<String> mylist = new ArrayList<String>();
    private static final int REQUEST_ENABLE_BT = 1;
    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 10000;
    UsersAdapter adapter;
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //getActionBar().setTitle("abc");

        mHandler = new Handler();

        // Use this check to determine whether BLE is supported on the device.  Then you can
        // selectively disable BLE-related features.
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
            finish();
        }
        // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
        // BluetoothAdapter through BluetoothManager.
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        // Checks if Bluetooth is supported on the device.
        if (mBluetoothAdapter == null) {
            Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
            finish();
            return;
        }


        // Construct the data source

        ArrayList<ViewHolder> arrayOfUsers = new ArrayList<ViewHolder>();

       // Create the adapter to convert the array to views

         adapter = new UsersAdapter(this, arrayOfUsers);

        ListView listView = (ListView) findViewById(R.id.mobile_list);
        listView.setAdapter(adapter);
        scanLeDevice(true);
        ViewHolder newUser2 = new ViewHolder("adtv2","vvg2");
         adapter.add(newUser2);

    }


    private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            ViewHolder newUser2 = new ViewHolder("adtv2","vvg2");
            adapter.add(newUser2);
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    //invalidateOptionsMenu();
                }
            }, SCAN_PERIOD);
            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
        //invalidateOptionsMenu();
    }



    // Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {

                @Override
                public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //mLeDeviceListAdapter.addDevice(device);
                            //mLeDeviceListAdapter.notifyDataSetChanged();

                            //ViewHolder newUser = new ViewHolder("Nathan", "San Diego");
                            String deviceName=null, deviceAddress=null;
                            if(device!=null)
                               deviceName= device.getName();
                            if (!(deviceName != null && deviceName.length() > 0))
                                deviceName = "unknown device";
                            if(device!=null)
                                deviceAddress= device.getAddress();
                            ViewHolder newUser = new ViewHolder(deviceName, deviceAddress);
                            ViewHolder newUser2 = new ViewHolder("adtv","vvg");
                            adapter.add(newUser2);
                        }
                    });
                }
            };
    public class UsersAdapter extends ArrayAdapter<ViewHolder> {

        public UsersAdapter(Context context, ArrayList<ViewHolder> users) {

            super(context, 0, users);

        }



        @Override

        public View getView(int position, View convertView, ViewGroup parent) {

            // Get the data item for this position

            ViewHolder user = getItem(position);

            // Check if an existing view is being reused, otherwise inflate the view

            if (convertView == null) {

                convertView = LayoutInflater.from(getContext()).inflate(R.layout.bt_details, parent, false);

            }

            // Lookup view for data population

            TextView tvName = (TextView) convertView.findViewById(R.id.DeviceName);

            TextView tvHome = (TextView) convertView.findViewById(R.id.DeviceAddress);

            // Populate the data into the template view using the data object

            tvName.setText(user.deviceName);

            tvHome.setText(user.deviceAddress);

            // Return the completed view to render on screen

            return convertView;

        }

    }
    public class ViewHolder {
        String deviceName;
        String deviceAddress;

        public ViewHolder(String device, String __address) {
            this.deviceName =device;
            this.deviceAddress= __address;
        }
    }

}


**I am trying to list the available Bluetooth devices after scan. 

我想这个方法没有被调用,因为listview只打印2条消息。它应该print3才能正常工作 LeScanCallback中的代码无法打印,所以我猜这个代码没有被调用。因此,蓝牙功能不起作用。**

bt_details.xml->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
            android:id="@+id/DeviceName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Name" />

        <TextView
            android:id="@+id/DeviceAddress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Address" />

    </LinearLayout>

listitem_device.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
     <!--   <TextView android:id="@+id/device_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="24dp"/>
        <TextView android:id="@+id/device_address"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="12dp"/>-->
        <ListView
            android:id="@android:id/list"
            android:layout_height="wrap_content"
            android:layout_width="match_parent">
        </ListView>
    </LinearLayout>

main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--tools:context=".ListActivity" -->

    <ListView
        android:id="@+id/mobile_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

listitem.xml

<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/label"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dip"
    android:textSize="16dip"
    android:textStyle="bold" >
</TextView>

我猜是BLUETOOTH发现的问题。我已经粘贴了代码和布局xml文件

2 个答案:

答案 0 :(得分:1)

您在ListActivity上使用了错误的布局,似乎您复制了一个在线示例,并试图对其进行修改以执行本来不是针对(动态数据)的操作

我建议您更改

public class DeviceScanActivity extends ListActivity

收件人

public class DeviceScanActivity extends AppCompatActivity

并删除setListAdapter方法。

然后使用您的主要布局

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);  // here

然后,这些数据将正常工作

        String[] mobileArray = {"Android","IPhone","WindowsMobile","Blackberry",
                "WebOS","Ubuntu","Windows7","Max OS X"};
        ArrayAdapter adapter = new ArrayAdapter<String>(this,
                R.layout.listitem, mobileArray);

        ListView listView = (ListView) findViewById(R.id.mobile_list);
        listView.setAdapter(adapter);

但是,您想添加蓝牙设备,因此删除所有内容(或者至少确保首先运行),然后换个适配器,可能是一个自定义-start here,然后通过“使用自定义ArrayAdapter”部分进行阅读。

例如public class LeDeviceListAdapter extends ArrayAdapter< BluetoothDevice>

如果那是您的活动领域的适配器

public class DeviceScanActivity extends AppCompatActivity {
    private LeDeviceListAdapter mLeDeviceListAdapter; // This here

然后,此代码应该有效

// in onCreate
mLeDeviceListAdapter = new LeDeviceListAdapter();

然后将您的监听器设置为仅使用内置的add方法

// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
        new BluetoothAdapter.LeScanCallback() {

            @Override
            public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mLeDeviceListAdapter.add(device);
                    }
                });
            }
        };

答案 1 :(得分:0)

我添加了

requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 456;

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_COARSE_LOCATION: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission granted, yay! Start the Bluetooth device scan.
                    scanLeDevice(true);
                } else {
                    // Alert the user that this application requires the location permission to perform the scan.
                }
            }
        }
    }

将build.gradle中的minSdkVersion更改为23 现在BLE扫描效果很好