Last active
May 23, 2021 12:59
-
-
Save telent/6409c94ff9a4f448ecbd6b5859718669 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| My first application | |
| """ | |
| import toga | |
| from toga.style import Pack | |
| from toga.style.pack import COLUMN, ROW | |
| from rubicon.java import JavaClass, JavaInterface | |
| from rubicon.java.jni import java | |
| LocationListener = JavaInterface("android/location/LocationListener") | |
| class LocListener(LocationListener): | |
| def onFlushComplete(self, code): | |
| print(f"{code} flush") | |
| def onProviderDisabled(self, provider): | |
| print(f"{provider} disabled") | |
| def onProviderEnabled(self, provider): | |
| print(f"{provider} enabled") | |
| def onStatusChanged(self, status, extras): | |
| print(f"status {status} {extras}") | |
| def onLocationChanged(self, location): | |
| print(f"location {location}") | |
| if location != None: | |
| # self.locationHolder.latitude = location.getLatitude() | |
| # self.locationHolder.longitude = location.getLongitude() | |
| print(location) | |
| class Gadgetbee(toga.App): | |
| LocationManager = JavaClass("android/location/LocationManager") | |
| def ensureLocationPermission(self, activity, code): | |
| ContextCompat = JavaClass('androidx/core/content/ContextCompat') | |
| ActivityCompat = JavaClass('androidx/core/app/ActivityCompat') | |
| Helpers = JavaClass('org/beeware/android/HelpersKt') | |
| Manifest = JavaClass('android/Manifest') | |
| permission = JavaClass('android/Manifest$permission') | |
| GRANTED = JavaClass('android/content/pm/PackageManager').PERMISSION_GRANTED | |
| if ContextCompat.checkSelfPermission(activity, "android.permission.ACCESS_FINE_LOCATION") != GRANTED: | |
| perms = permission.ACCESS_FINE_LOCATION | |
| if (ActivityCompat.shouldShowRequestPermissionRationale(activity, | |
| permission.ACCESS_FINE_LOCATION)): | |
| Helpers.requestPermission(activity, perms, code) | |
| else: | |
| Helpers.requestPermission(activity, perms, code) | |
| def pollLocation(self): | |
| location = self.locationManager.getLastKnownLocation(self.LocationManager.GPS_PROVIDER) | |
| if location != None: | |
| self.latitude = location.getLatitude() | |
| self.longitude = location.getLongitude() | |
| print(location) | |
| def startLocationReporting(self, context): | |
| print("service", JavaClass("android/app/Service")) | |
| loc_service = JavaClass("android/content/Context").LOCATION_SERVICE | |
| print("loc constant",loc_service) | |
| t = context.getSystemService(loc_service) | |
| self.locationManager = self.LocationManager(__jni__=java.NewGlobalRef(t)) | |
| loclistener = LocListener() | |
| self.pollLocation() | |
| self.locationManager.requestLocationUpdates(self.LocationManager.GPS_PROVIDER, | |
| 1000, 1.0, | |
| loclistener) | |
| def startup(self): | |
| """ | |
| Construct and show the Toga application. | |
| Usually, you would add your application to a main content box. | |
| We then create a main window (with a name matching the app), and | |
| show the main window. | |
| """ | |
| main_box = toga.Box(style=Pack(direction=COLUMN)) | |
| Intent = JavaClass('android/content/Intent') | |
| Uri = JavaClass('android/net/Uri') | |
| activity = JavaClass('org/beeware/android/MainActivity').singletonThis | |
| name_label = toga.Label("HI", style=Pack(padding=(0, 5))) | |
| name_box = toga.Box(style=Pack(direction=ROW, padding=5)) | |
| name_box.add(name_label) | |
| button = toga.Button( | |
| 'Where am I?', | |
| on_press=self.say_hello, | |
| style=Pack(padding=5) | |
| ) | |
| main_box.add(name_box) | |
| main_box.add(button) | |
| self.ensureLocationPermission(activity, 1) | |
| self.startLocationReporting(activity) | |
| self.main_window = toga.MainWindow(title=self.formal_name) | |
| self.main_window.content = main_box | |
| self.main_window.show() | |
| def say_hello(self, widget): | |
| self.pollLocation() | |
| self.main_window.info_dialog( | |
| 'Hi there!', | |
| f"lat {self.latitude} lon {self.longitude}" | |
| ) | |
| def main(): | |
| return Gadgetbee() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| My first application | |
| """ | |
| import toga | |
| from toga.style import Pack | |
| from toga.style.pack import COLUMN, ROW | |
| from rubicon.java import JavaClass, JavaInterface, JavaProxy | |
| from rubicon.java.jni import java | |
| LocationListener = JavaInterface("android/location/LocationListener") | |
| class LocListener(LocationListener): | |
| def __init__(self): | |
| super().__init__() | |
| def onFlushComplete(self, code): | |
| print(f"{code} flush") | |
| return 0 | |
| def onProviderDisabled(self, provider): | |
| print(f"{provider} disabled") | |
| return 0 | |
| def onProviderEnabled(self, provider): | |
| print(f"{provider} enabled") | |
| return 0 | |
| def onStatusChanged(self, status, extras): | |
| print(f"status {status} {extras}") | |
| return 0 | |
| def onLocationChanged(self, location): | |
| print(f"location {location}") | |
| if location is not None: | |
| # self.locationHolder.latitude = location.getLatitude() | |
| # self.locationHolder.longitude = location.getLongitude() | |
| print(location) | |
| return 0 | |
| def hashCode(self): | |
| print("hash") | |
| return 1 | |
| class Gadgetbee(toga.App): | |
| LocationManager = JavaClass("android/location/LocationManager") | |
| def ensureLocationPermission(self, activity, code): | |
| ContextCompat = JavaClass('androidx/core/content/ContextCompat') | |
| ActivityCompat = JavaClass('androidx/core/app/ActivityCompat') | |
| Helpers = JavaClass('org/beeware/android/HelpersKt') | |
| Manifest = JavaClass('android/Manifest') | |
| permission = JavaClass('android/Manifest$permission') | |
| GRANTED = JavaClass('android/content/pm/PackageManager').PERMISSION_GRANTED | |
| if ContextCompat.checkSelfPermission(activity, "android.permission.ACCESS_FINE_LOCATION") != GRANTED: | |
| perms = permission.ACCESS_FINE_LOCATION | |
| if ActivityCompat.shouldShowRequestPermissionRationale(activity, | |
| permission.ACCESS_FINE_LOCATION): | |
| Helpers.requestPermission(activity, perms, code) | |
| else: | |
| Helpers.requestPermission(activity, perms, code) | |
| def pollLocation(self): | |
| location = self.locationManager.getLastKnownLocation(self.LocationManager.GPS_PROVIDER) | |
| if location is not None: | |
| self.latitude = location.getLatitude() | |
| self.longitude = location.getLongitude() | |
| print(location) | |
| def startLocationReporting(self, context): | |
| global loclistener | |
| print("service", JavaClass("android/app/Service")) | |
| loc_service = JavaClass("android/content/Context").LOCATION_SERVICE | |
| print("loc constant", loc_service) | |
| t = context.getSystemService(loc_service) | |
| # NewGlobalRef used here to cast the Object to a LocationManager | |
| self.locationManager = self.LocationManager(__jni__=java.NewGlobalRef(t)) | |
| locl = LocListener() | |
| self.locListener = locl | |
| print(locl._methods) | |
| self.pollLocation() | |
| self.locationManager.requestLocationUpdates(self.LocationManager.GPS_PROVIDER, | |
| 1000, 1.0, | |
| locl) | |
| def startup(self): | |
| """ | |
| Construct and show the Toga application. | |
| Usually, you would add your application to a main content box. | |
| We then create a main window (with a name matching the app), and | |
| show the main window. | |
| """ | |
| main_box = toga.Box(style=Pack(direction=COLUMN)) | |
| Intent = JavaClass('android/content/Intent') | |
| Uri = JavaClass('android/net/Uri') | |
| activity = JavaClass('org/beeware/android/MainActivity').singletonThis | |
| name_label = toga.Label("HI", style=Pack(padding=(0, 5))) | |
| name_box = toga.Box(style=Pack(direction=ROW, padding=5)) | |
| name_box.add(name_label) | |
| button = toga.Button( | |
| 'Where am I?', | |
| on_press=self.say_hello, | |
| style=Pack(padding=5) | |
| ) | |
| main_box.add(name_box) | |
| main_box.add(button) | |
| self.ensureLocationPermission(activity, 1) | |
| self.startLocationReporting(activity) | |
| self.main_window = toga.MainWindow(title=self.formal_name) | |
| self.main_window.content = main_box | |
| self.main_window.show() | |
| def say_hello(self, widget): | |
| self.pollLocation() | |
| print(self.locListener._methods) | |
| self.main_window.info_dialog( | |
| 'Hi there!', | |
| f"lat {self.latitude} lon {self.longitude}" | |
| ) | |
| def main(): | |
| return Gadgetbee() |
Author
Author
also got a java backtrace in logcat, but it seems to be consequent to the python error, not antecedent
-22 23:37:58.057 29211 29211 F zygote64: runtime.cc:523] (no managed stack frames)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at android.app.ActivityThread.-wrap11(ActivityThread.java:-1)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at android.os.Looper.loop(Looper.java:164)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at java.lang.reflect.Method.invoke(Native method)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at int java.lang.Object.hashCode() ((null):-1)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at android.location.LocationManager$ListenerTransport android.location.LocationManager.wrapListener(android.location.LocationListener, android.os.Looper) (LocationManager.java:870)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at int org.beeware.rubicon.Python.run(java.lang.String, java.lang.String[]) (Python.java:-2)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at void org.beeware.android.MainActivity.startPython(java.util.Map) (MainActivity.java:225)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle) (Instrumentation.java:1214)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at void android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent, java.lang.String) (ActivityThread.java:2856)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:106)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at void android.os.Looper.loop() (Looper.java:164)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[]) (Method.java:-2)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at void com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run() (RuntimeInit.java:438)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:523] at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:807)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:531] JNI DETECTED ERROR IN APPLICATION: JNI NewStringUTF called with pending exception java.lang.NullPointerException: Expected to unbox a 'int' primitive type but was returned null
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:531] at int java.lang.Object.hashCode() ((null):-1)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:531] at int java.util.HashMap.hash(java.lang.Object) (HashMap.java:338)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:531] at java.lang.Object java.util.HashMap.get(java.lang.Object) (HashMap.java:556)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:531] at void android.location.LocationManager.requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper, android.app.PendingIntent) (LocationManager.java:885)
05-22 23:37:58.058 29211 29211 F zygote64: runtime.cc:531] at void org.beeware.android.MainActivity.startPython(java.util.Map) (MainActivity.java:225)
Author
looking at the logcat line Native invocation 484536464400 :: hashCode and the code that produces it, I realise that it is trying to call the hashCode method. However, adding
class LocListener(LocationListener):
def hashCode(self):
print("hash")
return 42
seems to have no effect (and the print statement is not executed either, as far as I can tell)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
05-22 23:30:45.126 28875 28875 I Python : service <JavaClass: b'android/app/Service'>
05-22 23:30:45.127 28875 28875 I Python : loc constant location
05-22 23:30:45.155 28875 28875 I Python : Location[gps 51.595463,-0.030617 hAcc=15 et=+7h56m48s756ms alt=72.0 vel=0.0 vAcc=16 sAcc=0 bAcc=??? {Bundle[mParcelledData.dataSize=96]}]
05-22 23:30:45.163 28875 28875 D Python : Native invocation 484538061264 :: hashCode
05-22 23:30:45.163 28875 28875 E Python : Error invoking callback
05-22 23:30:45.163 28875 28875 E Python : Traceback (most recent call last):
05-22 23:30:45.163 28875 28875 E Python : File "/data/user/0/net.telent.gadgetbee/files/python/user_code/app_packages/rubicon/java/api.py", line 36, in dispatch
05-22 23:30:45.164 28875 28875 E Python : if len(signatures) == 1:
05-22 23:30:45.164 28875 28875 E Python : TypeError: object of type 'NoneType' has no len()
05-22 23:30:45.164 28875 28875 D Python : Native invocation done.
05-22 23:30:45.281 28900 28900 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***