当应用检查蓝牙是否为启用时,BLE应用程序崩溃,并且mBluetoothAdapter.isMultipleAdvertisementSupported()返回false

时间:2017-08-17 17:20:41

标签: java android android-studio bluetooth bluetooth-lowenergy

我希望有人能就这个问题给我一个建议。我一直试图解决它没有任何运气,我也看到这是一个真正的问题,那里有很多讨论。

这是一个简单的应用程序,只有一个按钮。该按钮将使设备在按下时作为信标工作,并在释放按钮时停止发送数据。开始时,应用会检查此question中建议是否支持蓝牙和BLE。

当设备未打开蓝牙时,应用程序崩溃并要求用户将其打开。但是当设备已经打开蓝牙时它不会崩溃。

进一步分析,我看到执行了以下代码片段,向我显示设备不支持BLE的消息。

if (mBluetoothAdapter.isEnabled()==false) {
    mBluetoothAdapter.enable();
    Toast.makeText(getApplicationContext(),"Enabling Bluetooth", Toast.LENGTH_SHORT).show();
    Log.e("BLE_code", "State: " + mBluetoothAdapter.getState());
}

if(!mBluetoothAdapter.isMultipleAdvertisementSupported()){
    Toast.makeText(getApplicationContext(),"Device does not support BLE", Toast.LENGTH_SHORT).show();
}

我还搜索了website以查看设备是否支持BLE(我正在使用三星Galaxy S7 ),它可能不存在,但我尝试过建议用于检查设备是否允许外围模式下的BLE并且可以发现它的应用程序。 (在谷歌商店有很多应用程序作为信标)。

还有更多人正在努力解决同一问题herehere以及其他一些问题。它可能有点旧,但仍然有效。

您可以在下面找到完整的代码进行测试。

编辑:

MainActivity.java

package com.ble_app.aecheverri.ble_app;
import android.bluetooth.le.AdvertiseSettings;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.content.Intent;
import android.util.Log;
import java.nio.charset.Charset;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.os.ParcelUuid;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseCallback;
import android.widget.EditText;
import java.util.UUID;
import android.content.Context;


public class MainActivity extends AppCompatActivity {

    private BluetoothAdapter mBluetoothAdapter;
    private final static int REQUEST_ENABLE_BT = 1;
    private Button btn;
    private BluetoothLeAdvertiser mBluetoothLeAdvertiser;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button) findViewById(R.id.BLE_CHECK_button);
        final EditText edit = (EditText) findViewById(R.id.Data_Sent);
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        mBluetoothAdapter.setName("APEX");

        //Check if bluetooth is on, otherwise, turn it on!
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();

        Log.e("BLE_code", "State: " + mBluetoothAdapter.getBluetoothLeAdvertiser());

        //getBluetoothLeScanner
        if (mBluetoothAdapter.isEnabled()==false) {
            mBluetoothAdapter.enable();
            Toast.makeText(getApplicationContext(),"Enabling Bluetooth", Toast.LENGTH_SHORT).show();
            Log.e("BLE_code", "State: " + mBluetoothAdapter.getState());
        }

        if(!mBluetoothAdapter.isMultipleAdvertisementSupported()){
            Toast.makeText(getApplicationContext(),"Device does not support BLE", Toast.LENGTH_SHORT).show();
        }


        final BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
        //Set the advertise settings and the power of the signal
        final AdvertiseSettings settings = new AdvertiseSettings.Builder()
                .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
                .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
                .setConnectable(false)
                .build();


        final AdvertiseCallback advertisingCallback = new AdvertiseCallback() {
            @Override
            public void onStartSuccess(AdvertiseSettings settingsInEffect) {
                super.onStartSuccess(settingsInEffect);
            }

            @Override
            public void onStartFailure(int errorCode) {
                Log.e("BLE_code", "Advertising onStartFailure: " + errorCode);
                super.onStartFailure(errorCode);
            }
        };

        //BLE Button

        btn.setOnTouchListener(new View.OnTouchListener() {
            private Handler mHandler;
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {

                switch  (motionEvent.getAction())
                {
                    case MotionEvent.ACTION_DOWN:
                        Log.e( "BLE_code","Button is being pressed");
                        Log.e("BLE_code", "State ble: " + mBluetoothAdapter.getState());
                        ParcelUuid pUuid = new ParcelUuid(UUID.fromString(getString(R.string.ble_uuid)));
                        AdvertiseData data = new AdvertiseData.Builder()
                                .setIncludeDeviceName( true )
                                .addServiceUuid( pUuid )
                                .addServiceData(pUuid,edit.getText().toString().getBytes(Charset.forName("UTF-8")))
                                .build();

                        Log.e( "BLE_code", "Sent Data: " + edit.getText().toString());
                        String macAddress = android.provider.Settings.Secure.getString(getContentResolver(),"bluetooth_address");
                        Toast.makeText(getApplicationContext(),"Device: " + macAddress, Toast.LENGTH_SHORT).show();
                        mBluetoothLeAdvertiser.startAdvertising(settings, data, advertisingCallback);
                        //advertiser.startAdvertising( settings, data, advertisingCallback );

                        if (mHandler!=null) return true;
                        mHandler = new Handler();
                        mHandler.postDelayed(btn_pressed,10);
                        break;
                    case MotionEvent.ACTION_UP:
                        if(mHandler==null) return true;
                        mHandler.removeCallbacks(btn_pressed);
                        mHandler = null;
                        advertiser.stopAdvertising(advertisingCallback);
                        Toast.makeText(getApplicationContext(),"Stoping Advertising", Toast.LENGTH_SHORT).show();
                        Log.e( "BLE_code","Button was released");
                        break;
                }
                return false;
            }

            Runnable btn_pressed = new Runnable() {
                public void run(){
                    Log.e( "BLE_code","Button while pressed");
                    mHandler.postDelayed(this,10);
                }
            };
        });
    }
}

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.ble_app.aecheverri.ble_app.MainActivity">

    <Button
        android:id="@+id/BLE_CHECK_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="195dp"
        android:text="Authenticate"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0.474" />

    <android.support.constraint.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/guideline"
        app:layout_constraintGuide_begin="20dp"
        android:orientation="vertical" />

    <android.support.constraint.Guideline
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/guideline2"
        android:orientation="vertical"
        app:layout_constraintGuide_end="340dp" />

    <EditText
        android:id="@+id/Data_Sent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="text"
        android:text="Data"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/BLE_CHECK_button"
        app:layout_constraintVertical_bias="0.683"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_bias="0.503" />

</android.support.constraint.ConstraintLayout>

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ble_app.aecheverri.ble_app">


    <!-- Declare this required feature if you want to make the app available to BLE-capable
    devices only.  If you want to make your app available to devices that don't support BLE,
    you should omit this in the manifest.  Instead, determine BLE capability by using
    PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) -->

    <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        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>

</manifest>

的strings.xml

<resources>
    <string name="app_name">BLE_app</string>
    <string name="ble_uuid">00000218-0000-1000-8000-00805f9b34fb</string>
</resources>

记录错误

08-17 13:55:25.533 13469-13469/com.ble_app.aecheverri.ble_app E/BoostFramework: BoostFramework() : Exception_1 = java.lang.ClassNotFoundException: Didn't find class "com.qualcomm.qti.Performance" on path: DexPathList[[],nativeLibraryDirectories=[/system/lib64, /vendor/lib64]]
08-17 13:55:25.566 13469-13469/com.ble_app.aecheverri.ble_app E/InputEventReceiver: Exception dispatching input event.
08-17 13:55:25.567 13469-13469/com.ble_app.aecheverri.ble_app E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
08-17 13:55:25.569 13469-13469/com.ble_app.aecheverri.ble_app E/MessageQueue-JNI: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.le.BluetoothLeAdvertiser.startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback)' on a null object reference
                                                                                      at com.ble_app.aecheverri.ble_app.MainActivity$2.onTouch(MainActivity.java:101)
                                                                                      at android.view.View.dispatchTouchEvent(View.java:10727)
                                                                                      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                      at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                      at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                      at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:509)
                                                                                      at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1863)
                                                                                      at android.app.Activity.dispatchTouchEvent(Activity.java:3226)
                                                                                      at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
                                                                                      at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:471)
                                                                                      at android.view.View.dispatchPointerEvent(View.java:10960)
                                                                                      at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5075)
                                                                                      at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4927)
                                                                                      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
                                                                                      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4511)
                                                                                      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4477)
                                                                                      at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4610)
                                                                                      at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4485)
                                                                                      at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4667)
                                                                                      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
                                                                                      at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4511)
                                                                                      at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4477)
                                                                                      at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4485)
                                                                                      at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
                                                                                      at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6960)
                                                                                      at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6899)
                                                                                      at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6860)
                                                                                      at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7070)
                                                                                      at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
                                                                                      at android.os.MessageQueue.nativePollOnce(Native Method)
                                                                                      at android.os.MessageQueue.next(MessageQueue.java:323)
                                                                                      at android.os.Looper.loop(Looper.java:136)
                                                                                      at android.app.ActivityThread.main(ActivityThread.java:6692)
                                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
                                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
08-17 13:55:25.571 13469-13469/com.ble_app.aecheverri.ble_app E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                Process: com.ble_app.aecheverri.ble_app, PID: 13469
                                                                                java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.le.BluetoothLeAdvertiser.startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback)' on a null object reference
                                                                                    at com.ble_app.aecheverri.ble_app.MainActivity$2.onTouch(MainActivity.java:101)
                                                                                    at android.view.View.dispatchTouchEvent(View.java:10727)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
                                                                                    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2492)
                                                                                    at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:509)
                                                                                    at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1863)
                                                                                    at android.app.Activity.dispatchTouchEvent(Activity.java:3226)
                                                                                    at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
                                                                                    at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:471)
                                                                                    at android.view.View.dispatchPointerEvent(View.java:10960)
                                                                                    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5075)
                                                                                    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4927)
                                                                                    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
                                                                                    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4511)
                                                                                    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4477)
                                                                                    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4610)
                                                                                    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4485)
                                                                                    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4667)
                                                                                    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
                                                                                    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4511)
                                                                                    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4477)
                                                                                    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4485)
                                                                                    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4458)
                                                                                    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6960)
                                                                                    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6899)
                                                                                    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6860)
                                                                                    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7070)
                                                                                    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
                                                                                    at android.os.MessageQueue.nativePollOnce(Native Method)
                                                                                    at android.os.MessageQueue.next(MessageQueue.java:323)
                                                                                    at android.os.Looper.loop(Looper.java:136)
                                                                                    at android.app.ActivityThread.main(ActivityThread.java:6692)
                                                                                    at java.lang.reflect.Method.invoke(Native Method)
                                                                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
                                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

1 个答案:

答案 0 :(得分:0)

您的BluetoothLeAdvertiser advertiser有空引用。可能是因为您的BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser()返回null。