【问题标题】:Android app close immediately. Compiling via buildozer p4aAndroid 应用程序立即关闭。通过 buildozer p4a 编译
【发布时间】:2021-03-31 18:21:54
【问题描述】:

我正在为通过 UDP 通信的 2 轮机器人编写应用程序。在 PC 上一切正常,但在通过 buildozer 为 android 编译后就不起作用了。

这是来自 logcat

    - waiting for device -
--------- beginning of crash
--------- beginning of system
--------- beginning of main
12-22 01:36:59.225 30049 30093 I python  : Initializing Python for Android
12-22 01:36:59.225 30049 30093 I python  : Setting additional env vars from p4a_env_vars.txt
12-22 01:36:59.225 30049 30093 I python  : Changing directory to the one provided by ANDROID_ARGUMENT
12-22 01:36:59.225 30049 30093 I python  : /data/user/0/org.msstukangithub.robot/files/app
12-22 01:36:59.225 30049 30093 I python  : Preparing to initialize python
12-22 01:36:59.225 30049 30093 I python  : _python_bundle dir exists
12-22 01:36:59.225 30049 30093 I python  : calculated paths to be...
12-22 01:36:59.225 30049 30093 I python  : /data/user/0/org.msstukangithub.robot/files/app/_python_bundle/stdlib.zip:/data/user/0/org.msstukangithub.robot/files/app/_python_bundle/modules
12-22 01:36:59.225 30049 30093 I python  : set wchar paths...
12-22 01:36:59.265 30049 30093 I python  : Initialized python
12-22 01:36:59.266 30049 30093 I python  : AND: Init threads
12-22 01:36:59.266 30049 30093 I python  : testing python print redirection
12-22 01:36:59.267 30049 30093 I python  : Android path ['.', '/data/user/0/org.msstukangithub.robot/files/app/_python_bundle/stdlib.zip', '/data/user/0/org.msstukangithub.robot/files/app/_python_bundle/modules', '/data/user/0/org.msstukangithub.robot/files/app/_python_bundle/site-packages']
12-22 01:36:59.267 30049 30093 I python  : os.environ is environ({'PATH': '/sbin:/system/sbin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin', 'DOWNLOAD_CACHE': '/data/cache', 'ANDROID_BOOTLOGO': '1', 'ANDROID_ROOT': '/system', 'ANDROID_ASSETS': '/system/app', 'ANDROID_DATA': '/data', 'ANDROID_STORAGE': '', 'EXTERNAL_STORAGE': '/sdcard', 'ASEC_MOUNTPOINT': '/mnt/asec', 'BOOTCLASSPATH': '/system/framework/core-oj.jar:/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/bouncycastle.jar:/system/framework/apache-xml.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/android.hidl.base-V1.0-java.jar:/system/framework/android.hidl.manager-V1.0-java.jar:/system/framework/framework-oahl-backward-compatibility.jar:/system/framework/android.test.base.jar:/system/framework/featurelayer-widget.jar:/system/framework/hwEmui.jar:/system/framework/hwTelephony-common.jar:/system/framework/hwIms-common.jar:/system/framework/hwframework.jar:/system/framework/com.huawei.nfc.jar:/system/framework/org.ifaa.android.manager.jar:/system/framework/hwperf.jar:/system/framework/hwaps.jar:/system/framework/hwcustEmui.jar:/system/framework/hwcustframework.jar:/system/framework/hwcustTelephony-common.jar:/system/framework/servicehost.jar:/system/framework/hwIAwareAL.jar', 'SYSTEMSERVERCLASSPATH': '/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/com.android.location.provider.jar:/system/framework/hwServices.jar:/system/framework/hwWifi-service.jar:/system/framework/hwcustServices.jar:/system/framework/hwcustwifi-service.jar', 'OEM_ROOT': '/product/hw_oem/CLT-L29', 'ODM_PRODUCT': '/odm/hw_odm/CLT-L29', 'CUST_POLICY_DIRS': '/system/emui/base:/system/emui/oversea:/vendor/etc:/odm/etc:/product/etc:/odm/hw_odm/CLT-L29:/product/region_comm/oversea:/preas/oversea:/product/hw_oem/CLT-L29:/preload/CLT-L29/hw/eu:/cust/global:/cust/hw/eu:/product/special_cust/CLT-L29/hw/eu', 'ANDROID_SOCKET_zygote_secondary': '18', 'ANDROID_ENTRYPOINT': 'main.pyc', 'ANDROID_ARGUMENT': '/data/user/0/org.msstukangithub.robot/files/app', 'ANDROID_APP_PATH': '/data/user/0/org.msstukangithub.robot/files/app', 'ANDROID_PRIVATE': '/data/user/0/org.msstukangithub.robot/files', 'ANDROID_UNPACK': '/data/user/0/org.msstukangithub.robot/files/app', 'PYTHONHOME': '/data/user/0/org.msstukangithub.robot/files/app', 'PYTHONPATH': '/data/user/0/org.msstukangithub.robot/files/app:/data/user/0/org.msstukangithub.robot/files/app/lib', 'PYTHONOPTIMIZE': '2', 'P4A_BOOTSTRAP': 'SDL2', 'PYTHON_NAME': 'python', 'P4A_IS_WINDOWED': 'True', 'P4A_ORIENTATION': 'landscape', 'P4A_NUMERIC_VERSION': 'None', 'P4A_MINSDK': '21', 'LC_CTYPE': 'C.UTF-8'})
12-22 01:36:59.267 30049 30093 I python  : Android kivy bootstrap done. __name__ is __main__
12-22 01:36:59.267 30049 30093 I python  : AND: Ran string
12-22 01:36:59.267 30049 30093 I python  : Run user program, change dir and execute entrypoint
12-22 01:36:59.377 30049 30093 I python  : [INFO   ] [Logger      ] Record log in /data/user/0/org.msstukangithub.robot/files/app/.kivy/logs/kivy_20-12-22_3.txt
12-22 01:36:59.377 30049 30093 I python  : [INFO   ] [Kivy        ] v1.11.1
12-22 01:36:59.378 30049 30093 I python  : [INFO   ] [Kivy        ] Installed at "/data/user/0/org.msstukangithub.robot/files/app/_python_bundle/site-packages/kivy/__init__.pyc"
12-22 01:36:59.378 30049 30093 I python  : [INFO   ] [Python      ] v3.8.1 (default, Dec 21 2020, 23:40:42) 
12-22 01:36:59.378 30049 30093 I python  : [Clang 8.0.2 (https://android.googlesource.com/toolchain/clang 40173bab62ec7462
12-22 01:36:59.378 30049 30093 I python  : [INFO   ] [Python      ] Interpreter at ""
12-22 01:36:59.830 30049 30093 I python  : [INFO   ] [Factory     ] 184 symbols loaded
12-22 01:36:59.863 30049 30093 I python  : [INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
12-22 01:37:00.106 30049 30093 I python  : [INFO   ] [Window      ] Provider: sdl2
12-22 01:37:00.124 30049 30093 I python  : [INFO   ] [GL          ] Using the "OpenGL ES 2" graphics system
12-22 01:37:00.125 30049 30093 I python  : [INFO   ] [GL          ] Backend used <sdl2>
12-22 01:37:00.126 30049 30093 I python  : [INFO   ] [GL          ] OpenGL version <b'OpenGL ES 3.2 v1.r14p0-00cet0.0416641283c5d6e2d53c163d0ca99357'>
12-22 01:37:00.126 30049 30093 I python  : [INFO   ] [GL          ] OpenGL vendor <b'ARM'>
12-22 01:37:00.126 30049 30093 I python  : [INFO   ] [GL          ] OpenGL renderer <b'Mali-G72'>
12-22 01:37:00.126 30049 30093 I python  : [INFO   ] [GL          ] OpenGL parsed version: 3, 2
12-22 01:37:00.126 30049 30093 I python  : [INFO   ] [GL          ] Texture max size <8192>
12-22 01:37:00.126 30049 30093 I python  : [INFO   ] [GL          ] Texture max units <16>
12-22 01:37:00.142 30049 30093 I python  : [INFO   ] [Window      ] auto add sdl2 input provider
12-22 01:37:00.143 30049 30093 I python  : [INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
12-22 01:37:00.144 30049 30093 I python  : [WARNING] [Base        ] Unknown <android> provider
12-22 01:37:00.144 30049 30093 I python  : [INFO   ] [Base        ] Start application main loop
12-22 01:37:00.145 30049 30093 I python  : [INFO   ] [Base        ] Leaving application in progress...
12-22 01:37:00.145 30049 30093 I python  :  Traceback (most recent call last):
12-22 01:37:00.145 30049 30093 I python  :    File "kivy/properties.pyx", line 860, in kivy.properties.ObservableDict.__getattr__
12-22 01:37:00.145 30049 30093 I python  :  KeyError: 'GridUnderJoy'
12-22 01:37:00.145 30049 30093 I python  :  
12-22 01:37:00.146 30049 30093 I python  :  During handling of the above exception, another exception occurred:
12-22 01:37:00.146 30049 30093 I python  :  
12-22 01:37:00.146 30049 30093 I python  :  Traceback (most recent call last):
12-22 01:37:00.146 30049 30093 I python  :    File "/home/ms/RoX/.buildozer/android/app/main.py", line 336, in <module>
12-22 01:37:00.146 30049 30093 I python  :    File "/home/ms/RoX/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/RoboT/kivy/app.py", line 855, in run
12-22 01:37:00.146 30049 30093 I python  :    File "/home/ms/RoX/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/RoboT/kivy/base.py", line 504, in runTouchApp
12-22 01:37:00.147 30049 30093 I python  :    File "/home/ms/RoX/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/RoboT/kivy/core/window/window_sdl2.py", line 747, in mainloop
12-22 01:37:00.147 30049 30093 I python  :    File "/home/ms/RoX/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/RoboT/kivy/core/window/window_sdl2.py", line 479, in _mainloop
12-22 01:37:00.147 30049 30093 I python  :    File "/home/ms/RoX/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/RoboT/kivy/base.py", line 339, in idle
12-22 01:37:00.147 30049 30093 I python  :    File "/home/ms/RoX/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/RoboT/kivy/clock.py", line 591, in tick
12-22 01:37:00.148 30049 30093 I python  :    File "kivy/_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events
12-22 01:37:00.148 30049 30093 I python  :    File "kivy/_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events
12-22 01:37:00.148 30049 30093 I python  :    File "kivy/_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events
12-22 01:37:00.148 30049 30093 I python  :    File "kivy/_clock.pyx", line 167, in kivy._clock.ClockEvent.tick
12-22 01:37:00.148 30049 30093 I python  :    File "/home/ms/RoX/.buildozer/android/app/main.py", line 70, in update
12-22 01:37:00.149 30049 30093 I python  :    File "/home/ms/RoX/.buildozer/android/app/main.py", line 97, in WHJoy
12-22 01:37:00.149 30049 30093 I python  :    File "kivy/properties.pyx", line 863, in kivy.properties.ObservableDict.__getattr__
12-22 01:37:00.149 30049 30093 I python  :  AttributeError: 'super' object has no attribute '__getattr__'
12-22 01:37:00.149 30049 30093 I python  : Python for android ended.

也许有人知道为什么在 PC 上运行此程序不会从 las 6 行产生此错误?正是这个 AttributeError: 'super' object has no attribute 'getattr' ? 怎么可能更改 main 中的代码以使其在 android 上运行?或者其他解决问题的方法?

主界面代码

    import time # do sleepa w komunikacji udp
from kivy.uix.widget import Widget
from kivy.uix.behaviors import DragBehavior
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
from threading import Thread
from kivy.properties import NumericProperty, BooleanProperty, ReferenceListProperty, ObjectProperty
#################  For Udp transmission ################
import socket

global Data1, DataToSend, UDP_IP, UDP_PORT
UDP_IP = "192.168.43.168" # IP ESP
UDP_PORT = 4210
MESSAGE = b"Hello, mot*** fu****"
Data1 = [88, 44, 0, 11, 3, 8, 40, 155]   # tymczasowo do testów
DataToSend = bytes(Data1)                # convert na byte aby dało się wysłać
#print("UDP target IP: %s" % UDP_IP)
#("UDP target port: %s" % UDP_PORT)
#print("message: %s" % MESSAGE)
                        # Internet     # UDP
#sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
###########################################################


global StopRunUDP, OnceRunUDP
StopRunUDP, OnceRunUDP = True, False
global WidX, HeiY, valXXY
global AccelX, AccelY, AccelZ, GyroX, GyroY, GyroZ, Battery, Temp
AccelX, AccelY, AccelZ, GyroX, GyroY, GyroZ = 0, 0, 0, 0, 0, 0
Battery, Temp = 0, 0
valXXY = NumericProperty
valXXY = 1

class Circle(DragBehavior, Widget):

    def on_touch_move(self, touch):
        if self.collide_point(*touch.pos):
            tx, ty = touch.pos
            sx, sy = self.pos
        return super(Circle, self).on_touch_move(touch)

    def on_touch_up(self, touch):
        if self.collide_point(*touch.pos):
            #print("\tCircle.on_touch_up:")  # do usnięcia komentaz pogladowy do spr działania
            self.pos = WidX / 2 - self.width / 2, HeiY / 2 - self.height / 2
        return super(Circle, self).on_touch_up(touch)


class GUI(FloatLayout):

    ######   Global   Variables      ######


    global StopRunUDP, OnceRunUDP
    runOnce =BooleanProperty(False) # zmienna do jednorazowego pobrania wid/hei pod joystickiem

###################   Automatyczny updete pozycji #################3
    def __init__(self, **kwargs):
        super(GUI, self).__init__(**kwargs)
        Clock.schedule_interval(self.update, 1/30.0)
        Clock.schedule_interval(self.change_color, 1 / 1)  # !!!!!!!! TO DO ZMIANY
       # Clock.schedule_interval(self.change_color, 1 / 30.0) # !!!!!!!! TO DO ZMIANY
    # clock.schedule uruchamia w każdej wolnej chwili funkcje
    # dzieki temu automatycznie sa aktualizowane wartości label/ variables itd

    def update(self, *args): # args to pusty argument żeby się nie czepiał kompilator w sesie że nic nie robi , ale bez niego nie działa
        if not self.runOnce :
            self.WHJoy()
            self.runOnce=True

        pozX = self.ids.cir.pos[0]+25
        pozY = self.ids.cir.pos[1]+25
        pX, pY = self.calc_Joy(pozX, pozY)

    #
        self.ids.padX.text = ' pad X: %.2f' % pX
        self.ids.padY.text = ' pad Y: %.2f' % pY


    #   #### Updateing Data of Joystick ####
        self.Send_Pos_Joy(pX,pY)

    #   ####   Takeing half wid of showed reactangles ####
        WidRectangle = self.ids.GyXx.width-10
        HalfWidRe= WidRectangle/2
        self.Update_AccelGyro(HalfWidRe)




# ################## Pobranie szerokosci placu pod Joy.. ###############
    def WHJoy(self):  # uruchamiane jdnorazowo aby pobrac szerokość placu pod
                        # joystickiem by móc go wycentrować
        global WidX, HeiY
        WidX = self.ids.GridUnderJoy.size[0]
        HeiY = self.ids.GridUnderJoy.size[1]

#   ####       Updating posytion of joystick to send to ESP ####
    def Send_Pos_Joy(self, pozX, pozY):
        global Data1, DataToSend
        pXx = self.Map_Func(pozX, -50, 50, 0, 100)
        pYy = self.Map_Func(pozY, -50, 50, 0, 100)
        Data1[0] = int(pXx)
        Data1[1] = int(pYy)
        DataToSend = bytes(Data1)
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#  ####        Updateing value in kivy screen                      ####
    def Update_AccelGyro(self,HalfWID):

                # GyroX
        Gyrox = self.Map_Func(GyroX, -32768, 32768, -HalfWID, HalfWID)
        self.ids.valGyroX.text = '%d' % GyroX  # modyfikator tekst
        self.ids.GyroX.sGx = Gyrox
                # GyroY
        Gyroy = self.Map_Func(GyroY, -32768, 32768, -HalfWID, HalfWID)
        self.ids.valGyroY.text = '%d' % GyroY  # modyfikator tekst
        self.ids.GyroY.sGy = Gyroy
                # GyroZ
        Gyroz = self.Map_Func(GyroZ, -32768, 32768, -HalfWID, HalfWID)
        self.ids.valGyroZ.text = '%d' % GyroZ  # modyfikator tekst
        self.ids.GyroZ.sGz = Gyroz
                # AccelX
        Accelx = self.Map_Func(AccelX, -32768, 32768, -HalfWID, HalfWID)
        self.ids.valAccelX.text = '%d' % AccelX  # modyfikator tekst
        self.ids.AccelX.sAx = Accelx
                # AccelY
        Accely = self.Map_Func(AccelY, -32768, 32768, -HalfWID, HalfWID)
        self.ids.valAccelY.text = '%d' % AccelY  # modyfikator tekst
        self.ids.AccelY.sAy = Accely
                # AccelZ
        Accelz = self.Map_Func(AccelZ, -32768, 32768, -HalfWID, HalfWID)
        self.ids.valAccelZ.text = '%d' % AccelZ  # modyfikator tekst
        self.ids.AccelZ.sAz = Accelz
                #Battery
        Baatt = self.Map_Func(Battery, 0, 255, 0, HalfWID*2)
        BtPerCent = self.Map_Func(Battery, 0, 255, 0, 100)
        self.ids.valBattery.text = ' %d ' % BtPerCent + '%' # modyfikator tekst
        self.ids.BATT.sBt = Baatt
        #print(HalfWID*2)
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    def change_color(self, *args):
        ww = Battery
        BatteryColor = (0, 0, 16 / 255, 1)
        if 191 < ww <= 255:  # 255-64
            BatteryColor = (94 / 255, 1, 0, 1)
        elif 128 < ww <= 191:
            BatteryColor = (221 / 255, 1, 0, 1)
        elif 64 < ww <= 128:
            BatteryColor = (1, 140 / 255, 0, 1)
        elif 0 <= ww <= 64:
            BatteryColor = (1, 64 / 255, 0, 1)
        self.ids.BATT.colOf = BatteryColor





# #### Calc position of joystick               #####
    def calc_Joy(self, pozX, pozY):

        if pozX >150: pozX = 150
        elif pozX<50: pozX = 50
        else: pozX = pozX
        UpDo = -(100-pozX)

        if pozY >150: pozY = 150
        elif pozY<50: pozY = 50
        else: pozY = pozY
        LeRi = -(100-pozY)

        return(UpDo,LeRi)
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    ###--------------------------- Dotąd jest G--------------------------###

            ################### map Function #################
    def Map_Func(self, x, minX, maxX, outMin, outMax):
        Out = (x - minX) * (outMax - outMin) / (maxX - minX) + outMin
        #  Out=    Y     *       Z            /      C       + outMin
        # Y/Z/C   ogarnąć zabezpiecznie  ( pamiętaj cholero nie dziel przez zero) , czy python to ogrania i uj z tym?
        return(Out)



    def do_something(self):
        global StopRunUDP, OnceRunUDP
        #print(StopRunUDP)
        if not OnceRunUDP:
            StopRunUDP = True
            OnceRunUDP = True

       # print('after IF')
        #print(StopRunUDP)
        # create the thread to invoke other_func with arguments (2, 5)
        t1 = Thread(target=self.Communication_UDP_ESP)
        # set daemon to true so the thread dies when app is closed
        t1.daemon = True            # Jesli True -> background worker , if false
        # start the thread
        t1.start()


    def Stop_UDP(self):    # Z niewiadomych przyczyn nie uruchamia sie ...
        global StopRunUDP, OnceRunUDP           # próba przynajmniej zkończenia watku other_func
        #print(StopRunUDP)
        StopRunUDP = False
        OnceRunUDP = False
        #print('after StopUDP')
        #print(StopRunUDP)


    def Communication_UDP_ESP(self):
        global StopRunUDP,OnceRunUDP
        global Data1, DataToSend, UDP_IP, UDP_PORT
        global AccelX, AccelY, AccelZ, GyroX, GyroY, GyroZ, Battery, Temp
                                     # Internet     # UDP
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # Tworzenie / podlączenie socketa
        sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
        sock.settimeout(0.3) # najwyrażnej rozwiązło problem , (socket.setblocking)
                    # jesli false to nie mrozi progrmu w oczekiwaniu na dane jesli true , mrozi
        #lost = 1

        def Save_Data_From_ESP(Data):
            global AccelX, AccelY, AccelZ, GyroX, GyroY, GyroZ, Battery, Temp
                        # Battery
            Battery = Data[0]
                        # Temp
            Temp = Data[1] << 8 | Data[2]
                        # Accel X
            AccelXx = Data[3] << 8 | Data[4]
            AccelX = self.Map_Func(AccelXx, 0, 65535, -32768, 32768)

                        # Accel Y
            AccelYy = Data[5] << 8 | Data[6]
            AccelY = self.Map_Func(AccelYy, 0, 65535, -32768, 32768)

                        # Accel Z
            AccelZz = Data[7] << 8 | Data[8]
            AccelZ = self.Map_Func(AccelZz, 0, 65535, -32768, 32768)

                        # Gyro X
            GyroXx = Data[9] << 8 | Data[10]
            GyroX = self.Map_Func(GyroXx, 0, 65500, -32750, 32750)

                        # Gyro Y
            GyroYy = Data[11] << 8 | Data[12]
            GyroY = self.Map_Func(GyroYy, 0, 65500, -32750, 32750)

                        # Gyro Z
            GyroZz = Data[13] << 8 | Data[14]
            GyroZ = self.Map_Func(GyroZz, 0, 65500, -32750, 32750)




        while StopRunUDP:
            # lost = lost+1     # for tests
            # print(lost)
            # if lost >90000 :
            #     lost = 0

            mili_Start = time.time()
            try:
                Data, addr = sock.recvfrom(16)  # buffer size is 15 bytes
            except:
                print("                                     error")

            if len(Data) > 0:  # jesli bufor wiekszy od zera ( linijak wyżej , albo bedzie , albo bedzie zero ....)
                Save_Data_From_ESP(Data)
               # print(Data)
                # print("received message: %s" % Data)  # wypisz dane
                Data = []  # zerowanie buforu , ale chyba niekonieczne
                sock.sendto(DataToSend, (UDP_IP, UDP_PORT))  # wysłanie wiadomości zwrotnej

            mili_Stop = time.time()
            TimeOut = mili_Stop - mili_Start
            #print(TimeOut)
            if TimeOut > 0.2 :
                print("Coś poszło nie tak, sprawdź połączenie")
                sock.sendto(DataToSend, (UDP_IP, UDP_PORT))  # wysłanie wiadomości zwrotnej

            #print()


        # def Print_Data_ESP_For_Check():
        #               # Battery
        #     Battery = Data[0]
        #     print("Battery: %x       " % Battery, end='')
        #     print("Battery in decimal: %d" % Battery)
        #               # Temp
        #     Temp = Data[1] << 8 | Data[2]
        #     print("Temp: %x       " % Temp, end='')
        #     print("Temp in decimal: %d" % Temp)
        #               # Accel X
        #     AccelXx = Data[3] << 8 | Data[4]
        #     AccelX = self.Map_Func(AccelXx, 0, 65535, -32768, 32768)
        #     print("AccelX: %x       " % AccelX, end='')
        #     print("AccelX in decimal: %d" % AccelX)
        #               # Accel Y
        #     AccelYy = Data[5] << 8 | Data[6]
        #     AccelY = self.Map_Func(AccelYy, 0, 65535, -32768, 32768)
        #     print("AccelY: %x       " % AccelY, end='')
        #     print("AccelY in decimal: %d" % AccelY)
        #               # Accel Z
        #     AccelZz = Data[7] << 8 | Data[8]
        #     AccelZ = self.Map_Func(AccelZz, 0, 65535, -32768, 32768)
        #     print("AccelZ: %x       " % AccelZ, end='')
        #     print("AccelZ in decimal: %d" % AccelZ)
        #               # Gyro X
        #     GyroXx = Data[9] << 8 | Data[10]
        #     GyroX = self.Map_Func(GyroXx, 0, 65500, -32750, 32750)
        #     print("GyroX: %x       " % GyroX, end='')
        #     print("GyroX in decimal: %d" % GyroX)
        #               # Gyro Y
        #     GyroYy = Data[11] << 8 | Data[12]
        #     GyroY = self.Map_Func(GyroYy, 0, 65500, -32750, 32750)
        #     print("GyroY: %x       " % GyroY, end='')
        #     print("GyroY in decimal: %d" % GyroY)
        #               # Gyro Z
        #     GyroZz = Data[13] << 8 | Data[14]
        #     GyroZ = self.Map_Func(GyroZz, 0, 65500, -32750, 32750)
        #     print("GyroZ: %x       " % GyroZ, end='')
        #     print("GyroZ in decimal: %d" % GyroZ)



class GUIApp(App):

    def build(self):

        return GUI()


if __name__ == '__main__':
    GUIApp().run()

还有一个规范文件。

    [app]

# (str) Title of your application
title = RobT

# (str) Package name
package.name = RoboT

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

# (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 = .

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

# (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

# (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 = landscape
# (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.7.7

# Kivy version to use
osx.kivy_version = 1.11.1

#
# Android specific
#

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

# (string) Presplash background color (for 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

# (string) Presplash animation using Lottie format.
# see https://lottiefiles.com/ for examples and https://airbnb.design/lottie/
# for general documentation.
# Lottie files can be created using various tools, like Adobe After Effect or Synfig.
#android.presplash_lottie = "path/to/lottie/file.json"

# (list) Permissions
#android.permissions = INTERNET

# (list) features (adds uses-feature -tags to manifest)
#android.features = android.hardware.usb.host

# (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

【问题讨论】:

    标签: python android kivy buildozer


    【解决方案1】:

    我怀疑问题出在时间上。 Android 设备可能比您的 PC 慢一点,导致当您调用 WHJoy() 时,GUI 实例中的 ids 未准备好。我建议从__init__() 方法中删除Clock.schedule_interval() 调用,并稍微延迟这些间隔调用的开始。也许从Appon_start() 方法开始:

    class GUIApp(App):
    
        def build(self):
    
            return GUI()
    
        def on_start(self):
            Clock.schedule_interval(self.root.update, 1/30.0)
            Clock.schedule_interval(self.root.change_color, 1 / 1)
    

    作为一个测试,只是为了看看时间是否是罪魁祸首,尝试运行这个:

    class GUIApp(App):
    
        def build(self):
            Clock.schedule_once(self.start_intervals, 3)
            return GUI()
    
        def start_intervals(self, dt):
            Clock.schedule_interval(self.root.update, 1/30.0)
            Clock.schedule_interval(self.root.change_color, 1 / 1)
    

    此代码在开始间隔(3 秒)之前进行了极大的延迟。当然,这对于您的最终代码是不可接受的,但如果这样可以消除错误,那么时间就是问题。

    【讨论】:

    • 问题已解决,但我还有一个。解决:.kv文件必须在pythone代码中通过: from kivy.lang import Builder Builder.load_string(''' kv.code ''')
    • 但另一个是:PermissionError: [Errno 13] Permission denied。当我运行负责 UDP 通信的线程时会发生女巫。
    • 你可以用Builder.load_file()代替Builder.load_string()
    • 您需要在spec文件中取消注释#android.permissions = INTERNET这一行,并添加runtime permissions
    猜你喜欢
    • 2019-01-27
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 2016-09-26
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多