BLE Advertisement in Android

android ble get advertising data
android ble advertising background
android ble library
android advertise_failed_data_too_large
android ble multi advertisement
android ble advertising github
android ble peripheral mode
android ble peripheral example

I am developing and app to Send BLE Advertisement packet in android. I have use AdvertiseData and AdverstiseSettings classes to generate the advertise packet. But when i do the StartAdvertising it always gives me an error with Error Code "2" , "ADVERTISE_FAILED_TOO_MANY_ADVERTISERS", "Failed to start advertising because no advertising instance is available."

Below is my code for MainActivity.JAVA

package rockwellcollins.blutooth_advertise;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private BluetoothLeScanner mBluetoothLeScanner;
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        textView = (TextView) findViewById(R.id.txtv);
        mBluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();

        if( !BluetoothAdapter.getDefaultAdapter().isMultipleAdvertisementSupported() ) {
            Toast.makeText(this, "Multiple advertisement not supported", Toast.LENGTH_SHORT).show();
        }
        advertise();
        BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner().startScan(scanCallback);
    }

    private void advertise() {
        BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();

        AdvertiseSettings settings = new AdvertiseSettings.Builder()
                .setAdvertiseMode( AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY )
                .setTxPowerLevel( AdvertiseSettings.ADVERTISE_TX_POWER_HIGH )
                .setConnectable(false)
                .build();
        Log.i("BLE","start of advertise data after settings");
        ParcelUuid pUuid = new ParcelUuid( UUID.fromString("b161c53c-0715-11e6-b512-3e1d05defe78"));

        AdvertiseData data = new AdvertiseData.Builder()
                .setIncludeDeviceName( true )
                .setIncludeTxPowerLevel(true)
                .addServiceUuid( pUuid )
                //.addServiceData( pUuid, "Data".getBytes(Charset.forName("UTF-8") ) )
                .build();
        Log.i("BLE","before callback");
        AdvertiseCallback advertisingCallback = new AdvertiseCallback() {
            @Override
            public void onStartSuccess(AdvertiseSettings settingsInEffect) {
                super.onStartSuccess(settingsInEffect);
                Log.i("BLE", "LE Advertise success.");

            }

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

        advertiser.startAdvertising( settings, data, advertisingCallback );
        Log.i("BLE", "start advertising");
    }

    private final ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            printScanResult(result);
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            textView.append("Received " + results.size() + " batch results:\n");
            for (ScanResult r : results) {
                printScanResult(r);
            }
        }

        @Override
        public void onScanFailed(int errorCode) {
            switch (errorCode) {
                case ScanCallback.SCAN_FAILED_ALREADY_STARTED:
                    textView.append("Scan failed: already started.\n");
                    break;
                case ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED:
                    textView.append("Scan failed: app registration failed.\n");
                    break;
                case ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED:
                    textView.append("Scan failed: feature unsupported.\n");
                    break;
                case ScanCallback.SCAN_FAILED_INTERNAL_ERROR:
                    textView.append("Scan failed: internal error.\n");
                    break;
            }
        }

        private void printScanResult(ScanResult result) {
            String id = result.getDevice() != null ? result.getDevice().getAddress() : "unknown";
            int tx = result.getScanRecord() != null ? result.getScanRecord().getTxPowerLevel() : 0;
            textView.append("TX: " + tx + " RX: " + result.getRssi() + " from " + id+ ".\n");
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Code for Android Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="rockwellcollins.blutooth_advertise">
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Could you please let me know what I am doing wrong and how can I solve this error?

Thanks

From my experience there are 4 types of Android devices in regard BLE advertisement:

  1. Devices with Android pre-5.0 - LE Advertisement not supported
  2. Devices with Android 5+ that don't support LE Advertisement and return null from getBluetoothLeAdvertiser(). Those devices return false from isMultipleAdvertisementSupported(). They do this even with Bluetooth ON (see Note below).
  3. Devices with Android 5+ that return the BluetoothLeAdvertiser object, but each try of advertising ends with ADVERTISE_FAILED_TOO_MANY_ADVERTISERS error (this is the case you have). Those devices return true from isMultipleAdvertisementSupported() which as you see is not true. So far I've seen only one phone from this category: Sony xperia z1 compact, but if there is one, there are more.
  4. Devices with Android 5+ that support LE Advertisement. Those return true from isMultipleAdvertisementSupported() but ONLY when Bluetooth is ON.

Note: in the 2., 3. and 4. the BluetoothLeAdvertiser object is returned ONLY when Bluetooth is ON. Otherwise null is returned, so you actually have no clue whether the device supports LE Advertisement or not until Bluetooth is enabled.

Check the nRF Connect app: Disable Bluetooth, install the app, open and select Advertiser tab or Navigation menu -> Device information. It will ask you to turn Bluetooth ON before the status will be shown.

BluetoothLeAdvertiser, From my experience there are 4 types of Android devices in regard BLE advertisement: Devices with Android pre-5.0 - LE Advertisement not supported; Devices� Find Ads For Advertising now. Visit & Look for More Results! Search for Ads For Advertising on fastquicksearch.com!

See this question for a possible answer, BLE Advertisments are not supported on every device.

Also try to omit the device name as suggested here.

BLE Advertisement in Android, Although a relatively new technology, Bluetooth Low Energy (LE) has as Bluetooth LE advertising was not introduced on Android until the� Search For Free Advertisement & Get Awesome Results. Search Free Advertisement. Compare Results on Zoo.com

You only need to add this code: @TargetApi(Build.VERSION_CODES.M) over your method

How to Advertise Android as a Bluetooth LE Peripheral, Android Advertising a BLE Device. Example#. You can use Bluetooth LE Advertising to broadcast data packages to all nearby devices without having to� Welcome to Internetcorkboard.com. Find Ads For Advertising Today! Find Ads For Advertising Now at Internetcorkboard.com!

Android, Hello, I am a android developer. I have developed one android application scan BLE device. It's working fine to scan BLE device. Now I want read advertisement � Looking for advertisement online? Search now! Explore Teoma.us, the leading search site for results around the web

How to read advertisement package from ble device in android app , Migrated:. Contribute to googlearchive/android-BluetoothAdvertisements development by creating an account on GitHub. Bluetooth 5 advertising extension Android 8.0 supports Bluetooth 5, which provides broadcasting improvements and flexible data advertisement for BLE. Bluetooth 5 supports BLE Physical Layers (PHYs) that retain the reduced power consumption of Bluetooth 4.2 and let users choose increased bandwidth or range.

googlearchive/android-BluetoothAdvertisements: Migrated, The BLE Peripheral Simulator is an Android app that allows developers to try out new features of Web Bluetooth without the need for a BLE Peripheral Device. MATCH_MODE_STICKY is useful in filtering out advertising BLE devices that are too far away from the Android device, since it requires a higher threshold of signal strength and number of sightings before that BLE device is surfaced as a scan result to our app.

Comments
  • I'm currently testing on a device that does not fall in any of those types, Huawei Mate 20 lite: isMultipleAdvertisementSupported() returns false even though it does allow advertisement, but only one at a time (hence it is sort of correct, as it does not allow multiple).
  • I check for the Bluetooth LE Feature and it's available on my device. PackageManager manager = getApplicationContext().getPackageManager(); boolean featureAvailable = manager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE); if(!featureAvailable) Toast.makeText(this, "Bluetooth LE feature is not available", Toast.LENGTH_SHORT).show();
  • Just the Bluetooth LE feature isn't enough. The advertisement is not supported on all devices that have Bluetooth LE. There's a list of compatible devices and you test if your device can advertise if you try out this app from Radius.
  • Actually, I am using Qualcomm eval kit for Android, APQ 8084 and it has Bluetooth 4.1, which means it supports the LE mode.
  • Did you check out the App @Markus Kauppinen suggested?
  • I checked it, but every time when click on the the Beacon Transmitter it crashes. Also, through my code I am seeing a ToastMessage of "Multiple advertisement not supported", so does it means that I am not able to transmit the beacon?