User Tools

Site Tools


doc:appunti:prog:kivy_debian_12_android_11

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
doc:appunti:prog:kivy_debian_12_android_11 [2023/10/04 17:31] – [Writing the buildozer.spec file] niccolodoc:appunti:prog:kivy_debian_12_android_11 [2025/12/01 11:57] (current) – [Kivy version] niccolo
Line 1: Line 1:
-====== Creating a Kivy app for Android 11 on Debian 12 Bookworm ======+====== Creating a Kivy app for Android 11-14 on Debian 12 Bookworm ====== 
 + 
 +See also the page **[[kivy_app_in_play_store]]**.
  
 **[[https://kivy.org/|Kivy]]** is a free and open source Python framework for developing mobile apps, with a single codebase, you will be able to deploy apps on **Windows**, **Linux**, **macOS**, **iOS** and **Android**. In this page I will focus on builing an Android app using a GNU/Linux workstation running Debian 12. **[[https://kivy.org/|Kivy]]** is a free and open source Python framework for developing mobile apps, with a single codebase, you will be able to deploy apps on **Windows**, **Linux**, **macOS**, **iOS** and **Android**. In this page I will focus on builing an Android app using a GNU/Linux workstation running Debian 12.
Line 78: Line 80:
 ==== Using the new venv install method ==== ==== Using the new venv install method ====
  
-FIXME Instead of disabling the externally-managed-environment flag or instead of using the pip3 ''%%--user%%'' install method, it should be possible to use the venv pip3 install method. You need to install the **python3-venv** Debian package. This recipe did not work for me, but should be investigated further:+:!: **WARNING**: Till now we did not use this new preferred method, because the package **python-for-android** uses the old ''pip install'' method. See below about the //[[#installation_in_user_space|user method]]// install. 
 + 
 +Instead of disabling the externally-managed-environment flag or instead of using the pip3 ''%%--user%%'' install method, it should be possible to use the venv pip3 install method. You need to install the **python3-venv** Debian package. This recipe did not work for me, but should be investigated further:
  
 <code bash> <code bash>
Line 121: Line 125:
  
 ==== Prepare the Kivy project in user space ==== ==== Prepare the Kivy project in user space ====
 +
 +:!: **INFO**: This procedure is **required only once** when we start a new projec.
  
 Now it is time to prepare the Kivy project directory for the build of the Android package. You must check the following: Now it is time to prepare the Kivy project directory for the build of the Android package. You must check the following:
Line 132: Line 138:
  
 <code> <code>
 +mkdir openolyimageshare
 cd openolyimageshare cd openolyimageshare
 buildozer init buildozer init
Line 181: Line 188:
 You can use **presplash.filename** and **icon.filename** to include two artwork in your app. The //presplash// will be displayed at startup, during the initialization of the environment (unfortunately it is rather time consuming). The //icon// is instead what you can imagine. Use PNG graphics at least 512 x 512 pixels, you can use transparency too. You can use **presplash.filename** and **icon.filename** to include two artwork in your app. The //presplash// will be displayed at startup, during the initialization of the environment (unfortunately it is rather time consuming). The //icon// is instead what you can imagine. Use PNG graphics at least 512 x 512 pixels, you can use transparency too.
  
-In **android.permissions** you must list all the permissions that your app will require from the operating system. If you forget to declare something your app simply will not be able to do that operation. Beware that starting from Android 10 the access to the external storae (basically the space into the SD card or into the device memory) has undergone a drastic change, see the table below for a basic overview.+In **android.permissions** you must list all the permissions that your app will require from the operating system. If you forget to declare something your app simply will not be able to do that operation. Beware that starting from Android 10 the access to the external storage (basically the space into the SD card or into the device memory) has undergone a drastic change, see the table below for a basic overview.
  
-^ READ_EXTERNAL_STORAGE   | This was the long-established permission required by the apps to read the [[https://android.googlesource.com/platform/docs/source.android.com/+/android-4.2.1_r1.1/src/tech/storage/index.md|external storage]] (a permissionless filesystem residing into the SD card or into a dedicated partition of the device internal storage). This is not longer true starting from **Android 10** (API level 29) which introduced the **scoped storage**, designed to protect app and user data and reduce file clutter; requesting ''READ_EXTERNAL_STORAGE'' in Android 10 actually means requesting access only to **photos and media**. Afterwards **Android 11** (API level 30) fixed several problems with that implementation; in Android 11 and above requesting ''READ_EXTERNAL_STORAGE'' does not give you any actual permission. Generally, in Android 11, an app cannot access the root directory of the SD card and the Download directory, it can access only its ASD (App Specific Directory).  |+^ READ_EXTERNAL_STORAGE   | This was the long-established permission required by the apps to read the [[https://android.googlesource.com/platform/docs/source.android.com/+/android-4.2.1_r1.1/src/tech/storage/index.md|external storage]] (a permissionless filesystem residing into the SD card or into a dedicated partition of the device internal storage). If you want e.g. to read the pictures from the DCIM folder of an **Android 8** device, you must grant this permission. This is not longer true starting from **Android 10** (API level 29) which introduced the **scoped storage**, designed to protect app and user data and reduce file clutter; requesting ''READ_EXTERNAL_STORAGE'' in Android 10 actually means requesting access only to **photos and media**. Afterwards **Android 11** (API level 30) fixed several problems with that implementation; in Android 11 and above requesting ''READ_EXTERNAL_STORAGE'' does not give you any actual permission. Generally, in Android 11, an app cannot access the root directory of the SD card and the Download directory, it can access only its ASD (App Specific Directory).  |
 ^ WRITE_EXTERNAL_STORAGE  | The same as ''READ_EXTERNAL_STORAGE'', but for write permission.  | ^ WRITE_EXTERNAL_STORAGE  | The same as ''READ_EXTERNAL_STORAGE'', but for write permission.  |
-^ CAMERA                  | With this permission an app can use the external storage even with Android 10 and above, but limited to the shared folders like **Pictures****DCIM**, etc. FIXME Check if this is true! May be accessing a ''DCIM/SUBFOLDER/'' is always granted if files are .jpg or similar media files.  |+^ CAMERA                  | Writing .jpg or similar media files under the Android shared folders **DCIM** or **Pictures** (or subfolders therein), is always permitted; no particular permission is required even in Android 11Requesting the CAMERA permission allow to use the camera itself, the flash, etc.  |
 ^ MANAGE_EXTERNAL_STORAGE  | Starting from Android 11, this is the permission required to access all the files into the storage. The app should also provide an ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent. App requesting this permission may have trouble getting into the Google Play Store.  | ^ MANAGE_EXTERNAL_STORAGE  | Starting from Android 11, this is the permission required to access all the files into the storage. The app should also provide an ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent. App requesting this permission may have trouble getting into the Google Play Store.  |
  
-=== Compile SDK vs Target SDK === +=== Target API vs Minimum API vs Compile SDK === 
-==== Compiling the package ====+ 
 +Into the **buildozer.spec** you can define the following: 
 + 
 +<file> 
 +# (int) Target Android API, should be as high as possible. 
 +#android.api 31 
 + 
 +# (int) Minimum API your APK / AAB will support. 
 +#android.minapi 21 
 + 
 +# (int) Android SDK version to use 
 +#android.sdk 20 
 +</file> 
 + 
 +By setting a **target API** lower than your SDK can support, you can declare what will be the highest Android version that your app is designed to be compatible with. In November 2025 the Google Play Store requires the SDK target 35 (Android 15). 
 + 
 +Declaring a **minimum API** you can tell what is the minimum Android version required by your app. We did not declared the android.minapi, so Buildozer choosed API 21 (**Android 5.0.2**). 
 + 
 +The **compile SDK** is the environment you want to use to create the app, i.e. the SDK you downloaded from Google (which generally support the higher API available at the moment). This will affects what functions and constructs you can use in your program. If you do not specify a version, Buildozer should detect the highest SDK downloaded and use it. 
 + 
 +The Android API supported by your Buildozer installation depends upon the version of **python-for-android** (**p4a**) downloaded and installed during your setup. To know what is the **target API supported by your Buildozer installation**, check the messages log during a build, you will find a line like this: 
 + 
 +<code> 
 +[INFO]:    Available Android APIs are (31, 34) 
 +</code> 
 + 
 +To know what is the **Android SDK versions available**, look into the directory downloaded during the Buildozer installation: 
 +<code> 
 +ls $HOME/.buildozer/android/platform/android-sdk/platforms/ 
 +android-31  android-34 
 +</code> 
 + 
 +^ Android Version  ^ API  ^ 
 +| Android 15        35 | 
 +| Android 14        34 | 
 +| Android 13        33 | 
 +| Android 12L      |  32 | 
 +| Android 12        31 | 
 +| Android 11        30 | 
 +| Android 10        29 | 
 +| Android 9        |  28 | 
 +| Android 8.1      |  27 | 
 +| Android 8.0      |  26 | 
 +| Android 7.1      |  25 | 
 +| Android 7.0      |  24 | 
 +| Android 6.0      |  23 | 
 +| Android 5.1      |  22 | 
 +| Android 5.0      |  21 | 
 + 
 +==== Compiling the package (debug or release) ==== 
 + 
 +:!: **INFO**: This is **the only procedure** to be executed whenever you want to compile a new version; the **version number** must be updated into the **main.py** source code. 
 + 
 +Enter the project directory and edit the **main.py** source code updating the definition of the **%%__version__%%** variable (the **buildozer.spec** will refer this value to create the package name). Then choose to make a debug build:
  
 <code> <code>
-# Choose debug or release build: 
 buildozer android debug buildozer android debug
-#buildozer android release 
 </code> </code>
 +
 +During this step the directory **$HOME/project-name/.buildozer/** will be populated by files and directories in the order of 3-4 Gb,
 +
 +The package will be created into the **bin/** subdirectory, using a name like **packagename-version-arm64-v8a_armeabi-v7a-debug.apk**.
 +
 +When you are ready to **publish** your package, you must create the //release// binary:
 +
 +<code>
 +buildozer android release
 +</code>
 +
 +In this case the package created into the **bin/** subdirectory will be named like **packagename-version-arm64-v8a_armeabi-v7a-release.aab**, which is not directly installable into the device.
 +
 +
 +===== Upgrading the build tools (Android SDK) =====
 +
 +As per November 2025, the **Google Play** requires that new packages uploaded to the store are compiled using the **SDK target 35**, this means that you have to declare ''android.api = 35'' in **buildozer.spec** file and that you have downloaded the relative Android SDK.
 +
 +==== Buildozer version ====
 +
 +To check what version of Buildozer is installed:
 +
 +<code>
 +buildozer --version
 +</code>
 +
 +You can also ask pip3, using whatever //venv// or //user// variant you used:
 +
 +<code>
 +pip3 list --user
 +Package         Version
 +--------------- -------
 +buildozer       1.5.0
 +...
 +</code>
 +
 +The upgrade should be as simple as running
 +
 +<code>
 +pip3 install --user --upgrade buildozer
 +</code>
 +
 +==== Python-for-android version ====
 +
 +To check the **python-for-android (p4a) version** installed by your Buildozer setup, enter the ''.buildozer'' subdirectory of your project:
 +
 +<code>
 +cd $HOME/openolyimageshare/.buildozer/android/platform/python-for-android
 +</code>
 +
 +and check the **pythonforandroid** Pyton module version:
 +
 +<code>
 +python3
 +Python 3.11.2 (main, Apr 28 2025, 14:11:48) [GCC 12.2.0] on linux
 +Type "help", "copyright", "credits" or "license" for more information.
 +>>> import pythonforandroid
 +>>> print(pythonforandroid.__version__)
 +2024.01.21
 +</code>
 +
 +Upgrading Buildozer will eventually upgrade also the python-for-android version. That **Android dependencies** will be stored inside the project subdirectory **$HOME/openolyimageshare/buildozer/android/platform/python-for-android**.
 +
 +You may want to require a specific python-for-android version by declaring the **p4a.branch** option into the **buildozer.spec** file:
 +
 +<file>
 +# Use the default version:
 +#p4a.branch = master
 +# Use a specific p4a version:
 +#p4a.branch = v2024.03.12
 +# Use the develop version:
 +#p4a.branch = develop
 +</file>
 +
 +Remember to refresh the build environment with the ''buildozer android clean'' command.
 +
 +==== Android SDK version ====
 +
 +All the SDKs downloaded will be stored into **$HOME/.buildozer/android/platform/android-sdk/platforms/** and are available to compile a package for the user.
 +
 +The SDK used to compile a specific package depends upon the **android.api** option you declared into the **buildozer.spec** file.
 +
 +<code>
 +cd $HOME/openolyimageshare/
 +vi buildozer.spec
 +# In the spec file set e.g. android.api = 35
 +buildozer android update
 +buildozer android clean
 +</code>
 +
 +The above command **does not update Buildozer** nor **python-for-android**, but it eventually downloads the **new Android SDK/API** into your **$HOME/.buildozer/** hierarchy (not into the project directory).
 +
 +==== Kivy version ====
 +
 +Usually you just declare that you need Kivy to compile the project by including it into the **requirements** of **buildozer.spec**:
 +
 +<file>
 +requirements = python3,kivy,requests,android
 +</file>
 +
 +You may be version specific with the syntax:
 +
 +<file>
 +requirements = python3,kivy==2.3.0,requests,android
 +</file>
 +
 +To inspect what version of Kivy was used in building the package, look into the prokect directory: **.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/packages/kivy/**; you will find a file e.g. **2.3.0.zip**.
 +
 +
 +==== Recompile with the updated components ====
 +
 +Once you updated some components, be sure to clean the build environment:
 +
 +<code>
 +buildozer android clean
 +</code>
 +
 +Once you recompiled the app, look into the project **$HOME/openolyimageshare/** for the file **.buildozer/android/platform/build-.../dists/openolyimageshare/AndroidManifest.xml** and verify that it has:
 +
 +<code xml>
 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 +    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="35" />
 +</manifest>
 +</code>
 +
 +If the **targetSdkVersion** did not upgrade as expected, verify you issued the ''clean'' command.
 +
 +Other generally unnecessary cleaning commands are:
 +
 +<code>
 +buildozer android clean_dists
 +buildozer android clean_builds
 +buildozer android clean_apk
 +rm -rf .buildozer/
 +</code>
 +
  
 ===== Web Resources ===== ===== Web Resources =====
Line 217: Line 411:
   * **[[https://community.appinventor.mit.edu/t/how-to-access-non-media-media-files-on-android-11/54828|How to access non-media & media files on Android 11+]]**   * **[[https://community.appinventor.mit.edu/t/how-to-access-non-media-media-files-on-android-11/54828|How to access non-media & media files on Android 11+]]**
   * **[[https://community.appinventor.mit.edu/t/asd-app-specific-directory-vs-private-folder/19154|ASD (app specific directory) vs Private folder]]**   * **[[https://community.appinventor.mit.edu/t/asd-app-specific-directory-vs-private-folder/19154|ASD (app specific directory) vs Private folder]]**
 +  * **[[https://developer.android.com/training/data-storage/shared/media|Access media files from shared storage]]**
  
doc/appunti/prog/kivy_debian_12_android_11.1696433490.txt.gz · Last modified: by niccolo