Android 启动扫描时,BluetoothLeScanner应用程序崩溃,且不显示任何结果

Android 启动扫描时,BluetoothLeScanner应用程序崩溃,且不显示任何结果,android,android-bluetooth,android-ble,Android,Android Bluetooth,Android Ble,我看到的错误消息是: 尝试在com.example.drodo.diamondbeacons.bleDeviceActivity.startScanning(bleDeviceActivity.java:91)上的空对象引用上调用虚拟方法“void android.bluetooth.le.BluetoothLeScanner.startScan(java.util.List,android.bluetooth.le.ScanSettings,android.bluetooth.le.ScanC

我看到的错误消息是:

尝试在com.example.drodo.diamondbeacons.bleDeviceActivity.startScanning(bleDeviceActivity.java:91)上的空对象引用上调用虚拟方法“void android.bluetooth.le.BluetoothLeScanner.startScan(java.util.List,android.bluetooth.le.ScanSettings,android.bluetooth.le.ScanCallback)”在com.example.drodo.diamondbeacons.BleDevicesActivity$1.onClick(BleDevicesActivity.java:68)。行中出现错误:mBluetoothLeScanner.startScan(buildScanFilters()、buildScanSettings()、mScanCallback)

这是我的密码:

public class BleDevicesActivity extends AppCompatActivity {

private Toolbar bleToolbar;

private static final String TAG = BleDevicesActivity.class.getName();

private static final long SCAN_PERIOD = 5000;

private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothLeScanner;
private ScanCallback mScanCallback;
private TextView deviceName;
private TextView deviceAddress;
private Button scanDevicesBtn;
private Handler mHandler;

public void setBluetoothAdapter(BluetoothAdapter btAdapter) {
    this.mBluetoothAdapter = btAdapter;
    mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
}

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

    mHandler = new Handler();

    bleToolbar = (Toolbar) findViewById(R.id.ble_toolbar);
    setSupportActionBar(bleToolbar);
    getSupportActionBar().setTitle("Ble Devices Nearby");
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    deviceName = (TextView) findViewById(R.id.device_name_text);
    deviceAddress = (TextView) findViewById(R.id.device_address_text);
    scanDevicesBtn = (Button) findViewById(R.id.scan_devices_btn);

    scanDevicesBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startScanning();

            Snackbar.make(v, "Scanning for BLE Devices Nearby", Snackbar.LENGTH_SHORT)
                    .setAction("Action", null).show();
        }
    });
}

public void startScanning() {
    if (mScanCallback == null) {
        Log.d(TAG, "Starting Scanning");

        // Will stop the scanning after a set time.
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                stopScanning();
                Toast.makeText(BleDevicesActivity.this, "Scanning Stopped", Toast.LENGTH_SHORT).show();
            }
        }, SCAN_PERIOD);

        // Kick off a new scan.
        mScanCallback = new SampleScanCallback();
        mBluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), mScanCallback);

        String toastText = getString(R.string.scan_start_toast) + " "
                + TimeUnit.SECONDS.convert(SCAN_PERIOD, TimeUnit.MILLISECONDS) + " "
                + getString(R.string.seconds);
        Toast.makeText(BleDevicesActivity.this, toastText, Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(BleDevicesActivity.this, R.string.already_scanning, Toast.LENGTH_SHORT).show();
    }
}

/**
 * Stop scanning for BLE Advertisements.
 */
public void stopScanning() {
    Log.d(TAG, "Stopping Scanning");

    // Stop the scan, wipe the callback.
    mBluetoothLeScanner.stopScan(mScanCallback);
    mScanCallback = null;

    // Even if no new results, update 'last seen' times.
    //amAdapter.notifyDataSetChanged();
}

/**
 * Return a List of {@link ScanFilter} objects to filter by Service UUID.
 */
private List<ScanFilter> buildScanFilters() {
    List<ScanFilter> scanFilters = new ArrayList<>();

    ScanFilter.Builder builder = new ScanFilter.Builder();
    builder.setServiceUuid(BleConstants.Service_UUID);
    scanFilters.add(builder.build());

    return scanFilters;
}

/**
 * Return a {@link ScanSettings} object set to use low power (to preserve battery life).
 */
private ScanSettings buildScanSettings() {
    ScanSettings.Builder builder = new ScanSettings.Builder();
    builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
    return builder.build();
}

/**
 * Custom ScanCallback object - adds to adapter on success, displays error on failure.
 */
private class SampleScanCallback extends ScanCallback {

    @Override
    public void onBatchScanResults(List<ScanResult> results) {
        super.onBatchScanResults(results);

        for (ScanResult result : results) {
            String device_name = result.getDevice().getName();
            String device_address = result.getDevice().getAddress();

            deviceName.setText(device_name);
            deviceAddress.setText(device_address);
        }

    }

    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);
        try {
            ScanRecord scanRecord = result.getScanRecord();

            assert scanRecord != null;
            byte[] manufacturerData = scanRecord.getManufacturerSpecificData(0x0590);

            assert manufacturerData != null;

            double lightValue = Double.parseDouble(Arrays.toString(new byte[]{manufacturerData[0]}).replace("[", "").replace("]", ""));
            double tempValue = Double.parseDouble(Arrays.toString(new byte[]{manufacturerData[1]}).replace("[", "").replace("]", ""));
            double batteryValue = Integer.parseInt(Arrays.toString(new byte[]{manufacturerData[2]}).replace("[", "").replace("]", ""));
            int alertPresses = Integer.parseInt(Arrays.toString(new byte[]{manufacturerData[3]}).replace("[", "").replace("]", ""));

            Toast.makeText(BleDevicesActivity.this, "LIGHT: " + lightValue + " %", Toast.LENGTH_SHORT).show();
            Toast.makeText(BleDevicesActivity.this, "TEMPERATURE: " + tempValue + " \u2103", Toast.LENGTH_SHORT).show();
            Toast.makeText(BleDevicesActivity.this, "BATTERY LEVEL: " + batteryValue + " Volts", Toast.LENGTH_SHORT).show();
            Toast.makeText(BleDevicesActivity.this, "ALERT PRESSES: " + alertPresses, Toast.LENGTH_SHORT).show();

        } catch (Exception e) {

            String error_message = e.getMessage();
            Toast.makeText(BleDevicesActivity.this, "Error: " + error_message, Toast.LENGTH_SHORT).show();
        }

    }

    @Override
    public void onScanFailed(int errorCode) {
        super.onScanFailed(errorCode);
        Toast.makeText(BleDevicesActivity.this, "Scan failed with error: " + errorCode, Toast.LENGTH_LONG)
                .show();
    }
}
}
公共类BleDeviceActivity扩展了AppCompatActivity{
专用工具栏;
私有静态最终字符串标记=bleDeviceActivity.class.getName();
专用静态最终长扫描周期=5000;
私人蓝牙适配器mBluetoothAdapter;
私人BluetoothLeScanner mBluetoothLeScanner;
专用扫描回拨;
私有文本视图设备名;
私有文本视图设备地址;
私人按钮扫描设备;
私人经理人;
公用适配器(蓝牙适配器btAdapter){
this.mBluetoothAdapter=btAdapter;
mBluetoothLeScanner=mBluetoothAdapter.getBluetoothLeScanner();
}
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u ble\u设备);
mHandler=新处理程序();
bleToolbar=(Toolbar)findviewbyd(R.id.ble\u Toolbar);
设置支持操作栏(工具栏);
getSupportActionBar().setTitle(“附近的可扩展设备”);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
deviceName=(TextView)findViewById(R.id.device\u name\u text);
deviceAddress=(TextView)findViewById(R.id.device\u address\u text);
scanDevicesBtn=(按钮)findviewbyd(R.id.scan\u devices\u btn);
scanDevicesBtn.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
开始扫描();
Snackbar.make(v,“扫描附近的BLE设备”,Snackbar.LENGTH_SHORT)
.setAction(“Action”,null).show();
}
});
}
公共无效开始扫描(){
如果(mScanCallback==null){
Log.d(标签“开始扫描”);
//将在设定的时间后停止扫描。
mHandler.postDelayed(新的Runnable(){
@凌驾
公开募捐{
停止扫描();
Toast.makeText(bleDeviceActivity.this,“扫描停止”,Toast.LENGTH_SHORT.show();
}
},扫描周期);
//开始新的扫描。
mScanCallback=新样本Cancallback();
开始扫描(buildScanFilters(),buildScanSettings(),mScanCallback);
String toast text=getString(R.String.scan\u start\u toast)+“
+TimeUnit.SECONDS.convert(扫描周期,TimeUnit.ms)+“
+getString(R.string.seconds);
Toast.makeText(bleDeviceActivity.this、Toast-Text、Toast.LENGTH_LONG).show();
}否则{
Toast.makeText(bleDeviceActivity.this,R.string.ready_scanning,Toast.LENGTH_SHORT).show();
}
}
/**
*停止扫描不可编辑的广告。
*/
公共无效停止扫描(){
Log.d(标签“停止扫描”);
//停止扫描,擦除回调。
mBluetoothLeScanner.stopScan(mScanCallback);
mScanCallback=null;
//即使没有新结果,也要更新“上次看到”的次数。
//amAdapter.notifyDataSetChanged();
}
/**
*返回要按服务UUID筛选的{@link ScanFilter}对象列表。
*/
私有列表buildScanFilters(){
List scanFilters=新建ArrayList();
ScanFilter.Builder=新建ScanFilter.Builder();
builder.setServiceUuid(bleContents.Service_UUID);
添加(builder.build());
返回扫描滤波器;
}
/**
*返回{@link ScanSettings}对象集以使用低功耗(以保持电池寿命)。
*/
专用扫描设置buildScanSettings(){
ScanSettings.Builder=新的ScanSettings.Builder();
builder.setScanMode(扫描设置.扫描模式\u低功率);
返回builder.build();
}
/**
*自定义ScanCallback对象-成功时添加到适配器,失败时显示错误。
*/
私有类SampleScanCallback扩展ScanCallback{
@凌驾
public void onBatchScanResults(列出结果){
super.onBatchScanResults(结果);
用于(扫描结果:结果){
字符串device_name=result.getDevice().getName();
字符串device_address=result.getDevice().getAddress();
deviceName.setText(设备名称);
deviceAddress.setText(设备地址);
}
}
@凌驾
公共void onScanResult(int callbackType、ScanResult){
super.onScanResult(回调类型、结果);
试一试{
ScanRecord ScanRecord=result.getScanRecord();
断言扫描记录!=null;
字节[]manufacturerData=scanRecord.GetManufacturerSpecificATA(0x0590);
断言manufacturerData!=null;
double lightValue=double.parseDouble(Arrays.toString(新字节[]{manufacturerData[0]})。替换(“[”,“”)。替换(“]”,“”);
double tempValue=double.parseDouble(Arrays.toString(新字节[]{manufacturerData[1]})。替换(“[”,“”)。替换(“]”,“”);
double batteryValue=Integer.parseInt(Arrays.toString(新字节[]{manufacturerData[2]})。替换(“[”,”)。替换(“],”);
int alertpress=Integer.parseInt(Arrays.toString(新字节[]{manufacturerData[3]})。替换(“[”,“”)。替换(“]”,“”);
Toast.makeText(bleDeviceActivity.this,“LIGHT:+lightValue+“%”,Toast.LENGTH\u SHORT.show();
Toast.makeText(bleDeviceActivity.this,“温度:+tempValue+”\u2103”,Toast.LENGTH\u SHORT.show();
Toast.makeText(bleDeviceActivity.this,“电池电量:+电池电量值+”伏特),Toast.LENGTH_SHORT.show();
烤面包
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
BluetoothLeScanner scanner = mBluetoothAdapter.getBluetoothLeScanner();
if (scanner != null) {
    scanner.startScan(buildScanFilters(), buildScanSettings(), mScanCallback);
} else {
    // Device Bluetooth is disabled; check and prompt user to enable.
}
BluetoothLeScanner scanner = mBluetoothAdapter.getBluetoothLeScanner();
if (scanner != null) {
    scanner.stopScan(mScanCallback);
} else {
    // Device Bluetooth is disabled; scanning should already be stopped, nothing to do here.
}