Is the new Altbeacon Lib. v2.16.2 supporting Android "O" Scannable API? - altbeacon

In Android API level 26, "setScannable" is added.
"setScannable" Added in API level 26
public AdvertisingSetParameters.Builder setScannable (boolean scannable)
Set whether the advertisement type should be scannable. Legacy advertisements can be both connectable and scannable. Non-legacy advertisements can be only scannable or only connectable.
I am creating a beacon and want to set it non-scannable mode.
Just wondering if the latest Altbeacon Lib. v2.16.2 support this setting? If not, is there a way to use Android API and Altbeacon Lib. together to set a beacon's advertising parameters?
Thanks!
Tried Altbeacon Lib. v2.15.2, it seems that Android API level 26 is not support, which means that "setScannable" is not available.
String id1 = "3b710c27-acf7-4225-8753-4aca354f5bec"; // UUID
String id2 = "1";
String id3 = "2";
Beacon beacon = new Beacon.Builder()
.setId1(id1)
.setId2(id2)
.setId3(id3)
.setManufacturer(0x01F1)
.setTxPower(iTxPower)
.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);
...
I would hope Altbeacon Lib. v2.16.2 could support Android API Level 26 so that "setScannable" is supported.

There is no such configuration ability in the 2.16.2 version of the library. It is logged as a feature request here:
https://github.com/AltBeacon/android-beacon-library/issues/813
This would not be difficult to add if you would like to work on that feature request. Please comment on that linked page above, if so, and I can give you guidance on what to do.

Related

Flutter : IOS to IOS Broadcast Beacon not working

I'm currently building an app that turns my device into a Beacon while simultaneously scanning for other Beacons.
So I can keep track of beacons that I had come in contact with.
Problem
Current I've tested this code in the following Scenarios:
Android TO Android - Broadcasting & Scanning - Working well
Android To IOS - BroadCasting & Scanning Both ways - Working well
IOS to IOS - Not Working (When I broadcast UUID from IOS Device, I can see UUID in Android device but I can't see UUID in any IOS device.)
I installed this piece of code in 4 devices (2 Android & 2 IOS). Now all 4 devices are broadcasting different UUID's and at the same time listening.
In Android Devices, I see 1 UUID of another Android Device and 2 UUID's of IOS Devices
In IOS Devices, I see 2 Android UUID's but I cannot see another IOS Device UUID.
This is very strange, and I need help to solve this, please!
I've currently implemented 2 packages to achieve this functionality :
(1) For broadcast
beacon_broadcast: https://pub.dev/packages/beacon_broadcast
version : 0.2.1
(2) For scan other beacons
flutter_blue: https://pub.dev/packages/flutter_blue
version : 0.6.3+1
These are some glimpse of my code
(1) For Broadcasting
String UUID = 'DYNAMIC_UUID_FOR_EACH_DEVICE';
static const MAJOR_ID = 1;
static const MINOR_ID = 30;
static const TRANSMISSION_POWER = -59;
static const IDENTIFIER = 'com.example.myDeviceRegion';
static const LAYOUT = 'm:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24';
static const MANUFACTURER_ID = 0x004c;
BeaconBroadcast beaconBroadcast = BeaconBroadcast();
beaconBroadcast
.setUUID(UUID)
.setMajorId(MAJOR_ID)
.setMinorId(MINOR_ID)
.setTransmissionPower(TRANSMISSION_POWER)
.setIdentifier(IDENTIFIER)
.setLayout(LAYOUT)
.setManufacturerId(MANUFACTURER_ID);
.start();
(2) For Scanning
FlutterBlue flutterBlue = FlutterBlue.instance;
flutterBlue.startScan(timeout: Duration(seconds: 30));
flutterBlue.scanResults.listen((List<ScanResult> results) {
print('scanningListen...');
for (ScanResult result in results) {
result.advertisementData.manufacturerData.forEach((item, hexcodeAsArray) => {
print("calculated UUID String : " + calculateHexFromArray(v));
_addToScanResult(calculateHexFromArray(v));
});
}
}
String calculateHexFromArray(decimalArray) {
String uuid = '';
decimalArray.forEach((i) => {uuid += i.toRadixString(16).padLeft(2, '0')});
String uuid1 = uuid.substring(4, uuid.length - 12);
return uuid1.toUpperCase();
}
Unfortunately, you cannot use FlutterBlue to detect iBeacon packets on iOS.
Why? FlutterBlue uses raw bluetooth scanning to detect beacons, which under the hood means using the native CoreBluetooth scanning APIs on iOS. Apple blocks CoreBluetooth APIs from reading the raw bytes of any bluetooth advertisement decodable as an iBeacon advertisement. While this may sound crazy, it is likely motivated by misguided security concerns by Apple. Read more in my blog post here: CoreBluetooth Doesn't Let You See iBeacons
Two options to fix this:
Switch to using the AltBeacon format. Simply change LAYOUT = 'm:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25'; and MANUFACTURER_ID = 0x0118;
This will work, but has the disadvantage of the advertisement only being detectable on iOS in the foreground.
Switch to using a different detection library on iOS that uses CoreLocation (the only API allowed to detect iBeacon on iOS) instead of CoreBluetooth. That means giving up FlutterBlue in favor of FlutterBeacon or similar.

GetDescriptor() null value / 128-bit UUID descriptor?

I'm writing my code using Xamarin. I'm developing my IOS app which allows me to read the BLE devices, Services, characteristic value and activation of the notification.
My BLE beacon have one custom Services that contain two custom characteristics and both have the notification implemented using CCCD.
My ble devices work correctly I test it with BLE scanner app and it working well without any problem.
I can read value and I can active the notification for both characteristic. See picture here.
The app that I wrote using xamarin work correctly (reading services, characteristic value....) the only problem that didn't work is the activation of the notification. Here's a portion of the code :
public UUID Charac_UUID0 = UUID.FromString("0000beef-1212-efde-1523-785fef13d123");
public UUID Charac_UUID = UUID.FromString("0000b1e0-1212-efde-1523-785fef13d123") ;
public UUID Descr_UUID = UUID.FromString("00002902-1212-efde-1523-785fef13d123");
protected BluetoothGattCharacteristic _charac;
....
....
this._charac = App.Current.State.SelectedService.GetCharacteristic(Charac_UUID0);
BluetoothLEManager.Current.ConnectedDevices[App.Current.State.SelectedDevice].SetCharacteristicNotification(_charac, true);
BluetoothGattDescriptor descriptor = _charac.GetDescriptor(Descr_UUID0);
descriptor.SetValue(BluetoothGattDescriptor.EnableNotificationValue.ToArray());
BluetoothLEManager.Current.ConnectedDevices[App.Current.State.SelectedDevice].WriteDescriptor(descriptor);
The code always give me an error at descriptor.SetValue and it indicate me that the descriptor is NULL meaning that _charac.GetDescriptor didn't return any value.
I suspect the Descriptor UUID value (Descr_UUID) is not correct. I don't know excatly how can I determine the Descr_UUID but I saw many example in the internet of people replacing the custom UUID of the caracteristic by 2902 which give me in my case a 128 descriptor UUID equal to 00002902-1212-efde-1523-785fef13d123.
But there is a problem here. The descriptor UUID for both characteristic will be the same because the base UUID is the same for both characteristic?
Any solution?
3 years later im sure you figured it out but, 2902 is the 16 bit value for a Client Characteristic Configuration Descriptor, and I believe it should also be inflated using the "BASE UUID" not just whatever your characteristic descriptor uses. See this: answer
This will convert your 16 (or 32) bit uuids to full 128 bit uuids using the BASE UUID:
public static UUID ConvertUuid(uint uuid)
{
const long msbMask = 0x0000000000001000;
const ulong lsb = 0x800000805f9b34fb;
var msb = msbMask | ((ulong)(uuid & uint.MaxValue) << 32);
return new UUID((long)msb, unchecked((long)lsb));
}

AudioContext.createMediaStreamSource alternative for iOS?

I've developed an app using Cordova and the Web Audio API, that allows the user to plug in headphones, press the phone against their heart, and hear their own heartbeat.
It does this by using audio filter nodes.
//Setup userMedia
context = new (window.AudioContext||window.webkitAudioContext);
navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
navigator.getUserMedia(
{audio:true},
userMediaSuccess,
function(e) {
alert("error2 " + e.message);
});
function userMediaSuccess(stream)
{
//set microphone as input
input = context.createMediaStreamSource(stream);
//amplify the incoming sounds
volume = context.createGain();
volume.gain.value = 10;
//filter out sounds below 25Hz
lowPass = context.createBiquadFilter();
lowPass.type = 'lowpass';
lowPass.frequency.value = 25;
//filter out sounds above 425Hz
highPass = context.createBiquadFilter();
highPass.type = 'highpass';
highPass.frequency.value = 425;
//apply the filters and amplification to microphone input
input.connect(lowPass);
input.connect(highPass);
input.connect(volume);
//send the result of these filters to the phones speakers
highPass.connect(context.destination);
lowPass.connect(context.destination);
volume.connect(context.destination);
}
It runs fine when I deploy to Android, but it seems most of these features aren't available on iOS mobile browsers.
I managed to make getUserMedia function using the iosRTC plugin, but createMediaStreamSource is still "not a function."
So, I'm looking for an alternative to the Web Audio API that can filter out frequencies, or if there are any plugins I could use, that would be perfect.
There's no way to do this on ios web. You'd need a native app, since Apple doesn't support audio input in safari.
Did you try to use
document.addEventListener('deviceready', function () {
// Just for iOS devices.
if (window.device.platform === 'iOS') {
cordova.plugins.iosrtc.registerGlobals();
}
});
You asked this question quite a while ago, but sadly createMediaStreamSource is still not supported in Safari Mobile (will it ever be?).
As previously said, a plugin is the only way to achieve this, and there is actually a Cordova/Phonegap plugin that does exactly that. cordova-plugin-audioinput gives you access to the sound from the microphone using either the Web Audio API or by callbacks that delivers raw audio data chunks, and it supports iOS as well as Android.
Since I don't want to post the same answer twice, I'll instead point you to the following answer here on stackoverflow, where you'll also find a code example: https://stackoverflow.com/a/38464815/6609803
I'm the creator of the plugin and any feedback is appreciated.
Good news, full support for ios safari
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createMediaStreamSource

WP7.1 backward compatibility

I have installed mango SDK in my machine and I want to create an application which runs on both Windows Phone OS 7.0 and Windows Phone OS 7.5 devices. Also I need to implement many of the mango features in the same application. Is it possible ? if yes please tell me how to do the version checking, because based on the version we need to implement the mango features.
You'll have to maintain two different versions. You can't compile one XAP that supports both versions at the same time.
The Mango APIs are only available when compiling with the 7.1 SDK. And as such, you can't do in-line checking in the code.
But it's rather pointless, as there's almost no users left that haven't upgraded to Mango, and all new phones ship with Mango.
Now days all the Windows phone are shipping with the Wp7.5 mango version also Older devices are getting mango updates, so it looks pointless in targeting only few WP7.0 running phones.
But if you dont need to anything SDK related api access then you can do this bifurcation.
However You can find the solution to the finding the OS version is in [my answer of same kind of question here.]1
You can do this using the Type class and reflection, although the process will not be easy. Create a Windows Phone 7.0 application, and then create a MangoExtensions class which implements the mango specific features:
http://www.sharpgis.net/post/2011/08/21/Windows-Phone-Adding-Mango-features-to-a-70-WinPhone-App.aspx
bool IsMangoDevice = (Environment.OSVersion.Version >= new Version(7, 1));
if (IsMangoDevice)
{
Type t = Type.GetType("Microsoft.Phone.Shell.StandardTileData, Microsoft.Phone");
//get the constructor for the StandardTileData and create a new instance of it
var newTileData = t.GetConstructor(new Type[] { }).Invoke(null);
//Get the setter method for the title property
var setMethod = newTileData.GetType().GetProperty("Title").GetSetMethod();
//Set the tile title
setMethod.Invoke(newTileData, new object[] { "This is my new tile" });
//Get the create method for the shell tiles
Type shellTileType = Type.GetType("Microsoft.Phone.Shell.ShellTile, Microsoft.Phone");
var createMethod = shellTileType.GetMethod("Create");
//Create the tile, with the uri and tile data
Uri uri = new new Uri("/MainPage.xaml?Test=This_Came_From_A_Secondary_Tile", UriKind.Relative)
createMethod.Invoke(null, new object[] { uri, newTileData});
}

MonoTouch Way to get Own phone number and Sim Id(SSID)?

Im stuck to get own phone number and Sim ID (SSID) using Monotouch
I tryed:
var v = NSUserDefaults.StandardUserDefaults.ValueForKey((NSString)#"SBFormattedPhoneNumber");
var t = NSUserDefaults.StandardUserDefaults.ValueForKey((NSString)#"ICCID");
new UIAlertView("Ur phone Number",""+v.ToString(),null,"Ok",null).Show();
new UIAlertView("Ur ICCID",""+t.ToString(),null,"Ok",null).Show();
and all other ValueFor***
it always return null or " "
Tried on iphone 3g. Please help.
Apple does not want to to access this information as it can easily be misused. Any application doing so is likely to be rejected from the AppStore. See the comment (with more than 30 up votes) from this answer.
Also note that your code above does not read from the SIM - it reads from the iTunes registration data, which does not have to be set to any value (i.e. you can't trust it).

Resources