I've written a small test application which works as a simple chat room using Nearby.MESSAGES_API.
When I subscribe I find that I receive a number of older Messages in my MessageListener (in onFound). If I disconnect and then reconnect (eg. switch to another application) I find that all the messages come through again. Is this meant to happen?
I have changed the application to include UUIDs in my messages and keep a stash of them to check whether I have received the message, but that may not be a good idea from a memory point of view (although I could put them in a database).
I don't understand how the "session" side of Nearby Messages works.
In Google Play Services 7.8 the "sessions" are internally divided into ten minute buckets. You're not the first person to be confused by this, we're looking at options to do this differently in the future. No promises, but we recognize it's an issue.
(I work on the Nearby API)
The issue was that publishAndSubscribe is called when onConnected is called. The issue with this is that onStart attempts to reconnect so publishAndSubscribe needn't be called again.
Related
I develop the Android watch/phone application pair, where watch and phone communicate using Data API.
I need to pass the messages immediately, or with few minutes delay at most (not 30 minutes). To achieve so, I call setUrgent() on my PutDataRequest.
For the reasons I do not understand, the message still takes very long time to deliver.
The message is delivered immediately if I try to play with the stock Android Wear app changing the watch face. Also, after the first message is delivered, others seem passing immediately. However, after some longer time of inactivity (few hours) the slow delivery problem resumes.
I have updated Google Play Services to 10.2.1, I tried to use GoogleApiClient.reconnect() on every action, I have removed all threading from the connectivity listeners - no help. Even rebooting both watch and phone does not pull out the pair of the stalled communication state.
From watching the logs, seems that one side sends the message, other just does not receive it. The sending side receives own data message instead.
As the communication is bidirectional, and messages may come at any time, I need to keep the connection permanent. The sender tries to connect before sending the message, and the onConnected listener is called, yet the message is not delivered immediately.
Is anything is required to deliver messages immediately, in addition to calling of the setUrgent method? Which kind of magic the Android Wear app does that not only it has no problems of communicating, and even pushes my "forgotten" messages through?
If you needs some additional information for diagnostics, please tell me how to debug.
I'm creating mobile application for iOS and Android. The problem is when any data has changed on server, I cannot notify mobile devices.
I have found 3 solutions, each have minus and pluses.
Use push notifications. Since iOS always shows a notification to user this is not a solution at all. Also I cannot know if the notification will go to device or when it will.
For every X seconds ask server if any change exists. I don't want to do that, because creating too many HTTP connections and closing them is not a good idea I think. Also if the data is changed right after the device asks, the info change on device will occur late.
Use web socket. My application's one time usage expectation is ~2 minutes. So web socket looks like a good choice, because app will be terminated or go to background state quickly and battery consume won't be much. Also all the server side data changes will come to the device just in time. But I don't know much about web socket. Is my opinion acceptable? Also how many concurrent connections can be done by my server. Is it a question too.
Here are my all solutions.
The document would suggest assumption 1. above is incorrect.
If you read the The Notification Payload section, you'll come across this;
The aps dictionary can also contain the content-available property. The content-available property with a value of 1 lets the remote notification act as a “silent” notification. When a silent notification arrives, iOS wakes up your app in the background so that you can get new data from your server or do background information processing. Users aren’t told about the new or changed information that results from a silent notification, but they can find out about it the next time they open your app.
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
I think for the most part this depends on what your app is doing.
I would say you should use a combination of #1 and #2.
2 - At the very base level if you need information from the server you are going to have to make a request. If this information needs to be up to date then you can proceed to make a request for the information when the ViewController is loaded. If you need this information to update as the ViewController is loaded then you will need to make subsequent requests every X seconds... In addition to this if your user is interacting with this data and sending an update to the server you can check at this point if the data is up to date and alert the user as well as return the current data.
1 - Push Notifications operate off of the 'send and forget' protocol. The notification is sent and is not verified if it is received or not. This is used as a supplement to #2 and is 'nice' but should not be depended upon.
Push notification is the intended way (from both Google through Google Cloud Messaging, and Apple through Apple Push Notification Service).
Both option 2 and 3 are frowned upon as they affect battery life, and they are unnecessary as most cases scenarios can be covered by push notifications.
I am trying to write a Bluetooth LE app that accesses a Zephyr HxM Smart heart monitor. This monitor has several Bluetooth services, but I am interested in the Battery Service, Heart Rate Service, and a Custom Service that has Activity and Peak Acceleration. There is one characteristic for each, Battery Level, (BAT), Heart Rate Measurement (HR), and Custom Measurement (CUS). The HxM updates about once per sec.
I am doing this with a Galaxy S4 with Android 4.4.
It is not working as expected from the documentation.
My initial approach was to do:
Read BAT
Set notification for HR
Set notification for CUS.
Then wait for the callbacks. Setting notification means calling
BluetoothGatt.setCharacteristicNotification(Characteristic char , boolean enabled)
(One could also do notification for BAT, however, the spec does not require this to be supported. The HxM, however, does support it.)
This didn't work. I got BAT and notifications for HR, but not CUS. If I eliminated the second step, I got notifications for CUS. I couldn't get both. (This indicates I am reading the characteristics correctly, so that is [probably] not the problem.)
I found some indications there were problems with the Bluetooth stack for Android being synchronous, but no hard documentation. I then tried the following:
Read BAT.
Wait for the BAT reading, then set notification for HR,
Get HR, then disable notification for HR, and start notification for CUS.
Get CUS, then disable notification for CUS, and start notification for HR.
And continue to loop.
I got BAT and that is all.
By trial and error, I discovered the following works:
Read BAT.
Wait for the BAT reading, then set notification for HR,
Get HR, then start notification for CUS.
Get CUS, then start notification for HR.
And continue to loop.
(Same as above but without disabling notifications.) Typically, I get a HR reading, then the CUS one within 200 ms. One can assume they are from the same update. (There are no timestamps in the data, which have to be kept short to be LE.) In reality the logic is more complicated, as timers are necessary in case expected readings don't come in. This logic is FAR more complicated (and more prone to error) than my first try, which is what the documentation seems to say is what is appropriate.
I have contacted Zephyr, and they say the HxM Smart has been extensively tested on Windows, and will do simultaneous notifications as it should. There are also indications it works as it should on iOS.
There is a further problem that I do not understand. In order to get notifications, you have to enable the Characteristics locally for notification with something like:
BluetoothGattDescriptor descriptor = characteristic
.getDescriptor(UUID_CLIENT_CHARACTERISTIC_CONFIG);
resSet = descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
resWrite = mBluetoothGatt.writeDescriptor(descriptor);
This is a per characteristic setting, and should only need to be done once, when the characteristic is first received. Instead, I find I have to do it every time I set the notifications. It is possible this just causes a sufficient time delay for things to work. I don't know. This trial and error is taking a lot of my time. It would be nice to have a definitive statement of how it works.
I should note that for all calls that return a result, the result is true (success).
I apologize for the long statement. My question is:
I find no documentation that I have to do the things described. All indications are that you set up notifications and wait for the callbacks. Is there documentation, or is this a bug, or just a bad implementation? (Or is it my error?) I would especially like to know where is the documentation for what I have had to do.
Second, there is a further complication. I have tried to debug into the routines to see what the code is actually doing. When I get to BluetoothGatt.class, the source lines don't match what the debug stack says. I thus assume that the S4 is not using standard Android. I don't know where to go from there. It has been frustrating, and while I have something that appears to work, it is kludgy and almost certainly less robust.
Thanks for any help.
I had the same problem with writing multiple values in sequence, putting a Thread.sleep(200) in between them solved the problem (alas i should say). Maybe this helps as well with getting notifications.
Tested this on android 4.4.2 on Nexus 5. And no, 4.4 does not solve all problems...
Im probably very late to this but you should implement a queuing architecture for setting up your characteristics to send notifications. I used a similar technique to miznick in the post https://stackoverflow.com/a/18207869/3314615 and ended up just writing wrapper code for the native BLE stack since there are several apps i use BLE for. Ever since then I have had no issues receiving notifications. I agree with you that the Android BLE documentation should have some sort of information or warning about the BLE Stack not being synchronous. Frankly, i believe it should be re-written to handle synchronous write calls and just queue them.
First, you set Notification(i.e. setCharacteristicNotification and set Descriptor) for first characteristic.
And, Set notification for second characteristic in onDescriptorWrite callback function.
Let me summarize my problem and what I would like to achieve.
I have a SonyEricsson X10i phone with Android 2.3.3. I realized that sometimes my phone not receiving calls even if it indicating full coverage. I checked myself in the MSC/VLR and it indicates that I registered and my phone is currently active (and also there is no IMSI DETACH flag), so it should working correctly (only the last Activate Date is a little bit old ~couple of hours, which can be good as well, without SMS/Call/Location Update), as I mentioned before the phone indicates full coverage and it seems it’s on the network. But when I tried to call it I only reached the Voice Mail.
In the MSC/VLR I see No Paging Response Cause for the call, but the phone does nothing. I tried with other SW version (4.0.3 ICS), but the same result. But I not noticed similar behaviour with a different handset (same type).
Sorry for the long summary.
So because what I described above, I ‘m trying to write an application/service which will perform GSM/UMTS location update in 15-20 minutes, but I couldn’t find any kind of procedure in android.telephony.gsm.GsmCellLocation, android.telephony.TelephonyManager which will do this for me.
My other concern is the
getState()/setStateOutOfService()/ setState() procedures from ServiceState class…
It seems they not really working. For example, when I first call the getState() I always get back STATE_OUT_OF_SERVICE, which is not true…
When I’m set the state to STATE_POWER_OFF or STATE_IN_SERVICE, at least I get back that state from getState() afterwards, but the phone does nothing for that . (Not even indicate out of coverage,etc…)
Every suggestion/comment are welcome.
I have also seen this problem many times (2 phones from the same manufacturer as yours). From your question, I understand that you want to force the phone to send an MM periodic location update (which it should be sending anyway).
This is too low level, and there's nowhere you can force this directly in the programming interface. The mobility management procedure is part of the phone stack, and is specified in detail in 3GPP TS 24.008, available from www.3gpp.org. Paragraph 4.2.2 defines when the phone is supposed to send these location updates.
The only other thing would be to try by indirect means to force the phone into a condition where it would send a location update. You might be able to do that by trying to select another network manually. If it's successful, and you then manually re-select your home network, then you would trigger a location update. If it's rejected and falls back to its home network, then I think a location update would be triggered as well.
But there would also be small costs to this - battery use while it does a networks scan, and time lost while it scans and does manual network selection.
(My personal experience is that the lost calls don't happen often enough to justify this.)
we've been trying to develop an android application which uses the c2dm service of Google.
When we start the application after clearing all data, the application receives the c2dm messages just fine, but after some time (maybe 2 minutes) the messages refuse to arrive.
We also checked the code we received after pushing the c2dm messages from the server, and the code was successful (code number 200 without error).
After searching relevant posts on Stack Overflow, we came across this post:
Why do Android C2DM push messages not always arrive?
but we verified that we don't register to the c2dm service each time the application starts.
What seems to be the problem in our case?
We use android 2.2 API 8 version .
Thanks in advance,
Mark.
You should always have in mind that Google's C2DM allows a certain limit of messages/day. I'm thinking that sending a large number of messages in 2-3 minutes (a client-chat, or something like that) could be the source of your problem.
And also, have in mind that there is no guarantee whatsoever that messages will arrive. Per Google's C2DM Introduction: C2DM makes no guarantees about delivery or the order of messages. But you probably already know this.
I am thinking that if your 2-3 minute average is a rule, then probably the limitation of the messages could be the cause. Try sending fewer messages and see if the interval doesn't get larger.
"maybe 2 minutes" - you should confirm that first of all. You must clarify:
Is this issue related to this one device?
Does it happen consistently? If not, what triggers it?
Has it happened once, or does it happen every time?
Do bear in mind that C2DM messages are not guaranteed. Some will not arrive.
Also be aware that sometimes Android devices "fall off" c2dm and don't receive messages for a period of time. You will see similar effects on some networks (e.g. in my experience some C2DM messages are not delivered over wifi networks, so try 3G too).