kivy / python-for-android

Turn your Python application into an Android APK
https://python-for-android.readthedocs.io
MIT License
8.32k stars 1.84k forks source link

API 29 support #2360

Closed pbienst closed 2 years ago

pbienst commented 3 years ago

I've been using the python-for-android libs successfully in the past in order to bundle Python with my own Java application. However, Google now requires API 29 support for all updates to the Play store, and I've been unsuccessful in getting this to work.

First, according to https://python-for-android.readthedocs.io/en/latest/quickstart/#installation , the recommended NDK version is r19b, but that one no longer seems available, so I installed r19c.

I have the following environment:

export ANDROIDSDK="$HOME/android/" # The directory where tools is located, not the SDK dir
export ANDROIDNDK="$HOME/android/ndk/19.2.5345600"
export ANDROIDAPI="29"  # Target API version of your application
export NDKAPI="21"  # Minimum supported API version of your application

This command

p4a create --arch=armeabi-v7a,arm64-v8a,x86,x86_64 --blacklist-requirements=android,libffi,openssl

gives the following error:

...
[INFO]:    Building genericndkbuild for arm64-v8a
[INFO]:    -> directory context /home/pbienst/.local/share/python-for-android/build/bootstrap_builds/service_only/jni
[INFO]:    -> running ndk-build V=1
           working: /home/pbienst/android/ndk/19.2.5345600/build/core/setup-app-platform.mk:101: *** Android NDK: Aborting.    .  Stop.                                             Exception in thread background thread for pid 98736:
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.8/dist-packages/sh.py", line 1633, in wrap
    fn(*rgs, **kwargs)
  File "/usr/local/lib/python3.8/dist-packages/sh.py", line 2557, in background_thread
    handle_exit_code(exit_code)
  File "/usr/local/lib/python3.8/dist-packages/sh.py", line 2261, in fn
    return self.command.handle_command_exit_code(exit_code)
  File "/usr/local/lib/python3.8/dist-packages/sh.py", line 861, in handle_command_exit_code
    raise exc
sh.ErrorReturnCode_2:

  RAN: /home/pbienst/android/ndk/19.2.5345600/ndk-build V=1

  STDOUT:
Android NDK: Found platform level in /home/pbienst/.local/share/python-for-android/build/bootstrap_builds/service_only/project.properties. Setting APP_PLATFORM to android-29.
Android NDK: android-29 is above the maximum supported version android-28. Choose a supported API level or set APP_PLATFORM to "latest".
/home/pbienst/android/ndk/19.2.5345600/build/core/setup-app-platform.mk:101: *** Android NDK: Aborting.    .  Stop.

What is the recommended way to proceed, so that I can update my Android app again?

paulheider commented 3 years ago

Based on the versions listed Android's unsupported NDK releases, it looks like you're using Android NDK, Revision 19c. If you list the supported API platforms, you'll see it only goes up to API 28:

> ls android-ndk-r19c/platforms/
android-16  android-17  android-18  android-19  android-21  android-22  android-23  android-24  android-26  android-27  android-28

The latest version (NDK r21d) supports acceptable API versions 29 and 30:

> ls android-ndk-r21d/platforms/
android-16  android-18  android-21  android-23  android-26  android-28  android-30
android-17  android-19  android-22  android-24  android-27  android-29

The first step is to up the NDK version (and path) mentioned in your buildozer.spec file:

# (str) Android NDK version to use                                                                                                              
android.ndk = 21d

# (str) Android NDK directory (if empty, it will be automatically downloaded.)                                                                  
android.ndk_path = /path/here

You could try NDK 20b. I don't know if it will work any better with python-for-android. I haven't gotten 21c to work yet.

obfusk commented 3 years ago

I can confirm that android.ndk = 20b + android.api = 29 works.

paulheider commented 3 years ago

@obfusk - I'm curious what your set-up looks like.

I'm on Ubuntu 18.04.

I've downloaded the latest command line tools for the SDK, as per instructions. and installed two platform flavors and two build tools flavors: ./cmdline-tools/latest/bin/sdkmanager "platforms;android-29" ./cmdline-tools/latest/bin/sdkmanager "platforms;android-30" ./cmdline-tools/latest/bin/sdkmanager "build-tools;28.0.2" ./cmdline-tools/latest/bin/sdkmanager "build-tools;30.0.3"

I also have three version of the NDK: android-ndk-r19c android-ndk-r20b android-ndk-r21d

I take a nice simple Kivy file: ` import kivy kivy.require( '2.0.0' )

from kivy.app import App from kivy.uix.label import Label

class MyApp(App):

def build(self):
    return Label(text='Hello world')

if name == 'main': MyApp().run() `

And tested a systematic range of SDK/NDK versions in the buildozer file by focusing on these three settings:

`

(int) Target Android API, should be as high as possible.

android.api = 30

(int) Minimum API your APK will support.

android.minapi = 30

...

(str) Android NDK version to useqa

android.ndk = 21d `

Target API values = (null), 27, 29, 30 Min API values = (null), 27, 28, 29, 30 NDK values = 19c, 20b, 21d

I paired the API values only with NDK values that are valid. So NDK 19c doesn't use 29 or 30. In between each buildozer android debug, I do a full rm -rf .buildozer to clear out the old history.

As long as my MinAPI is <= 28, I'm golden and I can build an app. (Also, prior to Google's Min API of 29, I'd regularly built and deployed Apps. Part of why I did this test was to make sure I didn't have any obvious software rot in my dev environment.)

Whether I use NDK 20b or 21d and set the MinAPI >= 29, I get critical failure.

[INFO]: Detected highest available build tools version to be 30.0.3 [DEBUG]: -> running gradlew assembleDebug [DEBUG]: [DEBUG]: > Task :compileDebugJavaWithJavac [DEBUG]: Note: Some input files use or override a deprecated API. [DEBUG]: Note: Recompile with -Xlint:deprecation for details. [DEBUG]: Note: Some input files use unchecked or unsafe operations. [DEBUG]: Note: Recompile with -Xlint:unchecked for details. [DEBUG]: D8: Dex file with version '38' cannot be used with min sdk level '30'. [DEBUG]: [DEBUG]: > Task :transformDexArchiveWithDexMergerForDebug FAILED

I can post the whole log file with color term characters and download progress bars now or can post a cleaner version if you tell me the best way to capture the log without these.

[DEBUG]: FAILURE: Build failed with an exception. [DEBUG]: [DEBUG]: * What went wrong: [DEBUG]: Execution failed for task ':transformDexArchiveWithDexMergerForDebug'. [DEBUG]: > com.android.build.api.transform.TransformException: java.lang.RuntimeException: java.lang.RuntimeException: com.android.buildr.dexing.DexArchiveMergerException: Error while merging dex archives: /home/paul/git/kivy-canary/.buildozer/android/platform/build-armeabi-v7a/ists/kivycanary__armeabi-v7a/build/intermediates/transforms/dexBuilder/debug/0, /home/paul/git/kivy-canary/.buildozer/android/platform/build-areabi-v7a/dists/kivycanary__armeabi-v7a/build/intermediates/transforms/externalLibsDexMerger/debug/0 [DEBUG]: [DEBUG]: * Try: [DEBUG]: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan $ o get full insights. [DEBUG]: [DEBUG]: * Get more help at https://help.gradle.org [DEBUG]: [DEBUG]: Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0. [DEBUG]: Use '--warning-mode all' to show the individual deprecation warnings. [DEBUG]: See https://docs.gradle.org/6.4.1/userguide/command_line_interface.html#sec:command_line_warnings [DEBUG]: [DEBUG]: BUILD FAILED in 3m 27s

I don't see any python-for-android relevant DEX issues. The greater Android ecosystem issues tied to the same error suggest downgrading or upgrading the version of gradle to skip a problematic version. It looks like python-for-android is beyond that hump in gradle versions.

obfusk commented 3 years ago

@paulheider Pretty much this (modulo the Python 3.9 stuff).

The play store requires target api >= 29 (but leaving minapi = 21 -- the p4a default -- works fine). Is there a reason you need a higher minapi?

paulheider commented 3 years ago

@obfusk - Thanks! That was exactly the sort of kick I needed. I tried varying both API settings early on in my tests but had another lurking issue at the time. So my mind remembered doing the tests but forgot why they failed. (Or remembered the wrong reasons.)

tldr; No, I don't need a higher minapi. I unset that feature and set the target API to 29 and everything works fine again.

github-actions[bot] commented 2 years ago

👋 We use the issue tracker exclusively for bug reports and feature requests. However, this issue appears to be a support request. Please use our support channels to get help with the project.

If you're having trouble installing or using python-for-android, maybe you could be interested in our quickstart guide.

Let us know if this comment was made in error, and we'll be happy to reopen the issue.