-2

I hope someone can give me an advice with regard to this problem. I've been trying to solve it without any luck, I´ve seen also that this is a real problem and there is a lot of discussions out there.

This is a simple app, that has only a button. The button will make the device to work as a beacon while is pressed, and it will stop sending data when the button is released. At the beginning, the app will check if Bluetooth and BLE are supported suggested in this question.

The app crashes when the device does not have the Bluetooth turned on and asks the user to turn it on. But it doesn´t crash when the device has the Bluetooth already turned on.

Doing further analysis, I saw that the following code snippet is executed showing me the message that The device does not support 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();
}

I also searched on this website to see if the device does support BLE (I'm working with a Samsung Galaxy S7), it might not be there, but I have tried the app that is suggested to check if the device allows BLE in peripheral mode and it can be discovered. (On the google store there are plenty apps that work as beacons).

There are also more people struggling with the same issue right here, here and some other questions. It might be a little bit old, but still valid.

You can find the full code below to test.

EDITED:

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>

Log errors

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)
  • Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: [How to create a Minimal, Complete, and Verifiable example.](https://stackoverflow.com/help/mcve) – Bob Aug 17 '17 at 17:53
  • Thanks for your suggestion. I tried to make myself as clear as possible. in the program, there is a button that is pressed and the app is crashing. – aecheverri Aug 17 '17 at 18:25
  • Please post your crash log then. – Bob Aug 17 '17 at 18:27
  • Here is the error that shows in log when it crashes. – aecheverri Aug 17 '17 at 18:55

1 Answers1

0

Your BluetoothLeAdvertiser advertiser has null reference. Probably because your BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser() returns null.

Bob
  • 13,447
  • 7
  • 35
  • 45
  • I saw that in the log, you are right. However, I can create a conditional that checks if its null or if its not enable, something like this: if (mBluetoothAdapter == null || mBluetoothAdapter.isEnabled()) – aecheverri Aug 17 '17 at 19:24
  • I just added the following lines to the code (take a look at the updated code where I check all of the suggestions done in the post). Is still crashing, I know my device supports Bluetooth and BLE as peripheral. However, the BluetoothAdpter shouldn't be null once is on. Otherwise. How should I assign the BluetoothAdpter? – aecheverri Aug 17 '17 at 19:38
  • Also, this only happens if I have the Bluetooth off and the app asks the user to turn it on. It doesn´t happen when the app is running when the Bluetooth has been previously turned on. – aecheverri Aug 17 '17 at 19:44
  • you should implement `onActivityResult`. Check this tutorial: https://androiddesk.wordpress.com/tag/enabling-bluetooth-in-android-example/ – Bob Aug 17 '17 at 19:49
  • I just saw that the app is executing this code if(!mBluetoothAdapter.isMultipleAdvertisementSupported()){ Toast.makeText(getApplicationContext(),"Device does not support BLE", Toast.LENGTH_SHORT).show(); } only when the app asks the user to turn on the Bluetooth. Why? I'm using a Samsung S7. Otherwise, it works fine and it does what it is supposed to do. – aecheverri Aug 17 '17 at 20:16
  • Any idea about this problem. How my device can work as peripheral using the BLE, but the "ismultipleAdvertisementSupported() is false? – aecheverri Aug 17 '17 at 22:00
  • You should post that as a new question with the new things you have done so far. – Bob Aug 18 '17 at 07:08
  • I can´t since the question wasn´t well-received (There is a bunch of salty people here). I will try to edit, hoping that someone can´t help. This is a real problem, I´ve seen a lot of people with the same issue. I might ask somewhere else. – aecheverri Aug 18 '17 at 14:14