Reputation: 81
I am trying to make a GPS app via Kivy in Python3. The app works fine, but then randomly crashes and gives the following logcat error:
refreshed screen
I/python (10601): inside onLocation
I/python (10601): trying to print kwargs inside onLocation():
I/python (10601): {'lat': 40.55075864, 'lon': -111.83829566, 'speed': 0.30016663670539856, 'bearing': 56.900001525878906, 'altitude': 1447.0, 'accuracy': 3.0}
I/python (10601): trying to assign lat from kwargs...
I/python (10601): trying to assign lng from kwargs...
I/python (10601): inside onLocation(): got lat: 40.55075864
I/python (10601): Inside onlocation(): trying to update gpsCycle...
I/python (10601): Inside class.onLocation(): trying to refresh Screen...
I/python (10601): Refreshing Screen
I/python (10601): refreshed screen
I/python (10601): [INFO ] [Base ] Leaving application in progress...
I/python (10601): Traceback (most recent call last):
I/python (10601): File "/home/joshua/GPSapp/.buildozer/android/app/main.py", line 217, in <module>
I/python (10601): File "/home/joshua/GPSapp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/gpsApp/kivy/app.py", line 855, in run
I/python (10601): File "/home/joshua/GPSapp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/gpsApp/kivy/base.py", line 504, in runTouchApp
I/python (10601): File "/home/joshua/GPSapp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/gpsApp/kivy/core/window/window_sdl2.py", line 747, in mainloop
I/python (10601): File "/home/joshua/GPSapp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/gpsApp/kivy/core/window/window_sdl2.py", line 479, in _mainloop
I/python (10601): File "/home/joshua/GPSapp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/gpsApp/kivy/base.py", line 339, in idle
I/python (10601): File "/home/joshua/GPSapp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/gpsApp/kivy/clock.py", line 591, in tick
I/python (10601): File "kivy/_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events
I/python (10601): File "kivy/_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events
I/python (10601): File "kivy/_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events
I/python (10601): File "kivy/_clock.pyx", line 154, in kivy._clock.ClockEvent.tick
I/python (10601): File "kivy/_clock.pyx", line 86, in kivy._clock.ClockEvent.get_callback
I/python (10601): File "/home/joshua/GPSapp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/gpsApp/kivy/weakmethod.py", line 56, in is_dead
I/python (10601): ReferenceError: weakly-referenced object no longer exists
I/python (10601): Python for android ended.
Here is my full code:
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.image import Image, AsyncImage
from kivy.utils import platform
from kivy.graphics import Rectangle, Color
from random import randint as rando
import time
import socket
import certifi
import os
#import urllib.request
from plyer import gps
try:
from android.permissions import request_permissions, Permission, check_permission
except Exception as e:
print('couldnt import android.permissions: ', e)
lat = "foo"
lng = "foo"
gpsData = "foo"
locationAble = True
class MyGrid(GridLayout):
def __init__(self, **kwargs):
global lat
global lng
global locationAble
global gpsData
super(MyGrid, self).__init__(**kwargs)
self.cols = 1
self.inside = GridLayout()
self.inside.cols = 2
#Starts GPS monitoring
try:
request_permissions([Permission.ACCESS_COARSE_LOCATION,
Permission.ACCESS_FINE_LOCATION])
try:
while not check_permission('android.permission.ACCESS_COARSE_LOCATION'):
print('Inside getLocationData(): Permissions have not been granted yet. Waiting .5 seconds')
time.sleep(.5)
pass
except Exception as e:
print('Couldnt loop waiting for permissions: ',e)
try:
gps.configure(on_location=self.onLocation)#, on_status=self.onStatus)
print('gps.configure worked')
except Exception as e:
print('gps.configure failed: ', e)
try:
gps.start(minTime=1000,minDistance=1)
except Exception as e:
print("gps.start failed: ", e)
except Exception as e:
print("GPS monitering failed: ", e)
locationAble = False
if locationAble:
self.add_widget(Label(text="Waiting for GPS data..."))
pass
else:
self.add_widget(Label(text="Couldn't get GPS data"))
pass
def refreshScreen(self):
global gpsData
print("Refreshing Screen")
finalStr = '[color=#000000][size=26]This app crashes from time to time. \nIf this happens you can open the app again.[/size] \n\n\n\n\n\n' + gpsData + '[/color]'
with self.canvas:
Color(1,1,1)
Rectangle(size = (1000,1000))
self.clear_widgets()
self.add_widget(Label(text=finalStr, halign = 'center', markup = True))
def onStatus(stype,status):
global lat
global lng
print('inside onStatus')
try:
gps_status = 'type={}\n{}'.format(stype, status)
print('finishing onStatus with gps_status as: ', str(gps_status))
except Exception as e:
print('failed inside onStatus: ', e)
def onLocation(self, **kwargs):
global lat
global lng
global gpsData
print('inside onLocation')
try:
gpsCycles = 0
if gpsCycles == 0:
try:
print('trying to print kwargs inside onLocation():')
print(kwargs)
except exception as e:
print('failed to print kwargs: ',e)
try:
gpsData = '\n'.join([
'{}={}'.format(k, v) for k, v in kwargs.items()])
except Exception as e:
print('Failed to get gps data inside onLocation: ', e)
#Formats the data into the string to display
try:
lat = kwargs['lat']
lng = kwargs['lon']
speed = kwargs['speed']
bearing = kwargs['bearing']
altitude = kwargs['altitude']
acc = kwargs['accuracy']
latStr = 'Latitude: ' + str(lat) + '\N{DEGREE SIGN}N'
lngStr = 'Longitude: ' + str(lng) + '\N{DEGREE SIGN}W'
speedStr = 'Speed: ' + str(speed) + 'm/s'
bearingStr = 'Bearing: ' + str(bearing) + '\N{DEGREE SIGN}'
altitudeStr = 'Altitude: ' + str(altitude) + 'meters'
accStr = 'Accurate within ' + str(acc) + ' meters'
gpsData = latStr + '\n' + lngStr + '\n' + speedStr + '\n' + bearingStr + '\n' + altitudeStr + '\n\n\n\n\n\n[size=30][u]' + str(accStr) + '[/u][/size]'
pass
except Exception as e:
print("failed to format data: ", e)
try:
print('trying to assign lat from kwargs...')
#lat = kwargs['lat']
#print('inside onLocation(): got lat: ',str(lat))
except Exception as e:
print('inside onLocation(): failed to assign lat: ',e)
try:
print('trying to assign lng from kwargs...')
#lng = kwargs['lon']
print('inside onLocation(): got lat: ',str(lat))
except Exception as e:
print('inside onLocation(): failed to assign lng: ',e)
try:
print('Inside onlocation(): trying to update gpsCycle...')
gpsCycles = gpsCycles + 1
except Exception as e:
print('Inside onLocation(): Couldnt update gpsCycles: ',e)
else:
print('Inside onLocation(): this is an exccess call')
except Exception as e:
print('Inside onLocation(): Main try failed: ',e)
try:
print("Inside class.onLocation(): trying to refresh Screen...")
self.refreshScreen()
print("refreshed screen")
except Exception as e:
print("Failed to refresh Screen: ", e)
class MyApp(App):
def build(self):
return MyGrid()
if __name__ == "__main__":
MyApp().run()
Anyone know why this is happening? I don't have the deepest understanding on python so please be patient with me. Is this Kivy crashing? or a logic error?
Upvotes: 1
Views: 271
Reputation: 1247
A variable defined inside a class is considered as a temporary variable and can be called for a limited number of times usually 4-5. If you try to access that variable more than that (usually happens in kivy when you are using any variable to do something on the screen and arriving at that same screen again and again) so you get the error, "weakly-referenced object no longer exists". Check on which screen you are getting that error. To remove this error you basically have to make that variable an instance variable (by adding 'self.' in front). In your case, I guess lat, long, etc are giving errors. So instead of using lat, long use self.lat, self.long, and so on
Also, there's a bug in older version of kivy which result in this error. In your buildozer.spec file change the version of kivy. In requirements instead of Python,kivy
write Python,kivy=2.2.0rc4
Then delete the .buildozer directory and pack the application again using buildozer android debug deploy run
Upvotes: 1