I'm trying to understand: is there a way to check if Android device supports DolbyDigital (AC3).
I found a broadcast action ACTION_HDMI_AUDIO_PLUG that indicates wether HDMI connected or not. Also it sends an array of all the supported encodings via the value EXTRA_ENCODINGS. But, as I understand, those are the values that the TV supports, not the Android device itself.
Related
The project I am currently working on involves a weight scale that has built-in BLE and my smartphone. The scale connects to the smartphone via BLE to send the current weight data to its app (I assume this is prioritized.) Although I can't figure out how to get the correct UUID to communicate with the scale in my own Android App as it doesn't seem to be using the standard GATT Services. The devices seem to use 0x2901, 0x2902...0x290X
Scale model: HNY200 (Color Black)
Link to scale: https://www.healthometernuyu.com/nuyu-products/scales/wireless-scale/HNY200KD.html
After using a BLE scanner on my phone I was able to determine the BLE Name for the device (Much like the SSID in a network) and the MAC Address. However, it also shows a long list of CUSTOM SERVICE and CUSTOM CHARACTERISTIC options each with Descriptors and their properties such as read and write. I would assume the data im searching for (The weight value) would come packaged in a CUSTOM CHARACTERISTIC with the properties including READ. After analyzing each individual one the value is either the exact same hexadecimal number each time or has no value at all. The ones with no value instead have "OTA_STATUS", "OTA_CMD", or "OTA_DATA" but does not reveal anything besides that.
BLE Scan of the device looking at the most interesting characteristics (but not all):
https://imgur.com/a/iHWDoSM
I currently dont have any code for the android app as I am just following along with the Android Developers Tutorial. However, in previous research, It seems as though I will need the correct UUID's as I might have to reverse engineer the protocol the scale is using to send prioritized data to its app. Some BLE scanners work to find the scale and some do not.
I expected one characteristic to reveal a value of the weight being displayed on the scale and instead I got very large hex values, nothing at all, or some string value such as "OTA_DATA".
I am building an Android app that scans two types of beacon using the android-beacon-library:
iBeacon type (0x4c000215)
custom beacon which beacon type code is 0x4106
I know there was an issue that fixed broken Samsung screen off scans https://github.com/AltBeacon/android-beacon-library/pull/798.
That fix was implemented into the 2.15.3 release.
Since then, during every scan with a samsung device >= Android 8.0, I don't see any of my custom beacon but I do receive other beacon types like iBeacon. So I am still using the 2.15.2 release.
Here is my custom beacon layout:
"m:0-1=4106,i:2-3,i:4-4,i:5-6,i:7-8,i:9-10,i:11-11,i:12-12,i:13-13,i:14-14,i:15-15,i:16-16,i:17-17,i:18-23,p:24-24"
I checked the code from the lib and I can see a filter that applies for samsung devices only:
if (Build.MANUFACTURER.equalsIgnoreCase("samsung")) {
// On the Samsung Galaxy Note 8.1, scans are blocked with screen off when the
// scan filter is empty (wildcard). We do a more detailed filter on Samsung only
// because it might block detections of AltBeacon packets with non-standard
// manufacturer codes. See #769 for details.
filters = new ScanFilterUtils().createScanFiltersForBeaconParsers(
mBeaconManager.getBeaconParsers());
}
If I remove this code, everything works as I expect.
Is there something I have to do so I don't need to edit the library?
Thanks.
The library uses both the BLE manufacturer ID and the beacon type code to match BLE filters when the app is in the background. For this to work, you must set these up exactly right, or the filters will not match.
Two issues here:
Your beacon type code should not include the BLE manufacturer ID. Instead of 0x4c000215 use 0x0215 (Note: 0x4c00 is the Apple BLE manufacturer ID, and will be applied separately.) If using a beacon layout string with this, you must adjust the byte offsets to account for this, so your layout starts with m:2-3=0215
For any beacon layout that will be matched with these filters, you must set the hardware assist manufacturer identifiers. By default, the library includes 0x0118 (Radius Networks for AltBeacon) and 0x0215 (Apple for iBeacon) for all other manufacturer beacon types. For any custom beacon that uses yet another manufacturer code (see list here: https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers) you must add it like this (example shown for hardware manufacturer id 0x1234):
beaconParser.setHardwareAssistManufacturerCodes(new int[]{0x1234});
Important tip: Mobile devices have a limited number of bluetooth hardware filter slots. You can help ensure you do not run out of them by:
Only register as many beacon layouts as you need. If not using the default AltBeacon layout, call beaconManager.getBeaconParsers().clear(); to remove it.
Only register the exact hardware manufacturer codes you need with each BeaconParser. If you register more than one you will use more than one filter slot.
The above APIs were designed before this Samsung restriction came into place making this a more serious issue. I am open to other ideas on how to make this API more intuitive so other folks don't run into the same problem as you did.
This question already has an answer here:
Android : Get "device name" on android tv
(1 answer)
Closed 4 years ago.
I wanna get android device name (i.e. the "name" that user can change through settings and that you can find under "Settings > About device > Device name").
Other developers recommend to get this name through bluetooth.
But on my device (Samsung Galaxy S4) this name is only updated when I enable bluetooth, so if I change the name when bluetooth is disabled : the new name won't be displayed until I enable bluetooth.
I'm wondering if there is a way to get the updated device name without enabling bluetooth?
I can think of a workaround like :
enabling bluetooth
get name
disable bluetooth
but I was wondering if a more elegant solution exists.
The device name you are talking about is also known as the bluetooth friendly name and therefore reading it through the bluetooth API is perfectly valid.
Be aware that if your app is running on a non-bluetooth device : this name don't exists.
If you read carefully the doc of the bluetooth API you will see for the setName(...) method:
... If Bluetooth state is not STATE_ON, this API will return false. After turning on Bluetooth, wait for ACTION_STATE_CHANGED with STATE_ON to get the updated value.
In other words: this behavior is not particular to your device, but it works as specified.
Your workaround is AFAIK the only way the get the updated name when name was changed while bluetooth was disabled (and unfortunately it has serious drawbacks : enabling/disabling BT is costly).
Please also note that you must wait for ACTION_STATE_CHANGED with STATE_ON to get the updated value.
I'm trying to develop an Android Wear app that can identify songs with Gracenote's GNSDK. I'm building upon their sample app.
I'm having trouble with the Wifi on the wearable device. The sample app is working in terms of a song identification attempt but misses an internet connection. (Although other apps work perfectly.)
So what happens: When the watch is in Wifi and not connected to the phone via bluetooth but solely via Wifi it works. Now connecting the phone to the watch via bluetooth the watch is supposed to connect to Wifi through the phone. And now a connection is no longer available. So identifying through the phone's internet is not working. Does anybody have a clue what can be the reason and how to troubleshoot?
If not:
Is there a way to, instead of making a full album identification via GnMic, grab only the fingerprint from the GnMusicIDStream object? And if so, how? The idea behind it is to listen to a song via GnMic on the wearable device, grab only the fingerprint and then send it to the mobile device. There, identify the song by doing an identification based on the fingerprint and send the result back on the watch.
Hope one of you has an idea how to solve the problem! Many thanks in advance! Any help is appreciated!
Best,
dmkscr
Due to limitations with accessing the internet directly from a Wear device, you must pass either raw audio bytes or a fingerprint to the handheld device via the DataItem or MessageApi. (See https://developer.android.com/training/wearables/data-layer/index.html for information on these Wear APIs.) Then, on the device you can produce a fingerprint and/or submit a MusicID query. You then need to again use the DataItem or MessageApi to pass result data back to the Wear device for display.
With either approach (passing audio bytes or a fingerprint to the handheld), you need to work with the GnMusicId class instead of GnMusicIdStream. The reason is that GnMusicIdStream automates multiple steps of workflow (capture audio, produce a fingerprint, perform a MusicID query based on the fingerprint), and doesn¹t provide hooks for performing them separately. GnMusicId is a lower level class that gives you more fine-grained control of this process.
If you choose to pass the audio data to the handheld, you can get the audio bytes on the Wear device using GnMic.getData(). Pass the audio data bytes to the handheld via DataItem or MessageApi. Then, on the handheld,
use the following methods of GnMusicId to produce a fingerprint and perform a MusicID query:
fingerprintBegin(GnFingerprintType fpType, long audioSampleRate, long audioSampleSize, long audioChannels)
fingerprintWrite(byte[] audioData, long audioDataSize)
fingerprintEnd()
fingerprintDataGet()
findAlbums(java.lang.String fingerprintData, GnFingerprintType fpType)
Optionally, if you choose to generate the fingerprint on the Wear device, do the following
Call GnMusicId.fingerprintFromSource(IGnAudioSource audioSource, GnFingerprintType fpType) to generate the fingerprint, using an instance of GnMic as the IGnAudioSource.
Get the fingerprint data via GnMusicId.fingerprintDataGet()
Pass the fingerprint data to the handheld via DataItem or MessageApi
On the handheld, call GnMusicId.findAlbums(java.lang.String fingerprintData, GnFingerprintType fpType)
I a trying to understand and modify the BLE sample von Android.com, now I can discover my sample BLE Device (HTC Fetch) and now I want to understand all that GATT and BLE stuff.
What are Characteristics and what are Profile and what are Serivces and what do they mean in the Bluetooth Low Energy World? I used HTC Dev and found a Service and a Characteristics UUID.
https://www.htcdev.com/devcenter/opensense-sdk/bluetooth-smart/htc-fetch/
But I guess what I need is the Find Me Profile, cause for the first steps I only want to get the Find Me react to a Button click.
https://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.find_me.xml
How to implement this in my App?
When I understand everything I try Power and Proximity (reading RSSI and compare with defined range).
Can some one help me understanding Bluetooth LE?
Here's a related post
How to use the profile of PROXIMITY PROFILE,IMMEDIATE ALERT SERVICE and Find Me Profile in android 4.3 BLE?
Basically you can approximate a proximity level using tx+power - rssi or distance roughly with
d = (rssi-A)/-20 (where A = rssi at one meter) or simply use rssi mapping out ranges to display You could also initially base it on just the connection range and skip rssi.
As for the FindMe, simply write the low or high alert values to make it sound when you press a button in your app. For pressing a button on the device use the UUIDs shown in the documentation.
sample code for that device is forthcoming