Error code 2 in beacon transmitter for Android Beacon library - android

I want to send a BLE advertisement using Android beacon library. Below is the code I am using for it.
package com.example.beacon_emitter;
import java.util.Arrays;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.BeaconTransmitter;
import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseSettings;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Beacon beacon = new Beacon.Builder()
.setId1("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6")
.setId2("1")
.setId3("2")
.setManufacturer(0x0118)
.setTxPower(-59)
.setDataFields(Arrays.asList(new Long[] {0l}))
.build();
BeaconParser beaconParser = new BeaconParser()
.setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");
BeaconTransmitter beaconTransmitter = new BeaconTransmitter(getApplicationContext(), beaconParser);
beaconTransmitter.startAdvertising(beacon,new AdvertiseCallback() {
#Override
public void onStartFailure(int errorCode) {
Log.e("beacon", "Advertisement start failed with code: "+errorCode);
}
#Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
Log.i("beacon", "Advertisement start succeeded.");
}
});
int result = BeaconTransmitter.checkTransmissionSupported(getApplicationContext());
Toast.makeText(this, "Device info " + result, Toast.LENGTH_LONG).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
It always gives me an errorcode 2, ADVERTISE_FAILED_TOO_MANY_ADVERTISERS. But the strange thing is when I checked the toast message it says the my device is supported the beacon transmission. I am confused.
Please help!
Thanks in Advance.

A few tips:
The BeaconTransmitter.checkTransmissionSupported() method only checks to see if the device has Bluetooth LE and that the operating system will give you a BluetoothAdvertiser.
To see if somebody else has been successful with getting your device to transmit, check to see if it is on this list: http://altbeacon.github.io/android-beacon-library/beacon-transmitter-devices.html
The ADVERTISE_FAILED_TOO_MANY_ADVERTISERS response can indicate that another app is advertising a beacon, and all the advertisement slots are used. Make sure that you don't have any other apps advertising in the background. Reboot or uninstall other apps that might be doing this if necessary.
Try the Locate Beacon app which is based on this same library, and see if it can advertise a beacon successfully. This will eliminate any possible problem with your code.
EDIT: Based on the comments below, it is reasonable to conclude that the firmware for the Intrynsyc eval kit does not properly implement the interface between Android and the Bluetooth chip. Otherwise it would either report that advertising is not available or it would not return an error message when starting advertising. The appropriate next step would be to open an issue with Intrynsyc and report these findings.

The ability to transmit as a beacon requires Bluetooth LE
advertisement capability, which may or may not be supported by a
device’s firmware.
Quote from Device Support For Beacon Transmission with Android 5+

Related

Application cycles between didEnterRegion() and didExitRegion() even when the device stays stationary near the beacon

I am using AltBeacon Android Library (I reproduced issue with v2.9.2; and also with v2.11) for integrating with iBeacon devices provided by Onyx and kontact.io.
The library seems to work very well, but I seem to have an issue with it for which I could not find an acceptable solution.
Here are some more details about how I use AltBeacon Library and about the issue:
Device is stationary near the beacon
Bluetooth on
Application runs in foreground
The BeaconManager is configured to scan in foreground mode with the following settings:
BeaconManager.setRegionExitPeriod(30000L);
beaconManager.setBackgroundBetweenScanPeriod(120000L);
beaconManager.setForegroundScanPeriod(5000L);
beaconManager.setForegroundBetweenScanPeriod(10000L);
beaconManager.getBeaconParsers().add(
new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
Application sets the BeaconManager in foreground mode
beaconManager.setBackgroundMode(false);
Application bounds to the BeaconManager
beaconManager.bind(…)
When onBeaconServiceConnect() is triggered, the application starts monitoring beacons in specific regions (the list of beacons I want to monitor is known, static; I use a list of regions, one different region for each beacon I want to monitor)
beaconManager.startMonitoringBeaconsInRegion(region);
When device enters beacon region (didEnterRegion() is called) application starts ranging for entered region
beaconManager.startRangingBeaconsInRegion(region);
Beacon is detected (didRangeBeaconsInRegion() is called for corresponding beacon)
Application switched beacon scanning to background mode:
beaconManager.setBackgroundMode(true);
After a few minutes, the didExitRegion() is called even if the device and the beacon were not moved and the application remained in the same state.
I have found two Stackoverflow issues which describe the same issue:
AltBeacon unstable for OnyxBeacons, cycling through didEnterRegion and didExitRegion repeatedly
http://stackoverflow.com/questions/40835671/altbeacon-reference-app-and-multiple-exit-entry-calls
The workaround that I currently use is the one suggested in the Stackoverflow issues:
I have updated beacon Advertising Frequency value from 1000 ms to 100 ms.
Once the frequency is increased, everything seems to work fine, but
the solution is not acceptable because the battery life of the beacon is
drastically impaired.
All the beacon scanning is performed in background (i.e. no Activity is used):
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.RemoteException;
import android.support.annotation.NonNull;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.Identifier;
import org.altbeacon.beacon.MonitorNotifier;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;
import org.altbeacon.beacon.powersave.BackgroundPowerSaver;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class BeaconDataProvider implements BeaconConsumer, RangeNotifier, MonitorNotifier {
private final Logger LOGGER = LogFactory.get(this);
private final Context applicationContext;
private final BeaconIdentifierFactory beaconIdentifierFactory;
private final BeaconScanningListener beaconScanningListener;
private BeaconManager beaconManager;
private Collection<Region> targetedRegions;
/**
* This field is used for improving battery consumption. Do not remove it.
*/
#SuppressWarnings({"unused", "FieldCanBeLocal"})
private BackgroundPowerSaver backgroundPowerSaver;
public BeaconDataProvider(Context applicationContext, BeaconIdentifierFactory beaconIdentifierFactory,
BeaconScanningListener beaconScanningListener) {
LOGGER.v("BeaconDataProvider - new instance created.");
this.applicationContext = applicationContext;
this.beaconIdentifierFactory = beaconIdentifierFactory;
this.beaconScanningListener = beaconScanningListener;
beaconManager = BeaconManager.getInstanceForApplication(applicationContext);
LOGGER.v("BeaconManager hashCode=%s", beaconManager.hashCode());
BeaconManager.setRegionExitPeriod(30000L);
beaconManager.setBackgroundBetweenScanPeriod(120000L);
beaconManager.setForegroundScanPeriod(5000L);
beaconManager.setForegroundBetweenScanPeriod(10000L);
beaconManager.getBeaconParsers().add(
new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
backgroundPowerSaver = new BackgroundPowerSaver(applicationContext);
}
public void setBackgroundMode() {
LOGGER.i("setBackgroundMode()");
beaconManager.setBackgroundMode(true);
}
public void setForegroundMode() {
LOGGER.i("setForegroundMode()");
beaconManager.setBackgroundMode(false);
}
public boolean checkAvailability() {
return android.os.Build.VERSION.SDK_INT >= 18 && applicationContext.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
public boolean isBluetoothEnabled() {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
boolean result = mBluetoothAdapter != null && mBluetoothAdapter.isEnabled();
LOGGER.i("isBluetoothEnabled() -> %s", result);
return result;
}
public boolean isLocationPermissionGranted(Context context) {
return (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED);
}
public void startScanning(Collection<BeaconIdentifier> targetedBeacons) {
LOGGER.i("startScanning()");
if (!beaconManager.isBound(this)) {
this.targetedRegions = getRegionsForTargetedBeacons(targetedBeacons);
beaconManager.bind(this);
}
else {
LOGGER.i("Scanning already started.");
}
}
#NonNull
private List<Region> getRegionsForTargetedBeacons(Collection<BeaconIdentifier> beaconIdentifiers) {
List<Region> regions = new ArrayList<>();
for (BeaconIdentifier beaconIdentifier : beaconIdentifiers) {
try {
Region region = new Region(beaconIdentifier.getRegionId(), Identifier.parse(beaconIdentifier.getUuid()),
Identifier.parse(String.valueOf(beaconIdentifier.getMajor())),
Identifier.parse(String.valueOf(beaconIdentifier.getMinor())));
regions.add(region);
}
catch (Exception e) {
LOGGER.e("Caught exception.", e);
LOGGER.w("Failed to create region for beaconIdentifier=%s", beaconIdentifier.getCallParamRepresentation());
}
}
return regions;
}
public void stopScanning() {
LOGGER.i("stopScanning()");
if (beaconManager.isBound(this)) {
for (Region region : targetedRegions) {
try {
beaconManager.stopMonitoringBeaconsInRegion(region);
}
catch (RemoteException e) {
LOGGER.e("Caught exception", e);
}
}
beaconManager.unbind(this);
}
}
#Override
public void didEnterRegion(Region region) {
LOGGER.v("didEnterRegion(region=%s)", region);
beaconScanningListener.onEnterRegion(region.getUniqueId());
try {
beaconManager.startRangingBeaconsInRegion(region);
}
catch (RemoteException e) {
LOGGER.e("Caught Exception", e);
}
}
#Override
public void didExitRegion(Region region) {
LOGGER.v("didExitRegion(region=%s)", region);
beaconScanningListener.onExitRegion(region.getUniqueId());
try {
beaconManager.stopRangingBeaconsInRegion(region);
}
catch (RemoteException e) {
LOGGER.e("Error", e);
}
}
#Override
public void didDetermineStateForRegion(int state, Region region) {
LOGGER.v("didDetermineStateForRegion(state=%s, region=%s)", state, region);
}
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
LOGGER.v("didRangeBeaconsInRegion(size=%s, region=%s, regionUniqueId=%s)", beacons.size(), region,
region.getUniqueId());
if (beacons.size() > 0) {
beaconScanningListener.onBeaconsInRange(beaconIdentifierFactory.from(beacons, region.getUniqueId()));
}
}
#Override
public void onBeaconServiceConnect() {
LOGGER.v("onBeaconServiceConnect()");
beaconManager.addRangeNotifier(this);
beaconManager.addMonitorNotifier(this);
for (Region region : targetedRegions) {
try {
beaconManager.startMonitoringBeaconsInRegion(region);
}
catch (RemoteException e) {
LOGGER.e("Caught exception", e);
}
}
}
#Override
public Context getApplicationContext() {
return applicationContext;
}
#Override
public void unbindService(ServiceConnection serviceConnection) {
LOGGER.v("unbindService()");
applicationContext.unbindService(serviceConnection);
}
#Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
LOGGER.v("bindService()");
return applicationContext.bindService(intent, serviceConnection, i);
}
}
public class BeaconIdentifier {
private final String uuid;
private final int major;
private final int minor;
private String regionId;
public BeaconIdentifier(String uuid, int major, int minor) {
this.uuid = uuid;
this.major = major;
this.minor = minor;
}
public int getMinor() {
return minor;
}
public int getMajor() {
return major;
}
public String getUuid() {
return uuid;
}
public String getCallParamRepresentation() {
return (uuid + "_" + major + "_" + minor).toUpperCase();
}
public String getRegionId() {
return regionId;
}
public void setRegionId(String regionId) {
this.regionId = regionId;
}
#Override
public boolean equals(Object o) {
if (o != null) {
if (o instanceof BeaconIdentifier) {
BeaconIdentifier other = (BeaconIdentifier) o;
return this == other || (this.uuid.equalsIgnoreCase(other.uuid)
&& this.major == other.major && this.minor == other.minor);
}
else {
return false;
}
}
else {
return false;
}
}
#Override
public int hashCode() {
int result = 17;
result = 31 * result + (uuid != null ? uuid.toUpperCase().hashCode() : 0);
result = 31 * result + major;
result = 31 * result + minor;
return result;
}
#Override
public String toString() {
return "BeaconIdentifier{" +
"uuid='" + uuid + '\'' +
", major=" + major +
", minor=" + minor +
", regionId='" + regionId + '\'' +
'}';
}
}
The BeaconDataProvider is used as a single instance per application; It is instantiated by Dagger 2 when the Android Application is created. It has #ApplicationScope lifecycle.
The beacon scanning is first started`in foreground mode from an Android IntentService:
beaconDataProvider.setForegroundMode();
beaconDataProvider.startScanning(targetedBeacons);
Once the device enters the region and the beacon is detected, beacon scanning is switched to background mode:
beaconDataProvider.setBackgroundMode();
At first I thought there was something wrong with the Onyx Beacons I was using, but I could reproduce the same issue with the Kontact IO Beacons.
Do you have any suggestions?
Am I miss-using the AltBeacon Android Library?
Thanks,
Alin
The fundamental cause of a call to didExitRegion() is the fact that no BLE beacon advertisement packets matching the region were received by the Android bluetooth stack in the previous 10 seconds. (Note: This value is configurable with BeaconManager.setRegionExitPeriod(...).)
There are several things that could be causing these spurious didExitRegion() calls:
A beacon is not advertising frequently enough.
A beacon is advertising with a very low radio signal.
There is too much radio noise in the vicinity for reliable detections.
The receiving device has a poor bluetooth antenna design causing weaker signals to not get detected.
The receiving device is too far away to reliably detect the beacon.
The foregroundScanPeriod or backgroundScanPeriod is set too short to get a guaranteed detection
Given the setup you've described, I suspect that when you have the beacon transmitting at 1Hz, some combination of 1-4 is causing the problem. You will have to experiment with each of these variables to see if you can isolate the problem to one predominant issue. But again, more than one may be at play at the same time.
Understand that even under good conditions only 80-90 percent of beacons packets transmitted over the air are received by a typical Android device. Because of this, if you have a setup where only 1-5 beacon packets are typically received in a 10 second period, you'll still sometimes get exit events if you get unlucky and a few packets in a row get corrupted by radio noise. There is no way to guarantee this won't happen. You can just make it statistically more unlikely by setting up your system so under nominal conditions it receives as many packets as possible in a 10 second period, so this becomes more unlikely.
Increasing the advertising rate is the easiest way to fix this, because it gives you more statistical chances of getting packets detected in any 10 second period. But as you have seen, there is a tradeoff in terms of battery life.
If you want do preserve battery life but don't care about the time it takes to get a didExitRegion callback, then you may want to modify BeaconManager.setRegionExitPeriod(...) to 30,000 milliseconds or more until the problem goes away.
The above discussion is specific to the configuration of the Android Beacon Library, the same theoretical ideas apply to any beacon detection framework including iOS Core Location. You sometimes see spurious exit events with that framework as well.
I think the problem is here:
beaconManager.setForegroundScanPeriod(5000L);
beaconManager.setForegroundBetweenScanPeriod(10000L);
You should generally set the scanPeriod to 5100 ms or more, because beacons that advertise have a slight chance of being missed if their transmission is always on the boundary of when you start and stop scanning.
So try:
beaconManager.setForegroundScanPeriod(5100L);
beaconManager.setForegroundBetweenScanPeriod(10000L);
Hope it helps. Let me know if works.
As a workaround to this issue, I have implemented some extra logic to consider a didExitRegion() event only if the corresponding didEnterRegion() is not called in a certain time interval (5 minutes in my case, but this can be adjusted).

BLE Advertisement in Android

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:
Devices with Android pre-5.0 - LE Advertisement not supported
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).
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.
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.
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.
You only need to add this code: #TargetApi(Build.VERSION_CODES.M) over your method

Android Studio: Can't see logs or system prints

I have simple application created by Android studio wizard.
Here is the class of the only Activity created by Android studio wizard
package test.com.myapplication;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("========> PRINT");
Log.d("=====>", "PRINT");
Log.i("=====>", "PRINT");
Log.e("=====>", "PRINT");
Log.v("=====>", "PRINT");
}
#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);
}
}
Application is running successfully on Note II.
Log level "verbose"
No filters.
Issue: can't see prints visible for filter "===>" or "PRINT".
"Enable ADB integration" does not change the described.
Studio version 1.2.1.1 running on mac os x.
UPDATE:
adb start-server
* daemon not running. starting it now on port 5037 *
cannot bind 'tcp:5037'
ADB server didn't ACK
* failed to start daemon *
Sometimes ADB Logcat stops working, and clicking on "Restart" in "Android" tab will force it to work again
Also sometimes just restarting your mobile device will help, or the computer you are using
I re-install the app until it works (max 3 times).

Can't connect socket io on Android with server nodejs

I follow code at page: http://socket.io/blog/native-socket-io-and-android/
and download, run successfully project https://github.com/nkzawa/socket.io-android-chat.
And I want to connect socket io with my node server
Code at: server nodejs version of socket io "version": "1.3.5",
var socketIO = require('socket.io'),
http = require('http'),
port = process.env.PORT || 8080,
ip = process.env.IP || '192.168.0.105', //My IP address. I try to "127.0.0.1" but it the same => don't run
server = http.createServer().listen(port, ip, function() {
console.log("IP = " , ip);
console.log("start socket successfully");
});
io = socketIO.listen(server);
//io.set('match origin protocol', true);
io.set('origins', ':');
var run = function(socket){
socket.on("message", function(value) {
console.log(value);
});
socket.on("user-join", function(value) {
console.log(value + "user-join");
socket.broadcast.emit("new-users", value);
});
}
io.sockets.on('connection', run);
Code at Android:
package com.example.phamhuu.chatnodejs;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import java.net.URISyntaxException;
public class MainActivity extends ActionBarActivity {
private Socket mSocket;
{
try {
IO.Options options = new IO.Options();
options.port = 8080;
mSocket = IO.socket("http://192.168.0.105:8080");
//mSocket = IO.socket("http://chat.socket.io");
} catch (URISyntaxException e) {
Log.e("abc", "index=" + e);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSocket.connect();
Log.e("result socket connect", String.valueOf(mSocket.connected()));
mSocket.emit("message", "Send message to server.");
}
#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);
}
}
I make sure add 'android.permission.INTERNET'
I try it on real device (My PC and my device the same wifi )but socket can't connect to server at address: 192.168.0.105 port: 8080
Can you help me?
Thanks very much.
Not really an answer to the question, but if you want to create a chat with Node.JS which works for also android clients, you can take a look at the alternative: JXM (on github) - messaging backend for JXcore (open sourced fork of Node.JS).
The problem you describe here probably will not be relevant any more.
There are practically ready samples to be used as they are (server part; clients: browsers, android, node).
I've wrote my few cents on this subject here: Simple Node.js chat program NOT using socket.io

NFC Android App acting differently on different phones

I have currently been testing some examples being found on the internet on sending NDEF messages through the NFC on my android phone.
I have three phones that I tested the phone with: Samsung Galaxy Nexus (Android 4.4.4), S3 (Android 4.4.2) and S4 (Android 4.4.4).
The app works perfect the way I wanted it to on the GN (it sends the message), however on the S3 and the S4 it sends the package name of the app instead of the message.
Can anybody help me with this? Does anyone know why or how to fix this? I am pretty new to Android dev and don't fully understand why it is doing this.
Code:
package tapit.cbstech.com.tap_it_3;
import android.app.Activity;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
public class main extends Activity implements CreateNdefMessageCallback {
NfcAdapter mNfcAdapter;
TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textView);
// Check for available NFC Adapter
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
mNfcAdapter.setNdefPushMessageCallback(this, this);
}
#Override
public NdefMessage createNdefMessage(NfcEvent event) {
String text = ("abcdefghi");
NdefMessage msg = new NdefMessage(
new NdefRecord[] { NdefRecord.createMime("text/plain", text.getBytes()),
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//NdefRecord.createApplicationRecord("hello test")
});
return msg;
}
#Override
public void onResume() {
super.onResume();
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
#Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent) {
textView = (TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage msg = (NdefMessage) rawMsgs[0];
textView.setText(new String(msg.getRecords()[0].getPayload()));
}
}
On the GNexus I get the "abcdefghi" but on the S3 and S4 I get "tapit.cbstech.com.tap_it_3"
Any help is appreciated! Thanks in advance!
Edit: Tested on a friends S3 and does the same (sending the package name) and tested on another friends nexus 5 (running Android L) and it worked sending the "abcdefghi" message.

Categories

Resources