Search code examples
urllib2kivyurlrequestbuildozer

Kivy app (on android) crashes when attempting to use google directions api


I new to Kivy (and relatively new to Python) and I am having a problem getting UrlRequests to work. In particular, I am trying to use the google directions api in an App for android.

First of all, the code works (completely) when I run the main.py file through python. The app also successfully builds and deploys to my phone using buildozer. The app loads and runs right up to the point where you press a button to launch a urlrequest, at which point the app just closes.

So I believe the problem is this button. The full details of the button are somewhat unnecessary to explain now I think, but basically it uses a function (like below) several times to return the distance between places.

import urllib2

#the google api key
google_api_key = '...'

def distance_checker(origin, destination):
    # This function outputs the distance between two places in meters
    api_key = google_api_key
    url = 'https://maps.googleapis.com/maps/api/directions/json?origin='
    start = origin.replace(' ', '%20')
    end = destination.replace(' ', '%20')
    final_url = url + start + '&destination=' + end + '&mode=walking' + '&key=' + api_key
    json_obj = urllib2.urlopen(final_url)
    data = json.load(json_obj)

    return data['routes'][0]['legs'][0]['distance']['value']

In my buildozer.spec file I do have 'android.permissions = INTERNET' included.

I also had my app attempt to access google using a function of the form (submitted by user: 10flow, on Pinging servers in Python),

import os

def ping_function(self):
    hostname = "google.com" #example
    response = os.system("ping -c 1 " + hostname)

    #and then check the response...
    if response == 0:
        self.box.add_widget(Label(text=(hostname + ' is up!'), size_hint_y=None, height=40))
    else:
        self.box.add_widget(Label(text=(hostname + ' is down!'), size_hint_y=None, height=40))

For clarity, the 'box' used above is for a ScrollView widget. This function does work in the app in android (i.e. it does create a Label saying 'google.com is up!'). So this would lead me to believe that accessing the internet itself is not the problem: the problem is either using a google api, or the using of urllib2 (that make sense?).

I also wrote a function which does the url query using UrlRequest instead of urllib2, but that had the same problem in the end (works on linux, not on android).

So I imagine the problem is using google apis. And I think it has something got to do with adding 'google-play-services_lib/' as an android.library reference in the buildozer.spec file.

If what I have said so far makes sense, could anyone comment on the google api/google-play-services_lib issue? I'm really not that familiar with apis in general, and am somewhat out of my depth. Or perhaps this isn't the issue, and I have missed something obvious.

Anyway, thanks in advance.

EDIT

I think I have narrowed down the problem somewhat. I can use apis that do not require a key, and I cannot use apis that do need a key. Posts like How to get google map apikey in android lead me to believe I just need to add the google api key (in the case of the google directions api) to the android meta data in the buildozer.spec file. I have unsuccessfully tried several variations of the following,

# (list) Android application meta-data to set (key=value format)
android.meta_data = com.google.android.maps.v2.API_KEY=AI...

If anyone could tell me what I am doing wrong it would be very helpful! Thanks.


Solution

  • So for others and posterity, I found an answer through the Kivy users forum (http://kivy.org/#forum, question: Problems with UrlRequest with an api that needs an api key).

    The issue was I was trying to access a https url, and hence needed to build the android apk using openssl. No need for android meta data or google play services, just add openssl to the requirements in the buildozer.spec file. requirements = openssl,kivy

    Once it was discovered that openssl was the issue, there was one more problem to overcome in that buildozer attempted to download an openssl tar file that no longer existed on the openssl.org webpage. However, one can edit the openssl version buildozer attempts to download in your_project/.buildozer/android/platform/python-for-android/recipes/openssl/recipe.sh . You will also need to update the MD5 value in that file.

    Hopefully this helps someone in the future.