jroal / a2dpvolume

Automatically exported from code.google.com/p/a2dpvolume
http://jimroal.com/slist.htm
95 stars 33 forks source link

GPS location is not always recorded #270

Closed uschindler closed 5 years ago

uschindler commented 5 years ago

When you dicsonnect the car, the app sometimes does not record the GPS location. This happens not reproducible, so its like 50/50 that it works or not.

It is not a bug with the operating system killing the service or similar because the servoce is running perfectly: It adjusts volume on connect and disconnect. But It does not record location anymore (sometimes). Not sure how this can be caused. It's easy visible, because the "GPS active" icon is not showing when the car disconnects.

It looks like this happens mostly when Google Maps Navigation is running at the same time. Maybe A2DP volume gets an error while fetching the location and ignores this.

jroal commented 5 years ago

Make sure you have given the app all permissions. I did not spend the time to carefully check permissions in all use cases. Go into Android settings -> Apps & notifications -> App info -> A2Dp Volume -. Permissions. Make sure all permissions are given or the app my crash or misbehave.

There may be other causes of this. Can you possibly connect Logcat and catch it when it crashes? The later Android versions have become very intolerant and seem to give java exception crashes all the time. The stack trace is not very helpful in determining the issues either so I don't know how to resolve these. I have all Motorola devices so I can't see the issues other devices are having.

uschindler commented 5 years ago

The app has all permissions. It also works, just sometimes it does not work. It looks like the GPS location is not recorded, if another app uses GPS (like Google Maps Navigation, which is common to be running in cars 🤨). The service does not crash, because all other stuff like changing volume is fine perfectly. I will just try to reproduce with logcat.

jroal commented 5 years ago

I think this may be happening because of the much more aggressive task killers in Android 8 and up. I now implemented a notification for the StoreLoc.java service so it keeps a foreground notification active while storing the location, and then clears that notification when done. I am posting a test APK (signed) here to try out and let me know if this fixed the issue.
A2DPVolume2.12.10.4.zip

uschindler commented 5 years ago

Hi Jim, I checked the log messages (using OSMonitor/Logcat), but while running A2DP volume no crash reports were appearing.

I checked the posted ZIP but I did not see any difference to before (with all notifications enabled). I can also reproduce the issue. If a google maps navigation is still running while the car disconnects, A2DP seems to get no GPS position. Looks like this is a conflict between both apps. Not sure how to fix this.

One thing: The Notification about "storing location" does not disappear when it's done. It is stuck in your newest test release. You can't even delete it manually. And when Google Maps is running it's also visible, but it does not save the current location.

Maybe I should also look at the code, maybe I see the problem. Does not seem to be related to the notifications.

uschindler commented 5 years ago

Could it be that the notification is not deleted because it does not call clear() on notificationManagerCompat in StoreLoc.java?

jroal commented 5 years ago

Look at line 652 where I do stop the notification. I tested on the pixel 2 emulator and it worked fine.

jroal commented 5 years ago

OK, I just noticed I only handled it for the pre-Orea notification manager, not the notificationCompatManager. Now I fixed that. Let me do some more testing and drop another test file here.

jroal commented 5 years ago

Does a location file get created? It may say "no data". I wonder if the app lacks location access? Do you have "Use passive location" and Use "Network Locations" both checked in the settings?

jroal commented 5 years ago

I cleaned up a bunch of bugs in the notifications. I still have more work to do but this hopefully fixes your issues. Added highlights of the changes in the log. Here is a zip file of the new test APK 2.12.10.5. A2DPVolume2.12.10.5.zip

uschindler commented 5 years ago

OK, I found the location file: My_Car.html and Grande_Punto.html (its there 2 times, why?). The date and time of both is uptodate and it shows 3 locations (best, most accurate and most recent). Everything looks OK here (precision 8 meters), but when I click on the button to show the location in Google Maps it still shows previous location. This is strange. It looks like the files are updated but the location is not sored inside the app to correctly show the google maps map. The issue only happens when Google Maps is running in parallel. Could it be that creating the google maps links somehow requires google maps?

I hope this helps. I will again check the StoreLoc.java file, the new results look helpful to get the place where it breaks.

uschindler commented 5 years ago

Here you see the issue: file is up-to-date, but when clicking on show location it shows an outdated one. It has nothing to do with notifications, it's just an update problem. Interestingly it only happens if Google Maps is running at same time while the location is captured and stored.

20181121_085413 20181121_085427

jroal commented 5 years ago

When I first implemented the location capture feature I just captured a single location based on the last device to disconnect. It get overwritten with each disconnect. Then I wanted to be able to track each device independently to know where each one was when I last disconnected. The last location that is used by the widget and the "Stored Location" button is in an internal file called "My-Last_location". You can see this in the ALauncher.java file and in "main.java" starting around line 523 in the button function. This file is not visible in the directory in internal memory or SD card. I believe that last location file is stored in Android/data somewhere but it is a hidden file that is not available to other applications. I presume you can get to it with root access.

The device dependent files are stored either in the internal SD memory or external SD card depending on your selection in the preferences. These file are available to other applications. "My_Car" is the default name in the case where the device name could not be found. See StoreLoc.java line 300. Then in line 380 it replaces this with the actual define name which it will then use to name the file. Interestingly I too have a "May_car" file captured but in my case it was from 11/2/2018 so it is old. Line 401 in StoreLoc.java captures the last location file. I have some try/catch blocks there with toasts if something goes wrong. I presume you are not seeing those toasts?

The function "clearLoc in StoreLoc.java handles writing the device dependent files when the location capture has either timed out or met the accuracy requirements. This can end up with a My_Car if a device name cannot be found. Line 489 starts by naming the device as "My Car" which is supposed to be replaced with the real device name on line 493. Then in line 503 the name is turned into a proper file name, replacing illegal characters with underscores and adding the ".html" to the end. The device dependent files can be viewed within the app by long pressing the device name in the list and clicking the "Location" button at the bottom left.

Hopefully that explanation will help with troubleshooting the issue here.

uschindler commented 5 years ago

Thanks Jim,

to conclude: The GPS location is correctly tracked and saved in the HTML file. So in general the StoreLoc.java service is working as expected. There are no bugs. Notifications are also fixed.

The bug here is solely about the "Widget" or the "show last location" button in the app. It does not always show the same location as the HTML file. Sometimes it shows the old/previous location. So it looks like the internal (invisible) file is not always updated. I have no idea how this can happen. It happens reproducible, if Google Maps is running at the same time, but there is nothing in the code that depends on Google Maps. It just produces a maps.google.com link and saves it in several files. The link inside the HTML file opens the correct location, but the widget is showing the old one.

About the device name: I deleted all files and ran again. Afzter disconnect it created 2 HTML files: My_Car.html and Grande_Punto.html (the latter is the name of my Car profile).

jroal commented 5 years ago

When you open the link in the widget or "Stored Location" what device does it say in the maps view? It should have the device name with time and accuracy shown in Maps when you open it.

It is also strange that it captured "my_car". That should not happen. Is there some other device that connects/disconnects? When you ran "Find Devices" is there a device on that list that is disconnecting other than your car? I wonder if I have a bug where it sees a Bluetooth device not in the devices list (so not in the A2DP Volume database) that still triggers the location capture. Also,m what is in the My_Car file? Did it capture real location data or does it say no location data?

uschindler commented 5 years ago

See the screenshots above, it contains the name: The google maps one is after clicking on the widget, the other screenshot is the HTML file. Both screenshots were done at the same time.

I don't use Bluetooth functionality in A2DP volume at all. It just triggers on "Car Mode". On my phone, the car mode is triggered automatically by the operating system. So I only have a single profile in A2DP volume that listens on Car Mode changes. If I click on "search devices" it shows 4 of them, but that are all my paired devices (TV, Laptop, Car's Bluetooth). But while testing, I was outside of my car. I just triggered Car Mode from the App Drawer and exited Car mode again to test. Bluetooth was disabled while doing this.

jroal commented 5 years ago

I cleaned up the file naming in StoreLoc now. I had several places in the class where it named the file again. Now I moved that all to the onStartCommand so it names it once and uses a global variable for the name everywhere else in the class to ensure it is consistent. I also changed the notification to show what device location is being stored for. The name (car) is captured at the onStartCommand and then used to name the file as well as post the title in the notification. This way you can see what device name is used for the file name while it is capturing. Give this a try and let me know what happens.

I am not sure why having Maps open changes anything. Maybe it is just a race condition that changes timing when Maps is using resources?
A2DPVolume2.12.10.5b.zip

uschindler commented 5 years ago

OK, what happens: With your update only one file is created. So that bug is fixed, i no longer get the "My_Car.html" file. But it creates a "storing location" notification 2 times (!!!) - both notifications with the same name ("Grande Punto"). One of those is disappearing after a few seconds, the other one stays stuck forever.

I have the feeling the whole issue is caused by the fact that it is spawning 2 StoreLoc services. If google Maps is already running, the GPS location is there ASAP without delay and then the two services running are exiting at same time and somehow produce a concurrency clash while updating the files.

jroal commented 5 years ago

Now I added checks to make sure only 1 instance of the StoreLoc service is running. I also sent the clearAll command for the notifications both in the service and the StoreLoc classes. Give this a try. A2DPVolume2.12.10.5c.zip

uschindler commented 5 years ago

Unchanged behaviour. Notification appearing 2 times with same device name. One of them disappearing after a few seconds, the other one stuck.

jroal commented 5 years ago

Very strange. I cannot duplicate that on any emulator on my Motorola devices. I do get 2 notifications while location is being stored but they clear when done and the regular notification returns as expected.

uschindler commented 5 years ago

I got the 2nd notification to disappear if I add GPS a timeout (it was unlimited). Nevertheless, I think I know the problem: it looks like when Google Maps is enabled, it does not easily get a location, as there are no updates coming (Google Maps has the GPS fix already, so the location won't update and the updates listener is never called or not correctly called, no idea).

The HTML files are written in clearLoc() and this one is always called when the location service shuts down, even if it takes long.

But the private file for "show my last location" is not written in clearLoc(), but inside the notify from the GPS listener. If this one is never called, because the location was known before (Google Maps is running), the file is not updated.

So I'd move writing the last location file also to clearLoc() and place the best guess inside (either from l, l2, l3).

jroal commented 5 years ago

I made some more changes. I took your advice and added storing the my_last_location to the clearLoc function. I made this one a bit different in that it will try for any valid location and store it. I also added a check to ALauncher and the button functions to check for the my_last_location and if it does not exist it also looks for the other file that is stored at the same time My_last_location2. Give this a try. A2DPVolume2.12.10.5d.zip

uschindler commented 5 years ago

Works in all cases. When google maps is running it also stores the location. I think the problem is that the location change listener is only called, if the location actually changes. But if Google maps already has a GPS fix, the listener is not called - because nothing changes anymore.

Notifications (if enabled) are also working.

I think you can close that issue. Once you have committed your changes, I can add the missing German strings for the new notification, OK?

FYI, the notifications are not needed for my device, because I put A2DP volume on the list of applications that are not put into doze mode. The service is not killed then. So I disabled all notifications by A2DP volume, it's completely silent. Location is still captured now every time, great! I tested it with various tricks. When I was in my basement, it also tracked the (network based) location, although there was no GPS signal.

uschindler commented 5 years ago

I just pushed the new strings translation. Good night!

jroal commented 5 years ago

I pulled in the update German strings, fixed up a few others things, and then pushed 2.12.10.5 to beta. I updated the log to capture my changes. Thanks for all your help!