Isaias Awate

Isaias Awate

1611714000

Waktu Solat App for Android Made with Flutter

Waktu solat Malaysia

App waktu solat seluruh Malaysia. Prayer time app across Malaysia.

Focusing on lightweight, fast app, easy-to-use and modern UI 馃槈

App UI

GIF Screenshot

API

Malaysia Prayer Time JSON API ttps://mpt.i906.my/

Changelogs History

Wondering what changed with every 馃啎 releases? Or what bug 馃悰 has been fixed? View more here

Report an issue / Feature request

Found a bug (or bugs)? Report issue related to the app using in app problem reporter, or file them directly on issue tracker.

Have an idea 馃挕 that may benefit the app? Do not hesitate to submit your suggestion here. Really appreciated if you do.

Discussion

You can also use Discussions ask any question or suggesting any idea using. Kita sembang2 santai je gituu 鈽猴笍

Web app (Beta)

Open in Progressive Web App

App Releases

Get it on:

Get it on Google Play Explore on Huawei App Gallery

*i having some trouble to update the app in App Gallery. It might out of date for a few versions.

Not available for iOS sorry

Try the beta

Download here -> APK. And submit your review.

Honourable mention

Article that help me througout the development(Read: Website yg function teruk. The real MVP!. Banyak lagi website/blog2 lain tpi yang kt bwawh ni is da real lifesaver!)

  1. https://medium.com/platform45/flutter-handling-your-network-api-calls-like-a-boss-9093c71a7c97
  2. https://stackoverflow.com/questions/50115311/flutter-how-to-force-an-application-restart-in-production-mode
  3. https://javiercbk.github.io/json_to_dart/
  4. https://medium.com/swlh/flutter-dynamic-themes-in-3-lines-c3b375f292e3
  5. https://medium.com/@fuzzymemory/adding-scheduled-notifications-in-your-flutter-application-19be1f82ade8
  6. https://gist.github.com/taciomedeiros/50472cf94c742befba720853e9d598b6

Legalese

Download Details:

Author: iqfareez

Source Code: https://github.com/iqfareez/App-Waktu-Solat-Malaysia

#flutter #dart #mobile-apps

What is GEEK

Buddha Community

Waktu Solat App for Android Made with Flutter

Build an Android application with Kivy Python framework

If you鈥檙e a Python developer thinking about getting started with mobile development, then the Kivy framework is your best bet. With Kivy, you can develop platform-independent applications that compile for iOS, Android, Windows, macOS, and Linux. In this article, we鈥檒l cover Android specifically because it is the most used.

We鈥檒l build a simple random number generator app that you can install on your phone and test when you are done. To follow along with this article, you should be familiar with Python. Let鈥檚 get started!

Getting started with Kivy

First, you鈥檒l need a new directory for your app. Make sure you have Python installed on your machine and open a new Python file. You鈥檒l need to install the Kivy module from your terminal using either of the commands below. To avoid any package conflicts, be sure you鈥檙e installing Kivy in a virtual environment:

pip install kivy 
//
pip3 install kivy 

Once you have installed Kivy, you should see a success message from your terminal that looks like the screenshots below:

Kivy installation

Successful Kivy installation

 

Next, navigate into your project folder. In the main.py file, we鈥檒l need to import the Kivy module and specify which version we want. You can use Kivy v2.0.0, but if you have a smartphone that is older than Android 8.0, I recommend using Kivy v1.9.0. You can mess around with the different versions during the build to see the differences in features and performance.

Add the version number right after the import kivy line as follows:

kivy.require('1.9.0')

Now, we鈥檒l create a class that will basically define our app; I鈥檒l name mine RandomNumber. This class will inherit the app class from Kivy. Therefore, you need to import the app by adding from kivy.app import App:

class RandomNumber(App): 

In the RandomNumber class, you鈥檒l need to add a function called build, which takes a self parameter. To actually return the UI, we鈥檒l use the build function. For now, I have it returned as a simple label. To do so, you鈥檒l need to import Label using the line from kivy.uix.label import Label:

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

class RandomNumber(App):
  def build(self):
    return Label(text="Random Number Generator")

Now, our app skeleton is complete! Before moving forward, you should create an instance of the RandomNumber class and run it in your terminal or IDE to see the interface:

import kivy from kivy.app import App from kivy.uix.label import Label class RandomNumber(App):  def build(self):    return Label(text="Random Number Generator") randomApp = RandomNumber() randomApp.run()

When you run the class instance with the text Random Number Generator, you should see a simple interface or window that looks like the screenshot below:

 

Simple interface after running the code

You won鈥檛 be able to run the text on Android until you鈥檝e finished building the whole thing.

Outsourcing the interface

Next, we鈥檒l need a way to outsource the interface. First, we鈥檒l create a Kivy file in our directory that will house most of our design work. You鈥檒l want to name this file the same name as your class using lowercase letters and a .kv extension. Kivy will automatically associate the class name and the file name, but it may not work on Android if they are exactly the same.

Inside that .kv file, you need to specify the layout for your app, including elements like the label, buttons, forms, etc. To keep this demonstration simple, I鈥檒l add a label for the title Random Number, a label that will serve as a placeholder for the random number that is generated _, and a Generate button that calls the generate function.

My .kv file looks like the code below, but you can mess around with the different values to fit your requirements:

<boxLayout>:
    orientation: "vertical"
    Label:
        text: "Random Number"
        font_size: 30
        color: 0, 0.62, 0.96

    Label:
        text: "_"
        font_size: 30

    Button:
        text: "Generate"
        font_size: 15 

In the main.py file, you no longer need the Label import statement because the Kivy file takes care of your UI. However, you do need to import boxlayout, which you will use in the Kivy file.

In your main file, you need to add the import statement and edit your main.py file to read return BoxLayout() in the build method:

from kivy.uix.boxlayout import BoxLayout

If you run the command above, you should see a simple interface that has the random number title, the _ place holder, and the clickable generate button:

Random Number app rendered

Notice that you didn鈥檛 have to import anything for the Kivy file to work. Basically, when you run the app, it returns boxlayout by looking for a file inside the Kivy file with the same name as your class. Keep in mind, this is a simple interface, and you can make your app as robust as you want. Be sure to check out the Kv language documentation.

Generate the random number function

Now that our app is almost done, we鈥檒l need a simple function to generate random numbers when a user clicks the generate button, then render that random number into the app interface. To do so, we鈥檒l need to change a few things in our files.

First, we鈥檒l import the module that we鈥檒l use to generate a random number with import random. Then, we鈥檒l create a function or method that calls the generated number. For this demonstration, I鈥檒l use a range between 0 and 2000. Generating the random number is simple with the random.randint(0, 2000) command. We鈥檒l add this into our code in a moment.

Next, we鈥檒l create another class that will be our own version of the box layout. Our class will have to inherit the box layout class, which houses the method to generate random numbers and render them on the interface:

class MyRoot(BoxLayout):
    def __init__(self):
        super(MyRoot, self).__init__()

Within that class, we鈥檒l create the generate method, which will not only generate random numbers but also manipulate the label that controls what is displayed as the random number in the Kivy file.

To accommodate this method, we鈥檒l first need to make changes to the .kv file . Since the MyRoot class has inherited the box layout, you can make MyRoot the top level element in your .kv file:

<MyRoot>:
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Random Number"
            font_size: 30
            color: 0, 0.62, 0.96

        Label:
            text: "_"
            font_size: 30

        Button:
            text: "Generate"
            font_size: 15

Notice that you are still keeping all your UI specifications indented in the Box Layout. After this, you need to add an ID to the label that will hold the generated numbers, making it easy to manipulate when the generate function is called. You need to specify the relationship between the ID in this file and another in the main code at the top, just before the BoxLayout line:

<MyRoot>:
    random_label: random_label
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Random Number"
            font_size: 30
            color: 0, 0.62, 0.96

        Label:
            id: random_label
            text: "_"
            font_size: 30

        Button:
            text: "Generate"
            font_size: 15

The random_label: random_label line basically means that the label with the ID random_label will be mapped to random_label in the main.py file, meaning that any action that manipulates random_label will be mapped on the label with the specified name.

We can now create the method to generate the random number in the main file:

def generate_number(self):
    self.random_label.text = str(random.randint(0, 2000))

# notice how the class method manipulates the text attributre of the random label by a# ssigning it a new random number generate by the 'random.randint(0, 2000)' funcion. S# ince this the random number generated is an integer, typecasting is required to make # it a string otherwise you will get a typeError in your terminal when you run it.

The MyRoot class should look like the code below:

class MyRoot(BoxLayout):
    def __init__(self):
        super(MyRoot, self).__init__()

    def generate_number(self):
        self.random_label.text = str(random.randint(0, 2000))

Congratulations! You鈥檙e now done with the main file of the app. The only thing left to do is make sure that you call this function when the generate button is clicked. You need only add the line on_press: root.generate_number() to the button selection part of your .kv file:

<MyRoot>:
    random_label: random_label
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Random Number"
            font_size: 30
            color: 0, 0.62, 0.96

        Label:
            id: random_label
            text: "_"
            font_size: 30

        Button:
            text: "Generate"
            font_size: 15
            on_press: root.generate_number()

Now, you can run the app.

Compiling our app on Android

Before compiling our app on Android, I have some bad news for Windows users. You鈥檒l need Linux or macOS to compile your Android application. However, you don鈥檛 need to have a separate Linux distribution, instead, you can use a virtual machine.

To compile and generate a full Android .apk application, we鈥檒l use a tool called Buildozer. Let鈥檚 install Buildozer through our terminal using one of the commands below:

pip3 install buildozer
//
pip install buildozer

Now, we鈥檒l install some of Buildozer鈥檚 required dependencies. I am on Linux Ergo, so I鈥檒l use Linux-specific commands. You should execute these commands one by one:

sudo apt update
sudo apt install -y git zip unzip openjdk-13-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses5-dev libncursesw5-dev libtinfo5 cmake libffi-dev libssl-dev

pip3 install --upgrade Cython==0.29.19 virtualenv 

# add the following line at the end of your ~/.bashrc file
export PATH=$PATH:~/.local/bin/

After executing the specific commands, run buildozer init. You should see an output similar to the screenshot below:

Buildozer successful initialization

The command above creates a Buildozer .spec file, which you can use to make specifications to your app, including the name of the app, the icon, etc. The .spec file should look like the code block below:

[app]

# (str) Title of your application
title = My Application

# (str) Package name
package.name = myapp

# (str) Package domain (needed for android/ios packaging)
package.domain = org.test

# (str) Source code where the main.py live
source.dir = .

# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas

# (list) List of inclusions using pattern matching
#source.include_patterns = assets/*,images/*.png

# (list) Source files to exclude (let empty to not exclude anything)
#source.exclude_exts = spec

# (list) List of directory to exclude (let empty to not exclude anything)
#source.exclude_dirs = tests, bin

# (list) List of exclusions using pattern matching
#source.exclude_patterns = license,images/*/*.jpg

# (str) Application versioning (method 1)
version = 0.1

# (str) Application versioning (method 2)
# version.regex = __version__ = \['"\](.*)['"]
# version.filename = %(source.dir)s/main.py

# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = python3,kivy

# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
# requirements.source.kivy = ../../kivy

# (list) Garden requirements
#garden_requirements =

# (str) Presplash of the application
#presplash.filename = %(source.dir)s/data/presplash.png

# (str) Icon of the application
#icon.filename = %(source.dir)s/data/icon.png

# (str) Supported orientation (one of landscape, sensorLandscape, portrait or all)
orientation = portrait

# (list) List of service to declare
#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY

#
# OSX Specific
#

#
# author = 漏 Copyright Info

# change the major version of python used by the app
osx.python_version = 3

# Kivy version to use
osx.kivy_version = 1.9.1

#
# Android specific
#

# (bool) Indicate if the application should be fullscreen or not
fullscreen = 0

# (string) Presplash background color (for new android toolchain)
# Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
# red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,
# darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,
# olive, purple, silver, teal.
#android.presplash_color = #FFFFFF

# (list) Permissions
#android.permissions = INTERNET

# (int) Target Android API, should be as high as possible.
#android.api = 27

# (int) Minimum API your APK will support.
#android.minapi = 21

# (int) Android SDK version to use
#android.sdk = 20

# (str) Android NDK version to use
#android.ndk = 19b

# (int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi.
#android.ndk_api = 21

# (bool) Use --private data storage (True) or --dir public storage (False)
#android.private_storage = True

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

# (str) Android SDK directory (if empty, it will be automatically downloaded.)
#android.sdk_path =

# (str) ANT directory (if empty, it will be automatically downloaded.)
#android.ant_path =

# (bool) If True, then skip trying to update the Android sdk
# This can be useful to avoid excess Internet downloads or save time
# when an update is due and you just want to test/build your package
# android.skip_update = False

# (bool) If True, then automatically accept SDK license
# agreements. This is intended for automation only. If set to False,
# the default, you will be shown the license when first running
# buildozer.
# android.accept_sdk_license = False

# (str) Android entry point, default is ok for Kivy-based app
#android.entrypoint = org.renpy.android.PythonActivity

# (str) Android app theme, default is ok for Kivy-based app
# android.apptheme = "@android:style/Theme.NoTitleBar"

# (list) Pattern to whitelist for the whole project
#android.whitelist =

# (str) Path to a custom whitelist file
#android.whitelist_src =

# (str) Path to a custom blacklist file
#android.blacklist_src =

# (list) List of Java .jar files to add to the libs so that pyjnius can access
# their classes. Don't add jars that you do not need, since extra jars can slow
# down the build process. Allows wildcards matching, for example:
# OUYA-ODK/libs/*.jar
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar

# (list) List of Java files to add to the android project (can be java or a
# directory containing the files)
#android.add_src =

# (list) Android AAR archives to add (currently works only with sdl2_gradle
# bootstrap)
#android.add_aars =

# (list) Gradle dependencies to add (currently works only with sdl2_gradle
# bootstrap)
#android.gradle_dependencies =

# (list) add java compile options
# this can for example be necessary when importing certain java libraries using the 'android.gradle_dependencies' option
# see https://developer.android.com/studio/write/java8-support for further information
# android.add_compile_options = "sourceCompatibility = 1.8", "targetCompatibility = 1.8"

# (list) Gradle repositories to add {can be necessary for some android.gradle_dependencies}
# please enclose in double quotes 
# e.g. android.gradle_repositories = "maven { url 'https://kotlin.bintray.com/ktor' }"
#android.add_gradle_repositories =

# (list) packaging options to add 
# see https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html
# can be necessary to solve conflicts in gradle_dependencies
# please enclose in double quotes 
# e.g. android.add_packaging_options = "exclude 'META-INF/common.kotlin_module'", "exclude 'META-INF/*.kotlin_module'"
#android.add_gradle_repositories =

# (list) Java classes to add as activities to the manifest.
#android.add_activities = com.example.ExampleActivity

# (str) OUYA Console category. Should be one of GAME or APP
# If you leave this blank, OUYA support will not be enabled
#android.ouya.category = GAME

# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png

# (str) XML file to include as an intent filters in <activity> tag
#android.manifest.intent_filters =

# (str) launchMode to set for the main activity
#android.manifest.launch_mode = standard

# (list) Android additional libraries to copy into libs/armeabi
#android.add_libs_armeabi = libs/android/*.so
#android.add_libs_armeabi_v7a = libs/android-v7/*.so
#android.add_libs_arm64_v8a = libs/android-v8/*.so
#android.add_libs_x86 = libs/android-x86/*.so
#android.add_libs_mips = libs/android-mips/*.so

# (bool) Indicate whether the screen should stay on
# Don't forget to add the WAKE_LOCK permission if you set this to True
#android.wakelock = False

# (list) Android application meta-data to set (key=value format)
#android.meta_data =

# (list) Android library project to add (will be added in the
# project.properties automatically.)
#android.library_references =

# (list) Android shared libraries which will be added to AndroidManifest.xml using <uses-library> tag
#android.uses_library =

# (str) Android logcat filters to use
#android.logcat_filters = *:S python:D

# (bool) Copy library instead of making a libpymodules.so
#android.copy_libs = 1

# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64
android.arch = armeabi-v7a

# (int) overrides automatic versionCode computation (used in build.gradle)
# this is not the same as app version and should only be edited if you know what you're doing
# android.numeric_version = 1

#
# Python for android (p4a) specific
#

# (str) python-for-android fork to use, defaults to upstream (kivy)
#p4a.fork = kivy

# (str) python-for-android branch to use, defaults to master
#p4a.branch = master

# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
#p4a.source_dir =

# (str) The directory in which python-for-android should look for your own build recipes (if any)
#p4a.local_recipes =

# (str) Filename to the hook for p4a
#p4a.hook =

# (str) Bootstrap to use for android builds
# p4a.bootstrap = sdl2

# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)
#p4a.port =


#
# iOS specific
#

# (str) Path to a custom kivy-ios folder
#ios.kivy_ios_dir = ../kivy-ios
# Alternately, specify the URL and branch of a git checkout:
ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master

# Another platform dependency: ios-deploy
# Uncomment to use a custom checkout
#ios.ios_deploy_dir = ../ios_deploy
# Or specify URL and branch
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.7.0

# (str) Name of the certificate to use for signing the debug version
# Get a list of available identities: buildozer ios list_identities
#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"

# (str) Name of the certificate to use for signing the release version
#ios.codesign.release = %(ios.codesign.debug)s


[buildozer]

# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2

# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
warn_on_root = 1

# (str) Path to build artifact storage, absolute or relative to spec file
# build_dir = ./.buildozer

# (str) Path to build output (i.e. .apk, .ipa) storage
# bin_dir = ./bin

#    -----------------------------------------------------------------------------
#    List as sections
#
#    You can define all the "list" as [section:key].
#    Each line will be considered as a option to the list.
#    Let's take [app] / source.exclude_patterns.
#    Instead of doing:
#
#[app]
#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
#
#    This can be translated into:
#
#[app:source.exclude_patterns]
#license
#data/audio/*.wav
#data/images/original/*
#


#    -----------------------------------------------------------------------------
#    Profiles
#
#    You can extend section / key with a profile
#    For example, you want to deploy a demo version of your application without
#    HD content. You could first change the title to add "(demo)" in the name
#    and extend the excluded directories to remove the HD content.
#
#[app@demo]
#title = My Application (demo)
#
#[app:source.exclude_patterns@demo]
#images/hd/*
#
#    Then, invoke the command line with the "demo" profile:
#
#buildozer --profile demo android debug

If you want to specify things like the icon, requirements, loading screen, etc., you should edit this file. After making all the desired edits to your application, run buildozer -v android debug from your app directory to build and compile your application. This may take a while, especially if you have a slow machine.

After the process is done, your terminal should have some logs, one confirming that the build was successful:

Android successful build

You should also have an APK version of your app in your bin directory. This is the application executable that you will install and run on your phone:

Android .apk in the bin directory

Conclusion

Congratulations! If you have followed this tutorial step by step, you should have a simple random number generator app on your phone. Play around with it and tweak some values, then rebuild. Running the rebuild will not take as much time as the first build.

As you can see, building a mobile application with Python is fairly straightforward, as long as you are familiar with the framework or module you are working with. Regardless, the logic is executed the same way.

Get familiar with the Kivy module and it鈥檚 widgets. You can never know everything all at once. You only need to find a project and get your feet wet as early as possible. Happy coding.

Link: https://blog.logrocket.com/build-android-application-kivy-python-framework/

#python 

Cree Una Aplicaci贸n De Android Con El Marco Kivy Python

Si es un desarrollador de Python que est谩 pensando en comenzar con el desarrollo m贸vil, entonces el marco Kivy es su mejor opci贸n. Con Kivy, puede desarrollar aplicaciones independientes de la plataforma que compilan para iOS, Android, Windows, macOS y Linux. En este art铆culo, cubriremos Android espec铆ficamente porque es el m谩s utilizado.

Construiremos una aplicaci贸n generadora de n煤meros aleatorios simple que puede instalar en su tel茅fono y probar cuando haya terminado. Para continuar con este art铆culo, debe estar familiarizado con Python. 隆Empecemos!

Primeros pasos con Kivy

Primero, necesitar谩 un nuevo directorio para su aplicaci贸n. Aseg煤rese de tener Python instalado en su m谩quina y abra un nuevo archivo de Python. Deber谩 instalar el m贸dulo Kivy desde su terminal usando cualquiera de los comandos a continuaci贸n. Para evitar conflictos de paquetes, aseg煤rese de instalar Kivy en un entorno virtual:

pip install kivy 
//
pip3 install kivy 

Una vez que haya instalado Kivy, deber铆a ver un mensaje de 茅xito de su terminal que se parece a las capturas de pantalla a continuaci贸n:

Instalaci贸n decepcionada

Instalaci贸n exitosa de Kivy

 

A continuaci贸n, navegue a la carpeta de su proyecto. En el main.pyarchivo, necesitaremos importar el m贸dulo Kivy y especificar qu茅 versi贸n queremos. Puede usar Kivy v2.0.0, pero si tiene un tel茅fono inteligente anterior a Android 8.0, le recomiendo usar Kivy v1.9.0. Puede jugar con las diferentes versiones durante la compilaci贸n para ver las diferencias en las caracter铆sticas y el rendimiento.

Agregue el n煤mero de versi贸n justo despu茅s de la import kivyl铆nea de la siguiente manera:

kivy.require('1.9.0')

Ahora, crearemos una clase que b谩sicamente definir谩 nuestra aplicaci贸n; Voy a nombrar el m铆o RandomNumber. Esta clase heredar谩 la appclase de Kivy. Por lo tanto, debe importar appagregando from kivy.app import App:

class RandomNumber(App): 

En la RandomNumberclase, deber谩 agregar una funci贸n llamada build, que toma un selfpar谩metro. Para devolver la interfaz de usuario, usaremos la buildfunci贸n. Por ahora, lo tengo devuelto como una simple etiqueta. Para hacerlo, deber谩 importar Labelusando la l铆nea from kivy.uix.label import Label:

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

class RandomNumber(App):
  def build(self):
    return Label(text="Random Number Generator")

隆Ahora, el esqueleto de nuestra aplicaci贸n est谩 completo! Antes de continuar, debe crear una instancia de la RandomNumberclase y ejecutarla en su terminal o IDE para ver la interfaz:

importar kivy de kivy.app importar aplicaci贸n de kivy.uix.label clase de etiqueta de importaci贸n RandomNumber(App): def build(self): return Label(text="Generador de n煤meros aleatorios") randomApp = RandomNumber() randomApp.run()

Cuando ejecuta la instancia de clase con el texto Random Number Generator, deber铆a ver una interfaz o ventana simple que se parece a la siguiente captura de pantalla:

 

Interfaz simple despu茅s de ejecutar el c贸digo.

No podr谩 ejecutar el texto en Android hasta que haya terminado de construir todo.

Externalizaci贸n de la interfaz

A continuaci贸n, necesitaremos una forma de subcontratar la interfaz. Primero, crearemos un archivo Kivy en nuestro directorio que albergar谩 la mayor parte de nuestro trabajo de dise帽o. Querr谩 nombrar este archivo con el mismo nombre que su clase usando letras min煤sculas y una .kvextensi贸n. Kivy asociar谩 autom谩ticamente el nombre de la clase y el nombre del archivo, pero es posible que no funcione en Android si son exactamente iguales.

Dentro de ese .kvarchivo, debe especificar el dise帽o de su aplicaci贸n, incluidos elementos como la etiqueta, los botones, los formularios, etc. Para simplificar esta demostraci贸n, agregar茅 una etiqueta para el t铆tulo Random Number, una etiqueta que servir谩 como marcador de posici贸n. para el n煤mero aleatorio que se genera _, y un Generatebot贸n que llama a la generatefunci贸n.

Mi .kvarchivo se parece al siguiente c贸digo, pero puede jugar con los diferentes valores para que se ajusten a sus requisitos:

<boxLayout>:
    orientation: "vertical"
    Label:
        text: "Random Number"
        font_size: 30
        color: 0, 0.62, 0.96

    Label:
        text: "_"
        font_size: 30

    Button:
        text: "Generate"
        font_size: 15 

En el main.pyarchivo, ya no necesita la Labeldeclaraci贸n de importaci贸n porque el archivo Kivy se encarga de su interfaz de usuario. Sin embargo, necesita importar boxlayout, que utilizar谩 en el archivo Kivy.

En su archivo principal, debe agregar la declaraci贸n de importaci贸n y editar su main.pyarchivo para leer return BoxLayout()el buildm茅todo:

from kivy.uix.boxlayout import BoxLayout

Si ejecuta el comando anterior, deber铆a ver una interfaz simple que tiene el t铆tulo del n煤mero aleatorio, el _marcador de posici贸n y el generatebot贸n en el que se puede hacer clic:

Aplicaci贸n de n煤meros aleatorios renderizada

Tenga en cuenta que no tuvo que importar nada para que funcione el archivo Kivy. B谩sicamente, cuando ejecuta la aplicaci贸n, regresa boxlayoutbuscando un archivo dentro del archivo Kivy con el mismo nombre que su clase. Tenga en cuenta que esta es una interfaz simple y puede hacer que su aplicaci贸n sea tan robusta como desee. Aseg煤rese de consultar la documentaci贸n del idioma Kv .

Generar la funci贸n de n煤meros aleatorios

Ahora que nuestra aplicaci贸n est谩 casi terminada, necesitaremos una funci贸n simple para generar n煤meros aleatorios cuando un usuario haga clic en el generatebot贸n y luego mostrar ese n煤mero aleatorio en la interfaz de la aplicaci贸n. Para hacerlo, necesitaremos cambiar algunas cosas en nuestros archivos.

Primero, importaremos el m贸dulo que usaremos para generar un n煤mero aleatorio con import random. Luego, crearemos una funci贸n o m茅todo que llame al n煤mero generado. Para esta demostraci贸n, usar茅 un rango entre 0y 2000. Generar el n煤mero aleatorio es simple con el random.randint(0, 2000)comando. Agregaremos esto a nuestro c贸digo en un momento.

A continuaci贸n, crearemos otra clase que ser谩 nuestra propia versi贸n del box layout. Nuestra clase tendr谩 que heredar la box layoutclase, que alberga el m茅todo para generar n煤meros aleatorios y representarlos en la interfaz:

class MyRoot(BoxLayout):
    def __init__(self):
        super(MyRoot, self).__init__()

Dentro de esa clase, crearemos el generatem茅todo, que no solo generar谩 n煤meros aleatorios, sino que tambi茅n manipular谩 la etiqueta que controla lo que se muestra como n煤mero aleatorio en el archivo Kivy.

Para acomodar este m茅todo, primero necesitaremos hacer cambios en el .kvarchivo. Dado que la MyRootclase ha heredado el box layout, puede crear MyRootel elemento de nivel superior en su .kvarchivo:

<MyRoot>:
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Random Number"
            font_size: 30
            color: 0, 0.62, 0.96

        Label:
            text: "_"
            font_size: 30

        Button:
            text: "Generate"
            font_size: 15

Tenga en cuenta que todav铆a mantiene todas las especificaciones de la interfaz de usuario con sangr铆a en el archivo Box Layout. Despu茅s de esto, debe agregar una identificaci贸n a la etiqueta que contendr谩 los n煤meros generados, lo que facilita la manipulaci贸n cuando generatese llama a la funci贸n. Debe especificar la relaci贸n entre la ID en este archivo y otra en el c贸digo principal en la parte superior, justo antes de la BoxLayoutl铆nea:

<MyRoot>:
    random_label: random_label
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Random Number"
            font_size: 30
            color: 0, 0.62, 0.96

        Label:
            id: random_label
            text: "_"
            font_size: 30

        Button:
            text: "Generate"
            font_size: 15

La random_label: random_labell铆nea b谩sicamente significa que la etiqueta con el ID random_labelse asignar谩 a random_labelen el main.pyarchivo, lo que significa que cualquier acci贸n que manipula random_labelser谩n mapeados en la etiqueta con el nombre especificado.

Ahora podemos crear el m茅todo para generar el n煤mero aleatorio en el archivo principal:

def generate_number(self):
    self.random_label.text = str(random.randint(0, 2000))

# notice how the class method manipulates the text attributre of the random label by a# ssigning it a new random number generate by the 'random.randint(0, 2000)' funcion. S# ince this the random number generated is an integer, typecasting is required to make # it a string otherwise you will get a typeError in your terminal when you run it.

La MyRootclase deber铆a parecerse al siguiente c贸digo:

class MyRoot(BoxLayout):
    def __init__(self):
        super(MyRoot, self).__init__()

    def generate_number(self):
        self.random_label.text = str(random.randint(0, 2000))

隆Felicidades! Ya ha terminado con el archivo principal de la aplicaci贸n. Lo 煤nico que queda por hacer es asegurarse de llamar a esta funci贸n cuando se haga generateclic en el bot贸n. Solo necesita agregar la l铆nea on_press: root.generate_number()a la parte de selecci贸n de botones de su .kvarchivo:

<MyRoot>:
    random_label: random_label
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Random Number"
            font_size: 30
            color: 0, 0.62, 0.96

        Label:
            id: random_label
            text: "_"
            font_size: 30

        Button:
            text: "Generate"
            font_size: 15
            on_press: root.generate_number()

Ahora, puede ejecutar la aplicaci贸n.

Compilando nuestra aplicaci贸n en Android

Antes de compilar nuestra aplicaci贸n en Android, tengo malas noticias para los usuarios de Windows. Necesitar谩 Linux o macOS para compilar su aplicaci贸n de Android. Sin embargo, no necesita tener una distribuci贸n de Linux separada, en su lugar, puede usar una m谩quina virtual.

Para compilar y generar una .apkaplicaci贸n Android completa , usaremos una herramienta llamada Buildozer . Instalemos Buildozer a trav茅s de nuestra terminal usando uno de los siguientes comandos:

pip3 install buildozer
//
pip install buildozer

Ahora, instalaremos algunas de las dependencias requeridas de Buildozer. Estoy en Linux Ergo, as铆 que usar茅 comandos espec铆ficos de Linux. Debe ejecutar estos comandos uno por uno:

sudo apt update
sudo apt install -y git zip unzip openjdk-13-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses5-dev libncursesw5-dev libtinfo5 cmake libffi-dev libssl-dev

pip3 install --upgrade Cython==0.29.19 virtualenv 

# add the following line at the end of your ~/.bashrc file
export PATH=$PATH:~/.local/bin/

Despu茅s de ejecutar los comandos espec铆ficos, ejecute buildozer init. Deber铆a ver un resultado similar a la captura de pantalla a continuaci贸n:

Inicializaci贸n exitosa de Buildozer

El comando anterior crea un .specarchivo Buildozer , que puede usar para hacer especificaciones para su aplicaci贸n, incluido el nombre de la aplicaci贸n, el 铆cono, etc. El .specarchivo debe verse como el bloque de c贸digo a continuaci贸n:

[app]

# (str) Title of your application
title = My Application

# (str) Package name
package.name = myapp

# (str) Package domain (needed for android/ios packaging)
package.domain = org.test

# (str) Source code where the main.py live
source.dir = .

# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas

# (list) List of inclusions using pattern matching
#source.include_patterns = assets/*,images/*.png

# (list) Source files to exclude (let empty to not exclude anything)
#source.exclude_exts = spec

# (list) List of directory to exclude (let empty to not exclude anything)
#source.exclude_dirs = tests, bin

# (list) List of exclusions using pattern matching
#source.exclude_patterns = license,images/*/*.jpg

# (str) Application versioning (method 1)
version = 0.1

# (str) Application versioning (method 2)
# version.regex = __version__ = \['"\](.*)['"]
# version.filename = %(source.dir)s/main.py

# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = python3,kivy

# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
# requirements.source.kivy = ../../kivy

# (list) Garden requirements
#garden_requirements =

# (str) Presplash of the application
#presplash.filename = %(source.dir)s/data/presplash.png

# (str) Icon of the application
#icon.filename = %(source.dir)s/data/icon.png

# (str) Supported orientation (one of landscape, sensorLandscape, portrait or all)
orientation = portrait

# (list) List of service to declare
#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY

#
# OSX Specific
#

#
# author = 漏 Copyright Info

# change the major version of python used by the app
osx.python_version = 3

# Kivy version to use
osx.kivy_version = 1.9.1

#
# Android specific
#

# (bool) Indicate if the application should be fullscreen or not
fullscreen = 0

# (string) Presplash background color (for new android toolchain)
# Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
# red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,
# darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,
# olive, purple, silver, teal.
#android.presplash_color = #FFFFFF

# (list) Permissions
#android.permissions = INTERNET

# (int) Target Android API, should be as high as possible.
#android.api = 27

# (int) Minimum API your APK will support.
#android.minapi = 21

# (int) Android SDK version to use
#android.sdk = 20

# (str) Android NDK version to use
#android.ndk = 19b

# (int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi.
#android.ndk_api = 21

# (bool) Use --private data storage (True) or --dir public storage (False)
#android.private_storage = True

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

# (str) Android SDK directory (if empty, it will be automatically downloaded.)
#android.sdk_path =

# (str) ANT directory (if empty, it will be automatically downloaded.)
#android.ant_path =

# (bool) If True, then skip trying to update the Android sdk
# This can be useful to avoid excess Internet downloads or save time
# when an update is due and you just want to test/build your package
# android.skip_update = False

# (bool) If True, then automatically accept SDK license
# agreements. This is intended for automation only. If set to False,
# the default, you will be shown the license when first running
# buildozer.
# android.accept_sdk_license = False

# (str) Android entry point, default is ok for Kivy-based app
#android.entrypoint = org.renpy.android.PythonActivity

# (str) Android app theme, default is ok for Kivy-based app
# android.apptheme = "@android:style/Theme.NoTitleBar"

# (list) Pattern to whitelist for the whole project
#android.whitelist =

# (str) Path to a custom whitelist file
#android.whitelist_src =

# (str) Path to a custom blacklist file
#android.blacklist_src =

# (list) List of Java .jar files to add to the libs so that pyjnius can access
# their classes. Don't add jars that you do not need, since extra jars can slow
# down the build process. Allows wildcards matching, for example:
# OUYA-ODK/libs/*.jar
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar

# (list) List of Java files to add to the android project (can be java or a
# directory containing the files)
#android.add_src =

# (list) Android AAR archives to add (currently works only with sdl2_gradle
# bootstrap)
#android.add_aars =

# (list) Gradle dependencies to add (currently works only with sdl2_gradle
# bootstrap)
#android.gradle_dependencies =

# (list) add java compile options
# this can for example be necessary when importing certain java libraries using the 'android.gradle_dependencies' option
# see https://developer.android.com/studio/write/java8-support for further information
# android.add_compile_options = "sourceCompatibility = 1.8", "targetCompatibility = 1.8"

# (list) Gradle repositories to add {can be necessary for some android.gradle_dependencies}
# please enclose in double quotes 
# e.g. android.gradle_repositories = "maven { url 'https://kotlin.bintray.com/ktor' }"
#android.add_gradle_repositories =

# (list) packaging options to add 
# see https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html
# can be necessary to solve conflicts in gradle_dependencies
# please enclose in double quotes 
# e.g. android.add_packaging_options = "exclude 'META-INF/common.kotlin_module'", "exclude 'META-INF/*.kotlin_module'"
#android.add_gradle_repositories =

# (list) Java classes to add as activities to the manifest.
#android.add_activities = com.example.ExampleActivity

# (str) OUYA Console category. Should be one of GAME or APP
# If you leave this blank, OUYA support will not be enabled
#android.ouya.category = GAME

# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png

# (str) XML file to include as an intent filters in <activity> tag
#android.manifest.intent_filters =

# (str) launchMode to set for the main activity
#android.manifest.launch_mode = standard

# (list) Android additional libraries to copy into libs/armeabi
#android.add_libs_armeabi = libs/android/*.so
#android.add_libs_armeabi_v7a = libs/android-v7/*.so
#android.add_libs_arm64_v8a = libs/android-v8/*.so
#android.add_libs_x86 = libs/android-x86/*.so
#android.add_libs_mips = libs/android-mips/*.so

# (bool) Indicate whether the screen should stay on
# Don't forget to add the WAKE_LOCK permission if you set this to True
#android.wakelock = False

# (list) Android application meta-data to set (key=value format)
#android.meta_data =

# (list) Android library project to add (will be added in the
# project.properties automatically.)
#android.library_references =

# (list) Android shared libraries which will be added to AndroidManifest.xml using <uses-library> tag
#android.uses_library =

# (str) Android logcat filters to use
#android.logcat_filters = *:S python:D

# (bool) Copy library instead of making a libpymodules.so
#android.copy_libs = 1

# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64
android.arch = armeabi-v7a

# (int) overrides automatic versionCode computation (used in build.gradle)
# this is not the same as app version and should only be edited if you know what you're doing
# android.numeric_version = 1

#
# Python for android (p4a) specific
#

# (str) python-for-android fork to use, defaults to upstream (kivy)
#p4a.fork = kivy

# (str) python-for-android branch to use, defaults to master
#p4a.branch = master

# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
#p4a.source_dir =

# (str) The directory in which python-for-android should look for your own build recipes (if any)
#p4a.local_recipes =

# (str) Filename to the hook for p4a
#p4a.hook =

# (str) Bootstrap to use for android builds
# p4a.bootstrap = sdl2

# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)
#p4a.port =


#
# iOS specific
#

# (str) Path to a custom kivy-ios folder
#ios.kivy_ios_dir = ../kivy-ios
# Alternately, specify the URL and branch of a git checkout:
ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master

# Another platform dependency: ios-deploy
# Uncomment to use a custom checkout
#ios.ios_deploy_dir = ../ios_deploy
# Or specify URL and branch
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.7.0

# (str) Name of the certificate to use for signing the debug version
# Get a list of available identities: buildozer ios list_identities
#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"

# (str) Name of the certificate to use for signing the release version
#ios.codesign.release = %(ios.codesign.debug)s


[buildozer]

# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2

# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
warn_on_root = 1

# (str) Path to build artifact storage, absolute or relative to spec file
# build_dir = ./.buildozer

# (str) Path to build output (i.e. .apk, .ipa) storage
# bin_dir = ./bin

#    -----------------------------------------------------------------------------
#    List as sections
#
#    You can define all the "list" as [section:key].
#    Each line will be considered as a option to the list.
#    Let's take [app] / source.exclude_patterns.
#    Instead of doing:
#
#[app]
#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
#
#    This can be translated into:
#
#[app:source.exclude_patterns]
#license
#data/audio/*.wav
#data/images/original/*
#


#    -----------------------------------------------------------------------------
#    Profiles
#
#    You can extend section / key with a profile
#    For example, you want to deploy a demo version of your application without
#    HD content. You could first change the title to add "(demo)" in the name
#    and extend the excluded directories to remove the HD content.
#
#[app@demo]
#title = My Application (demo)
#
#[app:source.exclude_patterns@demo]
#images/hd/*
#
#    Then, invoke the command line with the "demo" profile:
#
#buildozer --profile demo android debug

Si desea especificar cosas como el 铆cono, los requisitos, la pantalla de carga, etc., debe editar este archivo. Despu茅s de realizar todas las ediciones deseadas en su aplicaci贸n, ejecute buildozer -v android debugdesde el directorio de su aplicaci贸n para construir y compilar su aplicaci贸n. Esto puede llevar un tiempo, especialmente si tiene una m谩quina lenta.

Una vez finalizado el proceso, su terminal deber铆a tener algunos registros, uno que confirme que la compilaci贸n fue exitosa:

Construcci贸n exitosa de Android

Tambi茅n debe tener una versi贸n APK de su aplicaci贸n en su directorio bin. Este es el ejecutable de la aplicaci贸n que instalar谩 y ejecutar谩 en su tel茅fono:

Android .apk en el directorio bin

Conclusi贸n

隆Felicidades! Si ha seguido este tutorial paso a paso, deber铆a tener una aplicaci贸n simple de generador de n煤meros aleatorios en su tel茅fono. Juega con 茅l y ajusta algunos valores, luego reconstruye. Ejecutar la reconstrucci贸n no llevar谩 tanto tiempo como la primera compilaci贸n.

Como puede ver, crear una aplicaci贸n m贸vil con Python es bastante sencillo , siempre que est茅 familiarizado con el marco o m贸dulo con el que est谩 trabajando. Independientemente, la l贸gica se ejecuta de la misma manera.

Familiar铆cese con el m贸dulo Kivy y sus widgets. Nunca se puede saber todo a la vez. Solo necesita encontrar un proyecto y mojarse los pies lo antes posible. Codificaci贸n feliz.

Enlace: https://blog.logrocket.com/build-android-application-kivy-python-framework/

#python 

KivyPython銉曘儸銉笺儬銉兗銈倰浣跨敤銇椼仸Android銈€儣銉偙銉笺偡銉с兂銈掓绡夈仚銈

銇傘仾銇熴亴銉€儛銈ゃ儷闁嬬櫤銈掑銈併倠銇撱仺銈掕冦亪銇︺亜銈婸ython闁嬬櫤鑰呫仾銈銆並ivy銉曘儸銉笺儬銉兗銈銇屾渶鍠勩伄绛栥仹銇欍侹ivy銈掍娇鐢ㄣ仚銈嬨仺銆乮OS銆丄ndroid銆乄indows銆乵acOS銆併亰銈堛伋Linux鐢ㄣ伀銈炽兂銉戙偆銉仌銈屻倠銉椼儵銉冦儓銉曘偐銉笺儬銇緷瀛樸仐銇亜銈€儣銉偙銉笺偡銉с兂銈掗枊鐧恒仹銇嶃伨銇欍傘亾銇浜嬨仹銇丄ndroid銇屾渶銈備娇鐢ㄣ仌銈屻仸銇勩倠銇熴倎銆佺壒銇獳ndroid銇仱銇勩仸瑾槑銇椼伨銇欍

绨″崢銇贡鏁般偢銈с儘銉兗銈裤兗銈€儣銉倰浣滄垚銇椼伨銇欍傘亾銇偄銉椼儶銈掓惡甯浕瑭便伀銈ゃ兂銈广儓銉笺儷銇椼仸銆佸畬浜嗐仐銇熴倝銉嗐偣銉堛仹銇嶃伨銇欍傘亾銇浜嬨倰缍氥亼銈嬨伀銇丳ython銇簿閫氥仐銇︺亜銈嬪繀瑕併亴銇傘倞銇俱仚銆傚銈併伨銇椼倗銇嗭紒

Kivy銈掍娇銇勫銈併倠

銇俱仛銆併偄銉椼儶鐢ㄣ伄鏂般仐銇勩儑銈c儸銈儓銉亴蹇呰銇仾銈娿伨銇欍傘優銈枫兂銇玃ython銇屻偆銉炽偣銉堛兗銉仌銈屻仸銇勩倠銇撱仺銈掔⒑瑾嶃仐銆佹柊銇椼亜Python銉曘偂銈ゃ儷銈掗枊銇嶃伨銇欍備互涓嬨伄銈炽優銉炽儔銇亜銇氥倢銇嬨倰浣跨敤銇椼仸銆併偪銉笺儫銉娿儷銇嬨倝Kivy銉€偢銉ャ兗銉倰銈ゃ兂銈广儓銉笺儷銇欍倠蹇呰銇屻亗銈娿伨銇欍傘儜銉冦偙銉笺偢銇鍚堛倰閬裤亼銈嬨仧銈併伀銆並ivy銈掍划鎯崇挵澧冦伀銈ゃ兂銈广儓銉笺儷銇椼仸銇勩倠銇撱仺銈掔⒑瑾嶃仐銇︺亸銇犮仌銇勩

pip install kivy 
//
pip3 install kivy 

Kivy銈掋偆銉炽偣銉堛兗銉仚銈嬨仺銆佷互涓嬨伄銈广偗銉兗銉炽偡銉с儍銉堛伄銈堛亞銇垚鍔熴儭銉冦偦銉笺偢銇屻偪銉笺儫銉娿儷銇嬨倝琛ㄧず銇曘倢銇俱仚銆

銇屻仯銇嬨倞銇椼仧銈ゃ兂銈广儓銉笺儷

Kivy銇偆銉炽偣銉堛兗銉伀鎴愬姛

 

娆°伀銆併儣銉偢銈с偗銉堛儠銈┿儷銉銇Щ鍕曘仐銇俱仚銆傘亾銇main.py銉曘偂銈ゃ儷銇с並ivy銉€偢銉ャ兗銉倰銈ゃ兂銉濄兗銉堛仐銆佸繀瑕併仾銉愩兗銈搞儳銉炽倰鎸囧畾銇欍倠蹇呰銇屻亗銈娿伨銇欍侹ivy v2.0.0銈掍娇鐢ㄣ仹銇嶃伨銇欍亴銆丄ndroid 8.0銈堛倞鍙ゃ亜銈广優銉笺儓銉曘偐銉炽倰浣跨敤銇椼仸銇勩倠鍫村悎銇並ivyv1.9.0銈掍娇鐢ㄣ仚銈嬨亾銇ㄣ倰銇婂嫥銈併仐銇俱仚銆傘儞銉儔涓伀銇曘伨銇栥伨銇儛銉笺偢銉с兂銈掋亜銇樸仯銇︺佹鑳姐仺銉戙儠銈┿兗銉炪兂銈广伄閬曘亜銈掔⒑瑾嶃仹銇嶃伨銇欍

import kivy娆°伄銈堛亞銇佽銇洿寰屻伀銉愩兗銈搞儳銉崇暘鍙枫倰杩藉姞銇椼伨銇欍

kivy.require('1.9.0')

娆°伀銆佸熀鏈殑銇偄銉椼儶銈掑畾缇┿仚銈嬨偗銉┿偣銈掍綔鎴愩仐銇俱仚銆傜銇悕鍓嶃倰浠樸亼銇俱仚RandomNumber銆傘亾銇偗銉┿偣銇appKivy銇嬨倝銈儵銈广倰缍欐壙銇椼伨銇欍傘仐銇熴亴銇c仸銆佹app銈掕拷鍔犮仐銇︺偆銉炽儩銉笺儓銇欍倠蹇呰銇屻亗銈娿伨銇from kivy.app import App

class RandomNumber(App): 

銇с伅RandomNumber銈儵銈广伅銆佸懠銇冲嚭銇曘倢銇熼枹鏁般倰杩藉姞銇欍倠蹇呰銇屻亗銈娿伨銇build銇ㄣ倞銆self銉戙儵銉°兗銈裤倰銆傚疅闅涖伀UI銈掕繑銇欍伀銇併亾銇build闁㈡暟銈掍娇鐢ㄣ仐銇俱仚銆備粖銇仺銇撱倣銆佸崢绱斻仾銉┿儥銉仺銇椼仸杩旈併仐銇︺亜銇俱仚銆傘仢銇仧銈併伀銇佹Label銇銈掍娇鐢ㄣ仐銇︺偆銉炽儩銉笺儓銇欍倠蹇呰銇屻亗銈娿伨銇from kivy.uix.label import Label

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

class RandomNumber(App):
  def build(self):
    return Label(text="Random Number Generator")

銇撱倢銇с併偄銉椼儶銇偣銈便儷銉堛兂銇屽畬鎴愩仐銇俱仐銇熴傚厛銇层個鍓嶃伀銆RandomNumber銈儵銈广伄銈ゃ兂銈广偪銉炽偣銈掍綔鎴愩仐銆併偪銉笺儫銉娿儷銇俱仧銇疘DE銇у疅琛屻仐銇︺併偆銉炽偪銉笺儠銈с偆銈广倰纰鸿獚銇欍倠蹇呰銇屻亗銈娿伨銇欍

import kivy from kivy.app import App from kivy.uix.label import Label class RandomNumber锛圓pp锛夛細def build锛坰elf锛夛細return Label锛坱ext = "Random Number Generator"锛塺andomApp = RandomNumber锛堬級randomApp.run锛堬級

銉嗐偔銈广儓銈掍娇鐢ㄣ仐銇︺偗銉┿偣銈ゃ兂銈广偪銉炽偣銈掑疅琛屻仚銈嬨仺銆Random Number Generator娆°伄銈广偗銉兗銉炽偡銉с儍銉堛伄銈堛亞銇崢绱斻仾銈ゃ兂銈裤兗銉曘偋銈ゃ偣銇俱仧銇偊銈c兂銉夈偊銇岃〃绀恒仌銈屻伨銇欍

 

銈炽兗銉夈倰瀹熻銇椼仧寰屻伄銈枫兂銉椼儷銇偆銉炽偪銉笺儠銈с偆銈

銇欍伖銇︺伄妲嬬瘔銇屽畬浜嗐仚銈嬨伨銇с丄ndroid銇с儐銈偣銉堛倰瀹熻銇欍倠銇撱仺銇仹銇嶃伨銇涖倱銆

銈ゃ兂銈裤兗銉曘偋銉笺偣銇偄銈︺儓銈姐兗銈枫兂銈

娆°伀銆併偆銉炽偪銉笺儠銈с兗銈广倰銈€偊銉堛偨銉笺偡銉炽偘銇欍倠鏂规硶銇屽繀瑕併伀銇倞銇俱仚銆傘伨銇氥併儑銈c儸銈儓銉伀Kivy銉曘偂銈ゃ儷銈掍綔鎴愩仐銇俱仚銆傘亾銇儠銈°偆銉伀銇併伝銇ㄣ倱銇┿伄瑷▓浣滄キ銇屽惈銇俱倢銇︺亜銇俱仚銆傘亾銇儠銈°偆銉伀銇佸皬鏂囧瓧銇.kv鎷″嫉瀛愩倰浣跨敤銇椼仸銆併偗銉┿偣銇ㄥ悓銇樺悕鍓嶃倰浠樸亼銈嬨亾銇ㄣ亴銇с亶銇俱仚銆侹ivy銇偗銉┿偣鍚嶃仺銉曘偂銈ゃ儷鍚嶃倰鑷嫊鐨勩伀闁㈤d粯銇戙伨銇欍亴銆併仢銈屻倝銇屻伨銇c仧銇忓悓銇樸仹銇傘倠鍫村悎銆丄ndroid銇с伅姗熻兘銇椼仾銇勫彲鑳芥с亴銇傘倞銇俱仚銆

銇濄伄.kv銉曘偂銈ゃ儷鍐呫仹銆併儵銉欍儷銆併儨銈裤兂銆併儠銈┿兗銉犮仾銇┿伄瑕佺礌銈掑惈銈銈€儣銉伄銉偆銈€偊銉堛倰鎸囧畾銇欍倠蹇呰銇屻亗銈娿伨銇欍傘亾銇儑銉€倰绨″崢銇仚銈嬨仧銈併伀銆併偪銈ゃ儓銉Random Number銇儵銉欍儷銆併儣銉兗銈广儧銉儉銉笺仺銇椼仸姗熻兘銇欍倠銉┿儥銉倰杩藉姞銇椼伨銇欍傜敓鎴愩仌銈屻倠涔辨暟_銆併亰銈堛伋闁㈡暟Generate銈掑懠銇冲嚭銇欍儨銈裤兂generate

绉併伄.kv銉曘偂銈ゃ儷銇互涓嬨伄銈炽兗銉夈伄銈堛亞銇銇堛伨銇欍亴銆佽浠躲伀鍚堛倧銇涖仸銇曘伨銇栥伨銇ゃ倰銇勩仒銈嬨亾銇ㄣ亴銇с亶銇俱仚銆

<boxLayout>:
    orientation: "vertical"
    Label:
        text: "Random Number"
        font_size: 30
        color: 0, 0.62, 0.96

    Label:
        text: "_"
        font_size: 30

    Button:
        text: "Generate"
        font_size: 15 

銇撱伄main.py銉曘偂銈ゃ儷銇с伅Label銆並ivy銉曘偂銈ゃ儷銇孶I銈掑嚘鐞嗐仚銈嬨仧銈併乮mport銈广儐銉笺儓銉°兂銉堛伅涓嶈銇仾銈娿伨銇椼仧銆傘仧銇犮仐銆boxlayoutKivy銉曘偂銈ゃ儷銇т娇鐢ㄣ仚銈嬨倰銈ゃ兂銉濄兗銉堛仚銈嬪繀瑕併亴銇傘倞銇俱仚銆

銉°偆銉炽儠銈°偆銉仹銆乮mport銈广儐銉笺儓銉°兂銉堛倰杩藉姞銇椼main.py銉曘偂銈ゃ儷銈掔法闆return BoxLayout()銇椼仸build銉°偨銉冦儔銇ц銇垮彇銈嬪繀瑕併亴銇傘倞銇俱仚銆

from kivy.uix.boxlayout import BoxLayout

涓婅銇偝銉炪兂銉夈倰瀹熻銇欍倠銇ㄣ佷贡鏁般伄銈裤偆銉堛儷銆_銉椼儸銉笺偣銉涖儷銉銉笺併亰銈堛伋銈儶銉冦偗鍙兘銇generate銉溿偪銉炽倰鍌欍亪銇熴偡銉炽儣銉仾銈ゃ兂銈裤兗銉曘偋銈ゃ偣銇岃〃绀恒仌銈屻伨銇欍

銉兂銉銉兂銈般仌銈屻仧涔辨暟銈€儣銉

Kivy銉曘偂銈ゃ儷銈掓鑳姐仌銇涖倠銇熴倎銇綍銈傘偆銉炽儩銉笺儓銇欍倠蹇呰銇屻仾銇嬨仯銇熴亾銇ㄣ伀娉ㄦ剰銇椼仸銇忋仩銇曘亜銆傚熀鏈殑銇併偄銉椼儶銈掑疅琛屻仚銈boxlayout銇ㄣ併偗銉┿偣銇ㄥ悓銇樺悕鍓嶃伄Kivy銉曘偂銈ゃ儷鍐呫伄銉曘偂銈ゃ儷銈掓绱€仐銇︽埢銈娿伨銇欍傘亾銈屻伅銈枫兂銉椼儷銇偆銉炽偪銉笺儠銈с兗銈广仹銇傘倞銆併偄銉椼儶銈掑繀瑕併伀蹇溿仒銇﹀爡鐗€伀銇欍倠銇撱仺銇屻仹銇嶃伨銇欍Kv瑷瑾炪伄銉夈偔銉ャ儭銉炽儓銈蹇呫仛纰鸿獚銇椼仸銇忋仩銇曘亜銆

涔辨暟闁㈡暟銈掔敓鎴愩仚銈

銈€儣銉亴銇汇伡瀹屾垚銇椼仧銇仹銆併儲銉笺偠銉笺亴generate銉溿偪銉炽倰銈儶銉冦偗銇椼仧銇ㄣ亶銇贡鏁般倰鐢熸垚銇椼併仢銇贡鏁般倰銈€儣銉伄銈ゃ兂銈裤兗銉曘偋銈ゃ偣銇儸銉炽儉銉兂銈般仚銈嬬啊鍗樸仾闁㈡暟銇屽繀瑕併伀銇倞銇俱仚銆傘仢銇仧銈併伀銇併儠銈°偆銉唴銇亜銇忋仱銇嬨伄澶夋洿銈掕銇嗗繀瑕併亴銇傘倞銇俱仚銆

銇俱仛銆併仹涔辨暟銈掔敓鎴愩仚銈嬨仧銈併伀浣跨敤銇欍倠銉€偢銉ャ兗銉倰銈ゃ兂銉濄兗銉堛仐銇俱仚import random銆傛銇佺敓鎴愩仌銈屻仧鐣彿銈掑懠銇冲嚭銇欓枹鏁般伨銇熴伅銉°偨銉冦儔銈掍綔鎴愩仐銇俱仚銆傘亾銇儑銉€仹銇佺銇枔銇瘎鍥层倰浣跨敤銇椼伨銇02000銆傘亾銇random.randint(0, 2000)銈炽優銉炽儔銈掍娇鐢ㄣ仚銈嬨仺銆佷贡鏁般倰绨″崢銇敓鎴愩仹銇嶃伨銇欍傘亾銈屻倰銇欍亹銇偝銉笺儔銇拷鍔犮仐銇俱仚銆

娆°伀銆佺嫭鑷伄銉愩兗銈搞儳銉炽仺銇倠鍒ャ伄銈儵銈广倰浣滄垚銇椼伨銇box layout銆傘亾銇box layout銈儵銈广伅銆佷贡鏁般倰鐢熸垚銇椼仸銈ゃ兂銈裤兗銉曘偋銈ゃ偣涓娿仹銉兂銉銉兂銈般仚銈嬨儭銈姐儍銉夈倰鍚個銈儵銈广倰缍欐壙銇欍倠蹇呰銇屻亗銈娿伨銇欍

class MyRoot(BoxLayout):
    def __init__(self):
        super(MyRoot, self).__init__()

銇濄伄銈儵銈瑰唴銇сgenerate涔辨暟銈掔敓鎴愩仚銈嬨仩銇戙仹銇亸銆並ivy銉曘偂銈ゃ儷銇贡鏁般仺銇椼仸琛ㄧず銇曘倢銈嬨倐銇倰鍒跺尽銇欍倠銉┿儥銉倰鎿嶄綔銇欍倠銉°偨銉冦儔銈掍綔鎴愩仐銇俱仚銆

銇撱伄鏂规硶銇蹇溿仚銈嬨伀銇佹渶鍒濄伀.kv銉曘偂銈ゃ儷銇鏇淬倰鍔犮亪銈嬪繀瑕併亴銇傘倞銇俱仚銆備互鏉MyRoot銈儵銈广亴缍欐壙銇椼仸銇勩倠box layout銆併亗銇仧銇屼綔銈嬨亾銇ㄣ亴銇с亶銈MyRoot銇傘仾銇熴伄銉堛儍銉椼儸銉欍儷銇绱.kv銉曘偂銈ゃ儷銈掞細

<MyRoot>:
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Random Number"
            font_size: 30
            color: 0, 0.62, 0.96

        Label:
            text: "_"
            font_size: 30

        Button:
            text: "Generate"
            font_size: 15

銇с偆銉炽儑銉炽儓銇曘倢銇熴仚銇广仸銇甎I浠曟銈掍繚鎸併仐銇︺亜銈嬨亾銇ㄣ伀娉ㄦ剰銇椼仸銇忋仩銇曘亜Box Layout銆傘亾銇緦銆佺敓鎴愩仌銈屻仧鐣彿銈掍繚鎸併仚銈婭D銈掋儵銉欍儷銇拷鍔犮仐銇︺generate闁㈡暟銇屽懠銇冲嚭銇曘倢銇熴仺銇嶃伀绨″崢銇搷浣溿仹銇嶃倠銈堛亞銇仚銈嬪繀瑕併亴銇傘倞銇俱仚銆傘亾銇儠銈°偆銉伄ID銇ㄣ佷笂閮ㄣ伄銉°偆銉炽偝銉笺儔銇垾銇甀D銇ㄣ伄闁總銈掋佹銇BoxLayout琛屻伄鐩村墠銇寚瀹氥仚銈嬪繀瑕併亴銇傘倞銇俱仚銆

<MyRoot>:
    random_label: random_label
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Random Number"
            font_size: 30
            color: 0, 0.62, 0.96

        Label:
            id: random_label
            text: "_"
            font_size: 30

        Button:
            text: "Generate"
            font_size: 15

銇撱伄random_label: random_label琛屻伅鍩烘湰鐨勩伀銆両Drandom_label銈掓寔銇ゃ儵銉欍儷銇屻儠銈°偆銉random_label鍐呫伀銉炪儍銉椼仌銈屻倠銇撱仺銈main.py鎰忓懗銇椼伨銇欍傘仱銇俱倞銆佹搷浣random_label銇欍倠銈€偗銈枫儳銉炽伅銇欍伖銇︺佹寚瀹氥仌銈屻仧鍚嶅墠銇儵銉欍儷銇優銉冦儣銇曘倢銇俱仚銆

銇撱倢銇с併儭銈ゃ兂銉曘偂銈ゃ儷銇贡鏁般倰鐢熸垚銇欍倠銉°偨銉冦儔銈掍綔鎴愩仹銇嶃伨銇欍

def generate_number(self):
    self.random_label.text = str(random.randint(0, 2000))

# notice how the class method manipulates the text attributre of the random label by a# ssigning it a new random number generate by the 'random.randint(0, 2000)' funcion. S# ince this the random number generated is an integer, typecasting is required to make # it a string otherwise you will get a typeError in your terminal when you run it.

MyRoot銇撱伄銈儵銈广伅銆佷互涓嬨伄銈炽兗銉夈伄銈堛亞銇仾銈娿伨銇欍

class MyRoot(BoxLayout):
    def __init__(self):
        super(MyRoot, self).__init__()

    def generate_number(self):
        self.random_label.text = str(random.randint(0, 2000))

銇娿倎銇с仺銇嗭紒銇撱倢銇с併偄銉椼儶銇儭銈ゃ兂銉曘偂銈ゃ儷銇屽畬鎴愩仐銇俱仐銇熴傘亗銇ㄣ伅銆generate銉溿偪銉炽亴銈儶銉冦偗銇曘倢銇熴仺銇嶃伀蹇呫仛銇撱伄闁㈡暟銈掑懠銇冲嚭銇欍倛銇嗐伀銇椼仸銇忋仩銇曘亜銆傘儠銈°偆銉伄on_press: root.generate_number()銉溿偪銉抽伕鎶為儴鍒嗐伀琛屻倰杩藉姞銇欍倠銇犮亼銇ф笀銇.kv銇俱仚銆

<MyRoot>:
    random_label: random_label
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Random Number"
            font_size: 30
            color: 0, 0.62, 0.96

        Label:
            id: random_label
            text: "_"
            font_size: 30

        Button:
            text: "Generate"
            font_size: 15
            on_press: root.generate_number()

銇撱倢銇с併偄銉椼儶銈掑疅琛屻仹銇嶃伨銇欍

Android銇с偄銉椼儶銈掋偝銉炽儜銈ゃ儷銇欍倠

Android銇с偄銉椼儶銈掋偝銉炽儜銈ゃ儷銇欍倠鍓嶃伀銆乄indows銉︺兗銈躲兗銇仺銇c仸鎮亜銉嬨儱銉笺偣銇屻亗銈娿伨銇欍侫ndroid銈€儣銉偙銉笺偡銉с兂銈掋偝銉炽儜銈ゃ儷銇欍倠銇伅銆丩inux銇俱仧銇痬acOS銇屽繀瑕併仹銇欍傘仧銇犮仐銆佸嬪垾銇甃inux銉囥偅銈广儓銉儞銉ャ兗銈枫儳銉炽倰鐢ㄦ剰銇欍倠蹇呰銇仾銇忋佷唬銈忋倞銇划鎯炽優銈枫兂銈掍娇鐢ㄣ仹銇嶃伨銇欍

瀹屽叏銇狝ndroid.apk銈€儣銉偙銉笺偡銉с兂銈掋偝銉炽儜銈ゃ儷銇椼仸鐢熸垚銇欍倠銇伅銆Buildozer銇ㄣ亜銇嗐儎銉笺儷銈掍娇鐢ㄣ仐銇俱仚銆備互涓嬨伄銈炽優銉炽儔銇亜銇氥倢銇嬨倰浣跨敤銇椼仸銆併偪銉笺儫銉娿儷銇嬨倝Buildozer銈掋偆銉炽偣銉堛兗銉仐銇俱仐銈囥亞銆

pip3 install buildozer
//
pip install buildozer

娆°伀銆丅uildozer銇繀瑕併仾渚濆瓨闁總銇亜銇忋仱銇嬨倰銈ゃ兂銈广儓銉笺儷銇椼伨銇欍傜銇疞inuxErgo銈掍娇鐢ㄣ仐銇︺亜銈嬨伄銇с丩inux鍥烘湁銇偝銉炪兂銉夈倰浣跨敤銇椼伨銇欍傘亾銈屻倝銇偝銉炪兂銉夈倰1銇ゃ仛銇ゅ疅琛屻仚銈嬪繀瑕併亴銇傘倞銇俱仚銆

sudo apt update
sudo apt install -y git zip unzip openjdk-13-jdk python3-pip autoconf libtool pkg-config zlib1g-dev libncurses5-dev libncursesw5-dev libtinfo5 cmake libffi-dev libssl-dev

pip3 install --upgrade Cython==0.29.19 virtualenv 

# add the following line at the end of your ~/.bashrc file
export PATH=$PATH:~/.local/bin/

鐗瑰畾銇偝銉炪兂銉夈倰瀹熻銇椼仧寰屻併倰瀹熻銇buildozer init銇俱仚銆備互涓嬨伄銈广偗銉兗銉炽偡銉с儍銉堛伄銈堛亞銇嚭鍔涖亴琛ㄧず銇曘倢銇俱仚銆

Buildozer銇垵鏈熷寲銇屾垚鍔熴仐銇俱仐銇

涓婅銇偝銉炪兂銉夈伅Buildozer.spec銉曘偂銈ゃ儷銈掍綔鎴愩仐銇俱仚銆傘亾銇儠銈°偆銉倰浣跨敤銇椼仸銆併偄銉椼儶銇悕鍓嶃倓銈€偆銈炽兂銇仼銈掋偄銉椼儶銇寚瀹.spec銇с亶銇俱仚銆傘儠銈°偆銉伅娆°伄銈炽兗銉夈儢銉儍銈伄銈堛亞銇仾銈娿伨銇欍

[app]

# (str) Title of your application
title = My Application

# (str) Package name
package.name = myapp

# (str) Package domain (needed for android/ios packaging)
package.domain = org.test

# (str) Source code where the main.py live
source.dir = .

# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas

# (list) List of inclusions using pattern matching
#source.include_patterns = assets/*,images/*.png

# (list) Source files to exclude (let empty to not exclude anything)
#source.exclude_exts = spec

# (list) List of directory to exclude (let empty to not exclude anything)
#source.exclude_dirs = tests, bin

# (list) List of exclusions using pattern matching
#source.exclude_patterns = license,images/*/*.jpg

# (str) Application versioning (method 1)
version = 0.1

# (str) Application versioning (method 2)
# version.regex = __version__ = \['"\](.*)['"]
# version.filename = %(source.dir)s/main.py

# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = python3,kivy

# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
# requirements.source.kivy = ../../kivy

# (list) Garden requirements
#garden_requirements =

# (str) Presplash of the application
#presplash.filename = %(source.dir)s/data/presplash.png

# (str) Icon of the application
#icon.filename = %(source.dir)s/data/icon.png

# (str) Supported orientation (one of landscape, sensorLandscape, portrait or all)
orientation = portrait

# (list) List of service to declare
#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY

#
# OSX Specific
#

#
# author = 漏 Copyright Info

# change the major version of python used by the app
osx.python_version = 3

# Kivy version to use
osx.kivy_version = 1.9.1

#
# Android specific
#

# (bool) Indicate if the application should be fullscreen or not
fullscreen = 0

# (string) Presplash background color (for new android toolchain)
# Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
# red, blue, green, black, white, gray, cyan, magenta, yellow, lightgray,
# darkgray, grey, lightgrey, darkgrey, aqua, fuchsia, lime, maroon, navy,
# olive, purple, silver, teal.
#android.presplash_color = #FFFFFF

# (list) Permissions
#android.permissions = INTERNET

# (int) Target Android API, should be as high as possible.
#android.api = 27

# (int) Minimum API your APK will support.
#android.minapi = 21

# (int) Android SDK version to use
#android.sdk = 20

# (str) Android NDK version to use
#android.ndk = 19b

# (int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi.
#android.ndk_api = 21

# (bool) Use --private data storage (True) or --dir public storage (False)
#android.private_storage = True

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

# (str) Android SDK directory (if empty, it will be automatically downloaded.)
#android.sdk_path =

# (str) ANT directory (if empty, it will be automatically downloaded.)
#android.ant_path =

# (bool) If True, then skip trying to update the Android sdk
# This can be useful to avoid excess Internet downloads or save time
# when an update is due and you just want to test/build your package
# android.skip_update = False

# (bool) If True, then automatically accept SDK license
# agreements. This is intended for automation only. If set to False,
# the default, you will be shown the license when first running
# buildozer.
# android.accept_sdk_license = False

# (str) Android entry point, default is ok for Kivy-based app
#android.entrypoint = org.renpy.android.PythonActivity

# (str) Android app theme, default is ok for Kivy-based app
# android.apptheme = "@android:style/Theme.NoTitleBar"

# (list) Pattern to whitelist for the whole project
#android.whitelist =

# (str) Path to a custom whitelist file
#android.whitelist_src =

# (str) Path to a custom blacklist file
#android.blacklist_src =

# (list) List of Java .jar files to add to the libs so that pyjnius can access
# their classes. Don't add jars that you do not need, since extra jars can slow
# down the build process. Allows wildcards matching, for example:
# OUYA-ODK/libs/*.jar
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar

# (list) List of Java files to add to the android project (can be java or a
# directory containing the files)
#android.add_src =

# (list) Android AAR archives to add (currently works only with sdl2_gradle
# bootstrap)
#android.add_aars =

# (list) Gradle dependencies to add (currently works only with sdl2_gradle
# bootstrap)
#android.gradle_dependencies =

# (list) add java compile options
# this can for example be necessary when importing certain java libraries using the 'android.gradle_dependencies' option
# see https://developer.android.com/studio/write/java8-support for further information
# android.add_compile_options = "sourceCompatibility = 1.8", "targetCompatibility = 1.8"

# (list) Gradle repositories to add {can be necessary for some android.gradle_dependencies}
# please enclose in double quotes 
# e.g. android.gradle_repositories = "maven { url 'https://kotlin.bintray.com/ktor' }"
#android.add_gradle_repositories =

# (list) packaging options to add 
# see https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html
# can be necessary to solve conflicts in gradle_dependencies
# please enclose in double quotes 
# e.g. android.add_packaging_options = "exclude 'META-INF/common.kotlin_module'", "exclude 'META-INF/*.kotlin_module'"
#android.add_gradle_repositories =

# (list) Java classes to add as activities to the manifest.
#android.add_activities = com.example.ExampleActivity

# (str) OUYA Console category. Should be one of GAME or APP
# If you leave this blank, OUYA support will not be enabled
#android.ouya.category = GAME

# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png

# (str) XML file to include as an intent filters in <activity> tag
#android.manifest.intent_filters =

# (str) launchMode to set for the main activity
#android.manifest.launch_mode = standard

# (list) Android additional libraries to copy into libs/armeabi
#android.add_libs_armeabi = libs/android/*.so
#android.add_libs_armeabi_v7a = libs/android-v7/*.so
#android.add_libs_arm64_v8a = libs/android-v8/*.so
#android.add_libs_x86 = libs/android-x86/*.so
#android.add_libs_mips = libs/android-mips/*.so

# (bool) Indicate whether the screen should stay on
# Don't forget to add the WAKE_LOCK permission if you set this to True
#android.wakelock = False

# (list) Android application meta-data to set (key=value format)
#android.meta_data =

# (list) Android library project to add (will be added in the
# project.properties automatically.)
#android.library_references =

# (list) Android shared libraries which will be added to AndroidManifest.xml using <uses-library> tag
#android.uses_library =

# (str) Android logcat filters to use
#android.logcat_filters = *:S python:D

# (bool) Copy library instead of making a libpymodules.so
#android.copy_libs = 1

# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64
android.arch = armeabi-v7a

# (int) overrides automatic versionCode computation (used in build.gradle)
# this is not the same as app version and should only be edited if you know what you're doing
# android.numeric_version = 1

#
# Python for android (p4a) specific
#

# (str) python-for-android fork to use, defaults to upstream (kivy)
#p4a.fork = kivy

# (str) python-for-android branch to use, defaults to master
#p4a.branch = master

# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
#p4a.source_dir =

# (str) The directory in which python-for-android should look for your own build recipes (if any)
#p4a.local_recipes =

# (str) Filename to the hook for p4a
#p4a.hook =

# (str) Bootstrap to use for android builds
# p4a.bootstrap = sdl2

# (int) port number to specify an explicit --port= p4a argument (eg for bootstrap flask)
#p4a.port =


#
# iOS specific
#

# (str) Path to a custom kivy-ios folder
#ios.kivy_ios_dir = ../kivy-ios
# Alternately, specify the URL and branch of a git checkout:
ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master

# Another platform dependency: ios-deploy
# Uncomment to use a custom checkout
#ios.ios_deploy_dir = ../ios_deploy
# Or specify URL and branch
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.7.0

# (str) Name of the certificate to use for signing the debug version
# Get a list of available identities: buildozer ios list_identities
#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"

# (str) Name of the certificate to use for signing the release version
#ios.codesign.release = %(ios.codesign.debug)s


[buildozer]

# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2

# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
warn_on_root = 1

# (str) Path to build artifact storage, absolute or relative to spec file
# build_dir = ./.buildozer

# (str) Path to build output (i.e. .apk, .ipa) storage
# bin_dir = ./bin

#    -----------------------------------------------------------------------------
#    List as sections
#
#    You can define all the "list" as [section:key].
#    Each line will be considered as a option to the list.
#    Let's take [app] / source.exclude_patterns.
#    Instead of doing:
#
#[app]
#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
#
#    This can be translated into:
#
#[app:source.exclude_patterns]
#license
#data/audio/*.wav
#data/images/original/*
#


#    -----------------------------------------------------------------------------
#    Profiles
#
#    You can extend section / key with a profile
#    For example, you want to deploy a demo version of your application without
#    HD content. You could first change the title to add "(demo)" in the name
#    and extend the excluded directories to remove the HD content.
#
#[app@demo]
#title = My Application (demo)
#
#[app:source.exclude_patterns@demo]
#images/hd/*
#
#    Then, invoke the command line with the "demo" profile:
#
#buildozer --profile demo android debug

銈€偆銈炽兂銆佽浠躲併儹銉笺儔鐢婚潰銇仼銈掓寚瀹氥仚銈嬪牬鍚堛伅銆併亾銇儠銈°偆銉倰绶ㄩ泦銇欍倠蹇呰銇屻亗銈娿伨銇欍傘偄銉椼儶銈便兗銈枫儳銉炽伀蹇呰銇仚銇广仸銇法闆嗐倰琛屻仯銇熷緦buildozer -v android debug銆併偄銉椼儶銉囥偅銉偗銉堛儶銇嬨倝瀹熻銇椼仸銆併偄銉椼儶銈便兗銈枫儳銉炽倰銉撱儷銉夈亰銈堛伋銈炽兂銉戙偆銉仐銇俱仚銆傜壒銇綆閫熴伄銉炪偡銉炽倰浣跨敤銇椼仸銇勩倠鍫村悎銇併亾銈屻伀鏅傞枔銇屻亱銇嬨倠銇撱仺銇屻亗銈娿伨銇欍

銉椼儹銈汇偣銇屽畬浜嗐仚銈嬨仺銆佺鏈伀銇勩亸銇ゃ亱銇儹銈般亴琛ㄧず銇曘倢銆併儞銉儔銇屾垚鍔熴仐銇熴亾銇ㄣ倰纰鸿獚銇с亶銇俱仚銆

Android銇垚鍔熴仐銇熴儞銉儔

銇俱仧銆乥in銉囥偅銉偗銉堛儶銇偄銉椼儶銇瓵PK銉愩兗銈搞儳銉炽亴蹇呰銇с仚銆傘亾銈屻伅銆佹惡甯浕瑭便伀銈ゃ兂銈广儓銉笺儷銇椼仸瀹熻銇欍倠銈€儣銉偙銉笺偡銉с兂銇疅琛屽彲鑳姐儠銈°偆銉仹銇欍

bin銉囥偅銉偗銉堛儶銇瓵ndroid.apk

绲愯珫

銇娿倎銇с仺銇嗭紒銇撱伄銉併儱銉笺儓銉偄銉倰銈广儐銉冦儣銉愩偆銈广儐銉冦儣銇у疅琛屻仐銇熷牬鍚堛伅銆侀浕瑭便伀鍗樼磾銇贡鏁般偢銈с儘銉兗銈裤兗銈€儣銉亴銈ゃ兂銈广儓銉笺儷銇曘倢銇︺亜銈嬨伅銇氥仹銇欍傘仢銈屻倰銇勩仒銇c仸銆併亜銇忋仱銇嬨伄鍊ゃ倰寰鏁淬仐銇︺亱銈夈佸啀妲嬬瘔銇椼仸銇忋仩銇曘亜銆傚啀妲嬬瘔銇疅琛屻伅銆佹渶鍒濄伄銉撱儷銉夈伝銇╂檪闁撱伅銇嬨亱銈娿伨銇涖倱銆

銇旇Η銇仺銇娿倞銆丳ython銈掍娇鐢ㄣ仐銇熴儮銉愩偆銉偄銉椼儶銈便兗銈枫儳銉炽伄妲嬬瘔銇佷娇鐢ㄣ仐銇︺亜銈嬨儠銉兗銉犮儻銉笺偗銇俱仧銇儮銈搞儱銉笺儷銇簿閫氥仐銇︺亜銈嬮檺銈娿銇嬨仾銈婄啊鍗銇с仚銆傘仺銇亱銇忋併儹銈搞儍銈伅鍚屻仒鏂规硶銇у疅琛屻仌銈屻伨銇欍

Kivy銉€偢銉ャ兗銉仺銇濄伄銈︺偅銈搞偋銉冦儓銇叄銈屻仸銇忋仩銇曘亜銆傘仚銇广仸銈掍竴搴︺伀鐭ャ倠銇撱仺銇仹銇嶃伨銇涖倱銆傘儣銉偢銈с偗銉堛倰瑕嬨仱銇戙仸銆併仹銇嶃倠銇犮亼鏃┿亸瓒炽倰婵°倝銇欍仩銇戙仹銇欍傘儚銉冦償銉笺偝銉笺儑銈c兂銈般

銉兂銈細https//blog.logrocket.com/build-android-application-kivy-python-framework/

#python 

Google's Flutter 1.20 stable announced with new features - Navoki

Flutter Google cross-platform UI framework has released a new version 1.20 stable.

Flutter is Google鈥檚 UI framework to make apps for Android, iOS, Web, Windows, Mac, Linux, and Fuchsia OS. Since the last 2 years, the flutter Framework has already achieved popularity among mobile developers to develop Android and iOS apps. In the last few releases, Flutter also added the support of making web applications and desktop applications.

Last month they introduced the support of the Linux desktop app that can be distributed through Canonical Snap Store(Snapcraft), this enables the developers to publish there Linux desktop app for their users and publish on Snap Store.  If you want to learn how to Publish Flutter Desktop app in Snap Store that here is the tutorial.

Flutter 1.20 Framework is built on Google鈥檚 made Dart programming language that is a cross-platform language providing native performance, new UI widgets, and other more features for the developer usage.

Here are the few key points of this release:

Performance improvements for Flutter and Dart

In this release, they have got multiple performance improvements in the Dart language itself. A new improvement is to reduce the app size in the release versions of the app. Another performance improvement is to reduce junk in the display of app animation by using the warm-up phase.

sksl_warm-up

If your app is junk information during the first run then the Skia Shading Language shader provides for pre-compilation as part of your app鈥檚 build. This can speed it up by more than 2x.

Added a better support of mouse cursors for web and desktop flutter app,. Now many widgets will show cursor on top of them or you can specify the type of supported cursor you want.

Autofill for mobile text fields

Autofill was already supported in native applications now its been added to the Flutter SDK. Now prefilled information stored by your OS can be used for autofill in the application. This feature will be available soon on the flutter web.

flutter_autofill

A new widget for interaction

InteractiveViewer is a new widget design for common interactions in your app like pan, zoom drag and drop for resizing the widget. Informations on this you can check more on this API documentation where you can try this widget on the DartPad. In this release, drag-drop has more features added like you can know precisely where the drop happened and get the position.

Updated Material Slider, RangeSlider, TimePicker, and DatePicker

In this new release, there are many pre-existing widgets that were updated to match the latest material guidelines, these updates include better interaction with Slider and RangeSliderDatePicker with support for date range and time picker with the new style.

flutter_DatePicker

New pubspec.yaml format

Other than these widget updates there is some update within the project also like in pubspec.yaml file format. If you are a flutter plugin publisher then your old pubspec.yaml  is no longer supported to publish a plugin as the older format does not specify for which platform plugin you are making. All existing plugin will continue to work with flutter apps but you should make a plugin update as soon as possible.

Preview of embedded Dart DevTools in Visual Studio Code

Visual Studio code flutter extension got an update in this release. You get a preview of new features where you can analyze that Dev tools in your coding workspace. Enable this feature in your vs code by _dart.previewEmbeddedDevTools_setting. Dart DevTools menu you can choose your favorite page embed on your code workspace.

Network tracking

The updated the Dev tools comes with the network page that enables network profiling. You can track the timings and other information like status and content type of your** network calls** within your app. You can also monitor gRPC traffic.

Generate type-safe platform channels for platform interop

Pigeon is a command-line tool that will generate types of safe platform channels without adding additional dependencies. With this instead of manually matching method strings on platform channel and serializing arguments, you can invoke native class and pass nonprimitive data objects by directly calling the Dartmethod.

There is still a long list of updates in the new version of Flutter 1.2 that we cannot cover in this blog. You can get more details you can visit the official site to know more. Also, you can subscribe to the Navoki newsletter to get updates on these features and upcoming new updates and lessons. In upcoming new versions, we might see more new features and improvements.

You can get more free Flutter tutorials you can follow these courses:

#dart #developers #flutter #app developed #dart devtools in visual studio code #firebase local emulator suite in flutter #flutter autofill #flutter date picker #flutter desktop linux app build and publish on snapcraft store #flutter pigeon #flutter range slider #flutter slider #flutter time picker #flutter tutorial #flutter widget #google flutter #linux #navoki #pubspec format #setup flutter desktop on windows

Fredy  Larson

Fredy Larson

1595059664

How long does it take to develop/build an app?

With more of us using smartphones, the popularity of mobile applications has exploded. In the digital era, the number of people looking for products and services online is growing rapidly. Smartphone owners look for mobile applications that give them quick access to companies鈥 products and services. As a result, mobile apps provide customers with a lot of benefits in just one device.

Likewise, companies use mobile apps to increase customer loyalty and improve their services. Mobile Developers are in high demand as companies use apps not only to create brand awareness but also to gather information. For that reason, mobile apps are used as tools to collect valuable data from customers to help companies improve their offer.

There are many types of mobile applications, each with its own advantages. For example, native apps perform better, while web apps don鈥檛 need to be customized for the platform or operating system (OS). Likewise, hybrid apps provide users with comfortable user experience. However, you may be wondering how long it takes to develop an app.

To give you an idea of how long the app development process takes, here鈥檚 a short guide.

App Idea & Research

app-idea-research

_Average time spent: two to five weeks _

This is the initial stage and a crucial step in setting the project in the right direction. In this stage, you brainstorm ideas and select the best one. Apart from that, you鈥檒l need to do some research to see if your idea is viable. Remember that coming up with an idea is easy; the hard part is to make it a reality.

All your ideas may seem viable, but you still have to run some tests to keep it as real as possible. For that reason, when Web Developers are building a web app, they analyze the available ideas to see which one is the best match for the targeted audience.

Targeting the right audience is crucial when you are developing an app. It saves time when shaping the app in the right direction as you have a clear set of objectives. Likewise, analyzing how the app affects the market is essential. During the research process, App Developers must gather information about potential competitors and threats. This helps the app owners develop strategies to tackle difficulties that come up after the launch.

The research process can take several weeks, but it determines how successful your app can be. For that reason, you must take your time to know all the weaknesses and strengths of the competitors, possible app strategies, and targeted audience.

The outcomes of this stage are app prototypes and the minimum feasible product.

#android app #frontend #ios app #minimum viable product (mvp) #mobile app development #web development #android app development #app development #app development for ios and android #app development process #ios and android app development #ios app development #stages in app development