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)
Related
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.
For weeks I was struggling to create an app that connected to an arduino device over Bluetooth Low Energy (Bluetooth LE) and I finally got it working today. I am sharing the resources I found so that if someone else is struggling they can learn from my experience. The information I am sharing is for bluetooth LE only. If your device is using bluetooth classic this will not work as they are not compatible.
For anyone who is new to this here is some terms you will need to know. You need to use them in your program to communicate with bluetooth LE.
UART: universal asynchronous receiver-transmitter. This is the protocol that is used to send data to a device via bluetooth LE and to receive data.
GATT: Generic Attribute Profile. This defines how data will be transferred back and forth using Services and Characteristics.
This was an excellent tutorial on how to create the app:
https://www.jenx.si/2020/08/13/bluetooth-low-energy-uart-service-with-xamarin-forms/
This app will scan for BLE devices, connect to them, send data to the device, and receive data from the device. My app is for android, but it looks like the app from this tutorial will work for IOS as well.
Once I created the app I searched for the UART UUID's of my device (an Adafruit Feather Bluefruit LE). Here is the page where I found the codes for my device:
https://learn.adafruit.com/adafruit-feather-m0-bluefruit-le/uart-service
I found the Send and Receive UUID's from the Nordic Semiconductor website:
https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v14.0.0%2Fble_sdk_app_nus_eval.html
Then in the GattIdentifiers page I replaced the generic UUID's that were entered with the UUID's for my device. Here is what my GattIdentifiers page looks like with my UUID's.
public class GattIdentifiers
{
public static Guid UartGattServiceId = Guid.Parse("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
public static Guid UartGattCharacteristicReceiveId = Guid.Parse("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");
public static Guid UartGattCharacteristicSendId = Guid.Parse("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
public static Guid SpecialNotificationDescriptorId = Guid.Parse("00002902-0000-1000-8000-00805f9b34fb");
}
A note on this is to make sure you put the right UUID's with the send and receive characteristics defined in the file. I had them reversed at first which was giving me "null" results. So if they are not working try reversing them.
I hope this helps!
I am making an Android app to receive data from Arduino(NRF24L01).
Arduino(NRF24L01) can send data only with Bluetooth device name.
So I get the value by putting the analog value in the BLEname.
Like this YouTube video.
https://youtu.be/F9yMTdcd33w?t=240
However, the Android application does not come back with the information of a device once it is already connected.
ex)
BLE Device name : "A=i" //(i=analog.value;)
first BLE SCAN -> find -> BLE Device name : "A=12"
I change i,(i=14;)
Second BLE SCAN -> find -> BLE Device name : "A=12"
why????????? i want "A=14"!!
Therefore, I would like to create an application that will continue to scan and retrieve device name information.
Is there any example I can refer to?
P.S I am sorry that I have not translated the translator and the context is not smooth.
You can refer this example for BLE scanning and connection or you can use customize as you want.
BleConnect
I am using Tizen SDK for Wearable from samsung-gear site in order to communicate a provider android application with Samsung Gear 2 device. I am able to send notifications to gear and once I run the consumer application on gear 2, I am able to transfer data between the watch and my Android phone as well.
What I am trying to do is to check within the Android application if the phone is paired with Gear 2. Something as simple as creating a communication object using the accessory service and calling a method like isPaired()?:
CommunicationObject commObject = new CommunicationObject(Communication parameters);
// I am assuming some connection call like commObject.connect() should be invoked first
// where I can check for it's result afterwards such as
if(commObject.isPaired())
{
// do something
}
I think SDK examples such as consumer/provider application they provide on their site already assume that the device is paired, hence they show how to transfer data between phone and the gear watch. Yet I am seeking something as simple as asking the phone if it's paired with a gear device, which should be the prerequisite for transferring the data, which is done automatically by Samsung Gear Manager I believe right now.
Note: For the case of example provider/consumer applications, one can just check if any connection is available using the code in them. But the data transfer connection enabled only when I manually start the consumer app from the gear device, otherwise it acts like gear device is not paired even though it is.
I believe this is not the most popular topic these days so I will post what I came up with as an answer although I doubt anyone will need it, without being perfect, it's the closest way I could get to my goal using the available documentation.
I should also mention that this slide helped me stay on track as well.
In my solution, there must be an active 2-way connection between the gear widget(consumer/.wgt) and the host side application(provider/.apk) as in the example application provided by Samsung(Hello Accessory) at all times, at least during the time where I wanted to check for the pairing condition. The documentation refers to it as:
Hello Gear is a simple application that consists of:
Host-side application(provider) : HelloAccessoryProvider.apk
Wearable-side Application(consumer) : HelloAccessoryConsumer.wgt (Web app)
See that both sides have some xml configuration and Android requires specific permissions which are explained in detail in Hello Gear documentation.
This 2 way communication is provided by the Samsung Accessory Framework on the network layer(through Samsung Accessory Protocol, SAP) given that both sides implement the same Accessory Service Profile, again, configured via the xml files on both ends(service name, channel id etc.).
Android side implements the protocol as a service, extending the SAAgent abstract class. Then the widget on gear side application(.wgt) can invoke the SAAgent callbacks and provider/consumer communication is handled through SASocket objects claimed on both ends over the predefined channel in the xml configuration files.
Please note that this communication has to be initialized on both ends, in my case I had to open the widget application once on Gear(I believe there should be a way to start the gear widget via an intent or notification, somehow, but I could not find yet) after the Android application has started, here started means that SAAgent service is up and bound to an Activity, being eligible to receive callbacks and send state messages to the rest of the application via broadcasts. Such as the number of active connections, or any data transmission between the gear socket and Android application can be done this way.
Note that if you don't have to transfer data between the gear widget and the Android application, you may just be OK with the notifications. The only requirement to send notifications to the Gear from Android applications seems to be that the Gear is paired with your phone and connected via Bluetooth. Then you can just send an intent as explained in more detail here in Section 6. All you need should be the permission:
com.samsung.wmanager.ENABLE_NOTIFICATION
and some metadata definition in your ApplicationManifest.xml file explained in the same section.
<meta-data
android:name="master_app_packagename"
android:value="com.example.gearMasterApp"/>
<meta-data
android:name="app_notification_maxbyte"
android:value="300 "/>
And here is the sample code for intent, in order to send notifications to the Gear:
public static final String ALERT_NOTIFICATION =
“com.samsung.accessory.intent.action.ALERT_NOTIFICATION_ITEM”;
public static final int NOTIFICATION_SOURCE_API_SECOND = 3;
Bitmap bitmapImg;
// Put data to Intent
Intent myIntent = new Intent(ALERT_NOTIFICATION);
myIntent.putExtra("NOTIFICATION_PACKAGE_NAME", “com.example.gearApp”);
myIntent.putExtra("NOTIFICATION_VERSION", NOTIFICATION_SOURCE_API_SECOND);
myIntent.putExtra("NOTIFICATION_TIME", System.currentTimeMillis(););
myIntent.putExtra("NOTIFICATION_MAIN_TEXT", “Title Text”);
myIntent.putExtra("NOTIFICATION_TEXT_MESSAGE", ”Body text);
byte [] byteArray = convertResizeBitmapToByte(bitmapImg);
myIntent.putExtra("NOTIFICATION_APP_ICON", byteArray);
myIntent.putExtra("NOTIFICATION_LAUNCH_INTENT", “com.example.gearMasterApp”);
myIntent.putExtra("NOTIFICATION_LAUNCH_TOACC_INTENT", “com.example.gearSideApp”);
sendBroadcast(myIntent);
public byte[] convertResizeBitmapToByte(Bitmap bitmap){
Bitmap scBitmap = Bitmap.createScaledBitmap(bitmap, 75, 75, false);
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
scBitmap.compress(Bitmap.CompressFormat.PNG, 50, byteArrayStream);
return byteArrayStream.toByteArray();
}
Once the notification is read on the gear side, you can receive the intent action along with some optional parameters:
Intent Action :
"com.samsung.accessory.intent.action.UPDATE_NOTIFICATION_ITEM"
This could be another approach to check active communication with the Gear and your phone, but there is no guarantee that the notification will be read and my case did require to keep the Gear communication optional in order to allow the Android application continue it's tasks even though there is no active connection with the Gear.
About the original question, where I asked for a way to detect if the Gear is paired or not, I tried listing paired Bluetooth devices using getBondedDevices() method of Android's BluetoothAdapter but it shows that your Gear is paired even when your Gear is turned off, which was not enough for my needs and I did not find it logical. It's true though once your device is turned back on.
I'm happy with the above solution since it was enough for my needs, therefore I will accept my own answer.
Can anyone give me an idea on how to read the values from the OBD II Bluetooth adapter in an android application.
I want to start with scanning for the bluetooth devices from my android application, then after bluetooth device is found, how would I interact with it and get the values from it?
You should start by reading this http://developer.android.com/guide/topics/wireless/bluetooth.html
it contains step by step procedure .
add required permissions,
make a bt adapter,
then find paired/unpaired devices
I used the BluetoothChat Application and was able to get some basic communications, I am not moving into data logging. You can use this application to have a sort of instant messenger conversation with your ECM.
What particular dongle are you using?
Do you know what protocols are in use within your vehicle?
Download the BluetoothChat sample application -
They will have already handled the intricacies of the connection for you, you will have to change the UUID in order to connect with your device - 00001101-0000-1000-8000-00805F9B34FB
Read up on your particular dongle, some require the return character to be sentat the end of every command "\r"
This should get you started!
Once you have made the Bluetooth connection using the android bluetooth api, use the transport to send and receive data via the Bluetooth channel.
This is new developer resource document:
https://developer.android.com/guide/topics/connectivity/bluetooth.html
The general workflow of the application functionality should go like this:
1) connect to the OBDII adapter through Bluetooth;
2) initialize OBDII adapter with AT commands;
3) continuously get data from the vehicle through issuing the corresponding PID codes.
This article also may be helpful.
http://blog.lemberg.co.uk/how-guide-obdii-reader-app-development