How to cancel the initial link between devices with Google Nearby? - android

I have been looking into this for a while, and while there are threads on here that answer the question to an extent, I have not found something suitable to what I want to do.
I want to able to monitor that two devices are near one another multiple times within a 10 minute span. Nearby Messages has a detection distance setting that works perfectly for this, the setting is called DISTANCE_TYPE_EARSHOT.
The problem is that once a connection has been established between two devices, all subsequent communication occurs via the internet, for a period of 10 minutes.
Is there any way to cancel this link? This thread does mention that one could manually clear data on "Google Play Services" to un-pair devices. Is there any way to do this programmatically?
Alternatively, is there an API that would be able to do what I need?

Related

Android --design a background service for fast data acquisition

I am developing an android app for our custom healthcare hardware device that, among other things, should receive data from 5 sensos. The sensor data are sent via Bluetooth and is received using delegates that fire at 64Hz, 1000Hz, 4Hz,4Hz, and 32Hz respectively. I have successfully created an app that received the sensor data. Unfortunately, at the moment, the sensor acquisition runs on the main UI thread. This is unacceptable because it is expected that the app should keep recording the data uninterrupted throughout the day. After spending some time exploring my options, many tutorial online suggest to use a service to achieve this. However, there are many types of services (IntentServices, foreground services, background services...) to choice from and I am not sure what is the best approach. Also, my app will target android O and it seems that using background services are somehow discouraged. Would any experienced android developer gives some suggestion on how to tackle this problem? Please note that, at the moment, this is just a demo and the battery and other resource usage is not an issue.
Best approach for things that you want to achieve is to use Foreground Service, that will keep connection with ble device and get notifications from gatt services. Also you will need to use WakeLock to keep your service alive in sleep mode.
One year ago was making sample app for internal ble device. Check bluetooth/gatt package, was really useful such implementation.(project isn't good for production, but as sample/demo is pretty nice)

Google Play Game Services connection issues handling

I'm currently developing a multiplayer card game (4 players) using Unity, and I'm using GPGS for multiplayer purpose.
One thing that I can't figure out is connection problem handling. For now I deployed a system that every five second each player send a message to other players telling them i'm online. If a player doesn't send any messages for 10 seconds, I'll consider him/her having connection issues.
My first question is: Is this the right way? I couldn't find anything other than OnPeerDisconnected in GPGS documentation, and I assume it's not related to this.
My second question is: Sometimes while playing the game, one or some of user(s)' gets timed out. In other words, they don't get any message and can't receive any. All my 4 devices are connected to the same network, and network quality is good. How's possible that one of four players encounter network problem?
My last question: I don't know when GPGS consider a player to be timed out? For testing purposes, one time before using the method I explained above, I disconnected one of players, and waited for 5 minutes. Nothing happened. Also I don't know if the user can come back to game (resume playing) after a long time (20-30 seconds) or not?
Thanks for your help. Sorry if anything is ambiguous.

Sending data from Android device to server in the background with minimal user impact

I have an app that generates data that needs to be sent to my server eventually (several hours of delay are no problem at all). I would like to do this with minimal impact to the user, which means to me:
Minimal battery use
No extra permissions, especially not "sketchy" ones
No other strange changes to the system (see example later)
So far I've found three approaches, that all have some serious problems:
Using a SyncAdapter triggered by a network message:
Technically, this sounded like the perfect answer to the problem: Have the system call a service in my app whenever it's doing something on the network anyways. That way, the network is guaranteed to be available, there's barely any extra battery use, since the radio is already on, and the whole thing happens in the background...
And then I tried actually implementing it...
Unfortunately, this approach requires some weird modifications to the system: My app needs to create a new dummy account for the sync-process, even if my app doesn't otherwise use any accounts. And unfortunately, this account cannot be hidden from the user, so now my app is listed when the user clicks "Add Account" in the System Settings, but inside the app, there is no indication of user accounts anywhere... Also, I need to request all sorts of strange permissions, like "Create accounts and set passwords", "Toggle sync on and off", and "Read sync settings". Why would an app that doesn't even provide me with a user account require a permission to set passwords on my device??? Not cool... Delete!!!
Using a BroadcastReceiver and checking for connectivity when it fires:
This requires permission to "view network connections" and possibly even "view information about Wi-Fi networking, such as whether Wi-Fi is enabled and names of connected Wi-Fi devices" ... Why would this app care about my wi-fi or network neighborhood? Creepy... Not getting installed on my device...
The nice thing about this approach is that a network connectivity change likely only happens while the radios are turned on (at least a change to the "available" state). So, if I use this event to trigger an upload (attempt), the battery-impact will be minimal as I won't cause the radio to turn on just for the upload. Unfortunately, this event will probably not be called very often. And to make matters worse, from the docs it sounds like the BroadcastReceiver will only be called while my app is in the resumed-state. So, I won't even be able to make use of events while my app is paused... I.e. using these broadcast events will only be slightly better than option 3:
Just blindly initiating the upload at regular intervals and, if it fails, retrying it again later:
This approach doesn't require any strange permissions and doesn't mess with any system settings. But, clearly, it is the worst I can do for battery use. So, while it's workable, I'd rather find a smarter alternative...
Is there a way to fix the issues of one of the first two approaches? The optimal solution would be a SyncAdapter without a dummy user-account, or, at least, with a hidden one, or one that already exists in the system... But many hours of searching didn't yield any usable answers...
Or is there another better way altogether?
#CommonsWare pointed out two further approaches:
Using JobScheduler:
This allows scheduling jobs for future execution that depend on certain network connectivity or even a certain charging status of the device. It says that it tries to batch job executions for all applications on the system, which may save battery by avoiding additional radio activation, if other apps also have jobs executing that access the network. But if my app is the only one needing to do a network request, I don't think the JobScheduler provides quite the same amount of battery-saving as a network-tickle-driven SyncAdapter would. This is just a guess based on my current understanding, though.
The big issue with using the JobScheduler is that it requires API level 21, i.e. Android 5.0+. For some apps, this might be acceptable, but for me it's not...
Using Google Play Services' Cloud Messenger API, specifically GcmNetworkManager:
This seems to provide pretty much identically the same functionality (except for controlling the retry-backoff-strategy) that the JobScheduler does, except it is available on all devices that have Google Play Services v7.5 or higher installed. Google Play Services is available for devices as far back as Android 2.3, but v7.5 was only released end of May 2015. So, while v7.5 is also available for Android 2.3, it is not guaranteed that it is installed.
To use it, the (supposedly very lightweight) Google Play Services API library needs to be added to the app, which provides the method GoogleApiAvailability.isGooglePlayServicesAvailable(...) that can check if Google Play Services is indeed installed and updated to the version required by the API library. To maximize the chances that this is the case, the API library v7.5 can be added to the app (see here and here for how to get it). If the check fails due to a user-resolvable problem, the library even provides the required dialog to prompt the user to fix the issue (e.g. run an update, ...).
The major advantage of this approach is that it does not require any extra permissions for the app and it doesn't rely on any other changes to the system (mock user accounts, ...). So, it is entirely transparent to the user.
I also found one additional approach, somewhat related to point 3 above:
Using AlarmManager.setInexactRepeating(...):
The AlarmManager also tries to batch callbacks together, just like the JobScheduler and GcmNetworkManager do. In fact, looking at LogCat that sometimes reads "AlarmManager: Checking for alarms... com.google.android.gms", it seems that GCM, and probably also JobScheduler, use the AlarmManager to trigger their execution. The features missing from the AlarmManager are: Suppressing a callback based on network connectivity or battery charging status, and automatic retries of failed executions with a back-off schedule. Technically, one can easily add these features, but some of them, like checking for network connectivity, might require additional permissions.The major advantage of this approach is: It's available on almost all devices (starting API level 3).
Currently I have the GcmNetworkManager approach implemented (point 5) and it works as expected.
But I'm actually considering moving to AlarmManager.setInexactRepeating(...) (point 6) to maximize compatibility. Checking for the device charging state seems to be possible without extra permissions and rather than checking for network connectivity, I can just fire off the http request and check whether it failed... The only feature I would be missing is determining whether the user is on a metered connection or not. And, of course, it will be a bit of work to implement retries, back-offs, ...
Update:
It seems like JobScheduler actually does detect existing network activity (see this JobScheduler introduction), which might make it superior to just using the AlarmManager, and pretty much as good or better than SyncAdapters... The GCM documentation also claims callback optimization based on current network activity (not just availability)... So, I guess the optimal solution would be to use the JobScheduler where available and fall back to GCM where it's not and to the AlarmManager where GCM isn't available either... Yuck...

Backend and Android technology for fast periodic communication

I'm trying to implement a fast communication between two android phones at a certain moment by, preferably, going through a server (since it's easier to be consistent).
The phones have to communicate their gps locations every x seconds, with x being as low as possible, with only one of the phone having to be on the app, the other can be idle (but obviously not turned off).
The first solution I tried is a syncadapter in the app which updates every x seconds, sends requests to server writing its location in a DB, and then the other retrieves the location in the same DB.
Note : I've implemented it this way only because I already had the underlying architecture (REST API and all) beforehand, but I don't know how to do this in the real world, so feel free to cricize my initial choice and advise me on a better solution
Thank you in advance :) !
You can look at Firebase https://www.firebase.com/ which is a real time database. It does have active listeners in the sdk to get real time updates for your GPS coordinates.
The problem you mentioned can be addressed with
https://github.com/firebase/geofire-java/tree/master/examples/SFVehicles

Request GSM/UMTS Location Update in Android

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.)

Categories

Resources