I'm writing software which requires cell location updates to be received or checked constantly. The problem I'm having is that when the screen is off: a) notifications stop (using PhonestateListener); b) when a timer is used to check the cell info of the current cell, old cell info is returned.
I've spent a lot of time searching the reason for this and found a couple of posts on this subject. However I never found an answer or a workaround to the problem, accept for having the phone turn the screen on constantly to get a new cell location.
I've check the android RIL source code and it seems as soon as the screen is turned off, a broadcast receiver in the RIL sets the screen state to off and stops URC messages from the modem. I decided to try and call these internal functions to, say, reset the screen state (bad solution!), but I kept getting permission errors due to system intents being created as a result of my actions (I even tried by getting su permission).
Finally, I tried to communicate directly with the modem to send a +CSQ command (using 'invokeOemRilRequestStrings' function in the RIL). However, that part failed as I kept getting errors about object type not being same as expected class type...
So... I would like to know if anyone can point me to a solution to get this thing done. Or is it an impossible thing to do on android without modifying the ROM?
Thanks in advance for your help.
Did you try registering for location updates in a separate Android service having FOREGROUND priority?
Related
I want to display health-service data such as step, pace, etc in AmbientMode.
But HealthServices(using ExerciseClient https://developer.android.com/training/wearables/health-services/active) seems to go into Sleep state when entering ambient mode.
I tried using AmbientUpdate with AlarmManager, but HealthServices did not wake up. Please let me know if you have a good way to solve this problem.
I want to change the data of the screen in the middle in AmbientMode.
Please help me.
Please add the relevant code that shows how you are setting up the connection to HealthServices. It will make it easier for people to help you. In the meantime, here are some suggestions for you to look into:
ExerciseClient will only send you data when you have an active workout with a listener set. It sounds like you do get updates in interactive mode so I'm going to assume that this part is working for you. Make sure that you don't accidentally end your workout e.g. in onPause or some other life cycle method/function that is called when the app loses focus (this happens when the device enters ambient mode).
Make sure that you have a Foreground service set up as outlined in the spec, and that you have the required permissions. Otherwise, you might run into issues when the device enters ambient mode and your app is sent to the background.
Use a continuously-running ForegroundService in conjunction with ExerciseClient to ensure correct operation for the entire workout.
Using a ForegroundService is essential when requesting location data. Your manifest file must specify foregroundServiceType="location and specify the appropriate permissions.
Note: If your app experiences AUTO_ENDED_PERMISSION_LOST errors, this is likely caused by a missing ForegroundService with appropriate location permissions.
Worth noting is that when the device is in ambient mode you will get data less frequently. HealthServices will do more batching of data in order to minimize the impact on battery life. The frequency and batch size varies based on the type of metric you are requesting. Make sure that you allow enough time for data to come through, and that you are parsing the batched data points correctly.
Make sure that you give enough time for the ExerciseClient to flush all data points when you end your workout or you might lose data.
Finally, if you're not actually tracking a workout, you might be better off using the PassiveMonitoringClient.
To receive data updates in the background, use the PassiveMonitoringClient. Your app must have a BroadcastReceiver declared in its AndroidManifest.xml. When you register to receive updates from Health Services, they will be delivered to this receiver.
I have a small test App that with an Android GPS API map fragment. I use FusedLocationProvider. TarketSDK=29. Using Java.
As long as the app is active it works beautifully. On locationUpdates, I add a new point to the track and everything looks great and stays accurate. The goal is to track my hike, total distance and track and show it on the map. Works great.
As soon I lock my phone or loses focus, then the updates stop and I no longer get location updates.
Solution seems to be:
Background Service (discouraged)
Foreground Service
PendingIntent
I have poured over the docs, StackOverflow, all examples/tutorials I can find, developer.android.com, etc. I have downloaded examples of the latter 2 from GitHub; they seem incredibly obtuse (probably just me).
What are the dis/advantages of ForegroundService vs PendingIntent?
How about a bare-bones example illustrating the min features of each to implement location updates while your phone is locked in your pocket or some other app is active? Just the template minimum.
I need to save the locationUpdates that occur while my app is not active or phone is locked; in order to fill in Track when activity is restored to the app.
Some simple end-to-end guidance from my working app to something that will maintain locationUpdates and save the data would be great.
Ok - I have answered my question in a roundabout way.
I had been Searching on "retrieving location updates when app is not active". This lead to the various solutions of background service, foreground service, pendingIntents, etc.
I eventually found that if you just start a Foreground Service with a Notification, even if your phone is locked or you switch active apps, your App continues to receive LocationUpdates; as the Foreground Service runs in the same thread and therefore activates your app code (if I understand the reasons why correctly).
So, I started searching on just how to start a Foreground Service. As anyone knows that has tried to figure this out lately, this has changed more than a couple times over recent versions. The online docs at developer.android.com are not up to date. You will spend a lot of time wondering why things do not work following these docs.
Eventually, with just searching on how to start a foreground service, I came across this simple and straightforward (non-youtube-video - don't you just hate those things) tutorial. https://androidwave.com/foreground-service-android-example/
I just added this code to my existing Mapping code that works when the app is active, and tested with locking the phone and putting it in my pocket and switching apps and doing the same. It appears to solve the problem.
Update: Added code to count number of location updates and average accuracy of each update holding the phone in hand, screen on and app active as the baseline. Phone locked, or App not active no difference in number of updates nor accuracy. Phone locked and in pocket, no difference in number of updates, but accuracy suffered by from an average of 10m to an average of 13m; to be expected I assume whilst in the pocket.
I have a big problem with an Android application that I developed.
The purpose of the application (for business) is to track the position of the device continuously (24 hours on 24) detecting a GPS track on a regular interval, which will then be synchronized to the server to the unleashing of certain events.
Of course, over time the device in and out of buildings, acquiring and losing the GPS signal continuously.
Often the device is not used and remains in office for several hours inside the company headquarters without GPS signal. During the course of time the Android system continues to provide me constantly getLastKnowLocation
My problem is that after some time that the system is running, sometimes two or three days, sometimes more days, my app starts to receive from the system always the same coordinates, regardless of who is in the open or at closed. From what I understand the Android operating system no longer seems able to update his coordinates and It will always return the same getLastKnowLocation indefinitely.
My App therefore becomes useless.
You know how I can fix this?
Is there any process that Android can restart in order for the system to wake up. In My App I will acquire any permission, except for root permissions.
For now the only control that I put, and that if the system always gives me the same identity for a number of seconds I call the method requestLocationUpdates of the location manager again.
But I need something more robust, to give me a better guarantee of operation. I'd like to be sure as possible that the systems try really to get updated coordinates.
The only thing I can think of is that maybe I can ask the system to restart some process so that the Location Manager, is fully reset. Can I do this? What is the process to be killed?
Can you think of any other solution or you found yourselves in this issue?
Thank you.
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.)
I live near the border and work in another country. So I have selected my own network provider as the favorite. However, I notice that it sticks with the provider for as long as it can. So when I start from my country I keep my network even when I am across the border, however, when I go the other way around, it will keep the foreign network even when my favorite network is already available. I know this, because when I want to manually select it, it is available from the list.
Now, I would like to create an application that would automatically search for my preferred network when it is roaming, each time it connects to another cell tower.
Now I understand, that previously I could have listened to Cell Location changed with a broadcast receiver, but that is now impossible. (Which is a pity)
And I read from this:
Programatically connecting to another Network operators
That it seems that I would be unable to select another provider from an application for security reasons. (At least with documented api calls).
However, I don't care about public api or not, because I don't intent to distribute this in the Android Market. It is just an app to make MY life easier, will probably open up the source code, so other people can use it if they want to.
I could use some hints, to get this working though.
So maybe there are other things that are broadcast for which I can listen to, like signal strength or something, this would start my code to check if I can switch network.
I would prefer this to work as a Broadcast Receiver, I also have read that when using Cell location from a Service that I won't get updates when the screen is turned off, which in this case defeats the purpose.
And then, I would greatly appreciate some hints/pointers as for how to search the Android source for stuff that I can use to select the network automatically.
Since it sounds like you might be traveling on a predictable path between the networks, have you considered using the ProximityAlert capability of the LocationManager? You define a circle around some location, and when your device enters/exits that circle, a broadcast is issued to your receiver.
I wrote a section on this in Pro Android 3, chapter 17. There's a sample application on our web site:
http://www.androidbook.com/projects
Click on the link for the project zip files, then look for ProAndroid3_Ch17_Maps.zip
There are instructions for downloading and importing from the link above. The project inside the zip is called ProximityAlertDemo. It's very basic, just to show the Proximity Alert itself, but it shouldn't be too hard to incorporate it into an app or a service. I'm afraid I don't have an answer for you on how to switch the networks from code though. The suggestion to launch into the Settings screen seems to be your best bet at the moment.