Q: Why isn't the code working in kivy launcher? (What am i missing?) I have been developing my first app for the workplace with kivy and have got it to a point where it needs to be tested by others. However I can't see where I'm going wrong when it comes to either compiling by buildozer or using Kivy launcher, it simply crashes immediately on start up.
I've already tried stripping back the code to just a login page with no MySQL at all as I know there is limited support within Kivy launcher.
I've managed to use buildozer to create apks of Kivy examples and another piece of demo code.
main.py:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
import time
import pymysql.cursors
global mycursor
global end1
global ad
global ogl
global enum
global snum
ogl = []
connection = pymysql.connect(host="localhost", user="user", password="pw", db="user", charset='utf8mb4', cursorclass=pymysql.cursors.Cursor)
mycursor = connection.cursor()

class SigninWindow(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    def validate_user(self):
        user = self.ids.username_field
        pwd = self.ids.pwd_field
        info = self.ids.info
        uname = user.text
        passw = pwd.text
        sqluname = "hold"
        sqlpassw = "hold"
        if uname == '' or passw == '':
            info.text = '[color=#808080]You need a username or password![/color]'
        else:
            mycursor = connection.cursor()
            sql = ("SELECT * FROM users WHERE user_name = %s")
            val = (uname)
            mycursor.execute(sql, val)
            myresult = mycursor.fetchall()
            for x in myresult:
                sqluname = x[3]
                sqlpassw = x[4]
            if uname == sqluname and passw == sqlpassw:
                info.text = '[color=#808080]Success![/color]'
                self.manager.current = 'Menu'
                self.ids.username_field.text = ""
                self.ids.pwd_field.text = ""
                self.ids.info.text = ""
            else:
                info.text = '[color=#808080]Invalid username or password[/color]'
                self.ids.username_field.text = ""
                self.ids.pwd_field.text = ""
class MenuWindow(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    def CSGO(self):
        self.manager.current = 'CutSheet'
    def DIGO(self):
        self.manager.current = 'DrumInput'
    def SIGO(self):
        self.manager.current = 'Signin'    
class CutSheetWindow(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    def home(self):
        self.manager.current = 'Menu'
        self.ids.drum_container.clear_widgets()
        self.ids.ic_field.text = ""
        self.ids.ic_hold.text = 'Incoming Number'
        self.ids.pc_hold.text = 'Product Code'
        self.ids.l_hold.text = 'Length'
        self.ids.sm_hold.text = 'Start Mark'
        self.ids.em_hold.text = 'End Mark'
    def lbupdate(self):
        global snum
        global enum
        ic = self.ids.ic_field.text
        sql = ("SELECT * FROM ic_drum WHERE ic_number = %s")
        val = (ic,)
        mycursor.execute(sql, val)
        myresult = mycursor.fetchall()
        drum_container = self.ids.drum_container
        drum_container.clear_widgets()
        for x in myresult:
            ic = x[0]
            self.ids.ic_hold.text = str(ic)
            pc = x[1]
            self.ids.pc_hold.text = str(pc)                                                                                                                                   
            l = x[2]
            self.ids.l_hold.text = str(l)
            sm = x[3]
            quant = sm
            self.ids.sm_hold.text = str(sm)
            em = x[4]
            self.ids.em_hold.text = str(em)
            up = x[6]
            sql = ("SELECT length FROM `Products` WHERE `BT Item Code` = %s ")
            val = (str(pc) ,)
            mycursor.execute(sql, val)
            cutb = mycursor.fetchone()
            cuta = cutb[0]
            cut = cuta
            snum = []
            enum = []
            if up == 1:
                while quant < em-cut:
                    details = GridLayout(cols=3,size_hint_y=None,height=30,pos_hint={'top': 1})
                    drum_container.add_widget(details)
                    details.add_widget(Label(text=str(quant),size_hint_x=.2,color=(0,0,0,1)))
                    quant = quant + cut
                    snum.append(quant)
                    details.add_widget(Label(text=str(quant),size_hint_x=.2,color=(0,0,0,1)))
                    quant = quant + 1
                    enum.append(quant)
                    og = (TextInput(hint_text='Outgoing Number', multiline=False,size_hint_x=.2,height=20))
                    details.add_widget(og)
                    og.fbind('on_text_validate', self.on_event,self.green)
                quant = l-quant
            else:
                while quant > sm-l+cut:
                    details = GridLayout(cols=4,size_hint_y=None,height=30,pos_hint={'top': 1})
                    drum_container.add_widget(details)
                    details.add_widget(Label(text=str(quant),size_hint_x=.2,color=(0,0,0,1)))
                    snum.append(quant)
                    quant = quant - cut
                    details.add_widget(Label(text=str(quant),size_hint_x=.2,color=(0,0,0,1)))
                    enum.append(quant)
                    quant = quant - 1 
                    og = (TextInput(hint_text='Outgoing Number', multiline=False,size_hint_x=.2,height=20))
                    details.add_widget(og)
                    og.fbind('on_text_validate', self.on_event)
            self.ids.test.text = 'Send'
            sql = ("UPDATE ic_drum SET waste = '%s' WHERE ic_number = '%s'")
            val = (quant,ic,)
            mycursor.execute(sql, val)
            connection.commit()
    def on_event(self,og):
        global ogl
        ogl.append(int(og.text))
        og.foreground_color=(0,1,0,1)
    def ogsend(self):
        ic = self.ids.ic_field.text
        sql = ("SELECT product_code FROM `ic_drum` WHERE `ic_number` = %s ")
        val = (float(ic) ,)
        mycursor.execute(sql, val)
        pc = mycursor.fetchone()
        pc = pc[0]
        if len(snum) == len(ogl):
            for i in range(len(snum)):
                s = snum[i]
                e = enum[i]
                o = ogl[i]
                sql = ("INSERT INTO `outgoing`(`ic_number`, `product_code`, `start`, `end`, `outgoing`) VALUES (%s,%s,%s,%s,%s)")
                val = (ic,pc,s,e,o)
                mycursor.execute(sql, val)
                connection.commit()
        else:
            content = Button(text='Missing outgoing numbers')
            popup = Popup(title='Error', content=content,auto_dismiss=True)
            content.bind(on_press=popup.dismiss)
            popup.open()
class DrumInputWindow(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    def home(self):
        self.manager.current = 'Menu'
    # For Switch
    def switch_on(self, instance, value):
        global end1
        global ad
        if len(self.ids.length_field.text) == 0:
            content = Button(text='Enter Values First!')
            popup = Popup(title='Error', content=content,auto_dismiss=True)
            content.bind(on_press=popup.dismiss)
            popup.open()
        else:
            l =  self.ids.length_field.text
            sm = self.ids.start_field.text
            hl = float(l)
            hs = float(sm)
            if value is True:
                hld = str(hl+hs)
                end1 = hld
                ad = 1
            else:
                hld = str(hl-hs)
                end1 = hld
                ad = 0
    def drum_hold(self):
        ic = self.ids.ic_field.text
        pc = self.ids.pc_field.text
        l =  self.ids.length_field.text
        sm = self.ids.start_field.text
        em = end1
        drum_container = self.ids.drum_container
        if len(ic) == 4:
            details = BoxLayout(size_hint_y=None,height=30,pos_hint={'top': 1})
            drum_container.add_widget(details)
            incoming = Label(text=ic,size_hint_x=.2,color=(1,0,0,1))
            pcode = Label(text=pc,size_hint_x=.2,color=(1,0,0,1))
            length = Label(text=l,size_hint_x=.2,color=(1,0,0,1))
            smark = Label(text=sm,size_hint_x=.2,color=(1,0,0,1))
            emark = Label(text=em,size_hint_x=.2,color=(1,0,0,1))
            hold = Label(text='Sent',size_hint_x=.2,color=(1,0,0,1))
            details.add_widget(incoming)
            details.add_widget(pcode)
            details.add_widget(length)
            details.add_widget(smark)
            details.add_widget(emark)
            details.add_widget(hold)
            prod = '%.6s' % str(pc)
            sql = ("INSERT INTO `ic_drum` (`ic_number`, `product_code`, `quantity`, `start`, `end`,`waste`) VALUES (%s,%s,%s,%s,%s,%s)")
            val = (float(ic),prod,float(l),float(sm),float(em),ad)
            mycursor.execute(sql, val)
            connection.commit()
        else:
            content = Button(text='IC number needs to be 4 digits')
            popup = Popup(title='Error', content=content,auto_dismiss=True)
            content.bind(on_press=popup.dismiss)
            popup.open()
class WindowManager(ScreenManager):
    pass
kv = Builder.load_file("my.kv")
class SkynetApp(App):
    def build(self):
        return kv
if __name__ == "__main__":
    SkynetApp().run()

my.kv:
#:kivy 1.1.6
WindowManager:
    SigninWindow:
    MenuWindow:
    DrumInputWindow:
    CutSheetWindow:
<FlatButton@ButtonBehavior+Label>:
    font_size: 16
<SigninWindow>:
    id: main_win
    name: 'Signin'
    space_x: self.size[0]/3
    BoxLayout:
        orientation: "vertical"
        spacing: 10
        canvas.before:
            Color:
                rgba: (1,1,1,1)
            Rectangle:
                size: self.size
                pos: self.pos
        BoxLayout:
            size_hint_y: None
            height: 100
            canvas.before:
                Color:
                    rgba: (1,0,0,1)
                Rectangle:
                    size: self.size
                    pos: self.pos
            Image:
                source: "logo.jpg"
                size_hint_x: .4

            Label:
                text: "Login"
                bold: True
                font_size: 16
                size_hint_x: .5
            FlatButton:
                text: "x"
                size_hint_x: .1
        BoxLayout:
            orientation: "vertical"
            padding: main_win.space_x, 10
            spacing: 20
            BoxLayout:
                orientation: "vertical"
                spacing: 10
                size_hint_y: None
                height: 100
                Label:
                    id: info
                    text: ''
                    markup: True
                TextInput:
                    id: username_field
                    hint_text: "Username"
                    multiline: False
                    focus: True
                    on_text_validate: pwd_field.focus = True
                TextInput:
                    id: pwd_field
                    hint_text: "Password"
                    multiline: False
                    password: True
                    on_text_validate: root.validate_user()
            Button:
                text: "Sign In"
                size_hint_y: None
                height: 40
                background_color: (1,0,0,1)
                background_normal: ''
                on_release: root.validate_user()
            Label:
                id: sp2
<MenuWindow>:
    id: Menu
    name: "Menu"
    BoxLayout:
        orientation: "vertical"
        space_x: self.size[0]/3
        spacing: 10
        canvas.before:
            Color:
                rgba: (1,1,1,1)
            Rectangle:
                size: self.size
                pos: self.pos
        BoxLayout:
            size_hint_y: None
            height: 100
            spacing: 10
            canvas.before:
                Color:
                    rgba: (1,0,0,1)
                Rectangle:
                    size: self.size
                    pos: self.pos
            Image:
                source: "logo.jpg"
                size_hint_x: .4
            Label:
                text: "Menu"
                bold: True
                font_size: 16
                size_hint_x: .5
            FlatButton:
                text: "x"
                size_hint_x: .1
        GridLayout:
            cols:1
            canvas.before:
                Color:
                    rgba: 1,1,1,1
                Rectangle:
                    pos: self.pos
                    size: self.size
            orientation: 'vertical'
            spacing: 10
            Button:
                text: "Cut Sheet"
                size_hint_y: None
                height: 40
                size_hint_x: .6
                background_color: (1,0,0,1)
                background_normal: ''
                on_release: root.CSGO()
            Button:
                text: "Drum Input"
                size_hint_y: None
                height: 40
                size_hint_x: .6
                background_color: (1,0,0,1)
                background_normal: ''
                on_release: root.DIGO()
            Button:
                text: "Sign Out"
                size_hint_y: None
                height: 40
                size_hint_x: .6
                background_color: (1,0,0,1)
                background_normal: ''
                on_release: root.SIGO()
            Label:
                id: sp2
<DrumInputWindow>:
    id: DrumInput
    name: "DrumInput"
    BoxLayout:
        orientation: "vertical"
        size: 400,400
        canvas.before:
            Color:
                rgba: (1,1,1,1)
            Rectangle:
                size: self.size
                pos: self.pos
        BoxLayout:
            size_hint_y: None
            height: 100
            spacing: 10
            canvas.before:
                Color:
                    rgba: (1,0,0,1)
                Rectangle:
                    size: self.size
                    pos: self.pos
            Image:
                source: "logo.jpg"
                size_hint_x: .4
            Label:
                text: "Drum Input"
                bold: True
                font_size: 16
                size_hint_x: .5
            FlatButton:
                text: "x"
                size_hint_x: .1
                on_release:root.home()
        BoxLayout:
            orientation: 'vertical'
            size_hint_y: None
            height: 40
            BoxLayout:
                padding: 10
                spacing: 10
                canvas.before:
                    Color:
                        rgba: (0,0,0,1)
                    Rectangle:
                        size: self.size
                        pos: self.pos
                FlatButton:
                    text: "Incoming Number"
                FlatButton:
                    text: "Product Code"
                FlatButton:
                    text: "Length"
                FlatButton:
                    text: "Start Mark"
                FlatButton:
                    text: "Up/Down"
                FlatButton:
                    text: "Holder"
                    color: (0,0,0,1)
        BoxLayout:
            orientation: 'vertical'
            size_hint_y: None
            height: 60
            BoxLayout:
                padding: 10
                spacing: 10
                TextInput:
                    id: ic_field
                    size_hint_x: .1
                    hint_text: "Incoming No"
                    multiline: False
                    focus: True
                    on_text_validate: pc_field.focus = True
                TextInput:
                    id: pc_field
                    size_hint_x: .1
                    hint_text: "Product Code"
                    multiline: False
                    on_text_validate: length_field.focus = True
                TextInput:
                    id: length_field
                    size_hint_x: .1
                    hint_text: "Length"
                    multiline: False
                    on_text_validate: start_field.focus = True
                TextInput:
                    id: start_field
                    size_hint_x: .1
                    hint_text: "Start Marking"
                    multiline: False
                Switch:
                    size_hint_x: .1
                    id: switch
                    on_active: root.switch_on(self, self.active)
                Button:
                    text: "Submit"
                    size_hint_x: .1
                    background_color: (1,0,0,1)
                    background_normal: ''
                    on_release: root.drum_hold()
        BoxLayout:
            orientation: 'vertical'
            size_hint_y: None
            height: 40
            BoxLayout:
                padding: 10
                spacing: 10
                canvas.before:
                    Color:
                        rgba: (0,0,0,1)
                    Rectangle:
                        size: self.size
                        pos: self.pos
                FlatButton:
                    text: "Incoming Number"
                FlatButton:
                    text: "Product Code"
                FlatButton:
                    text: "Length"
                FlatButton:
                    text: "Start Mark"
                FlatButton:
                    text: "End Mark"
                FlatButton:
                    text: "Status"
        GridLayout:
            cols: 1
            rows: 2
            ScrollView:
                size_hint: (1, .9)
                bar_width: 100
                bar_color: 1, 0, 0, 1   # red
                bar_inactive_color: 0, 0, 1, 1   # blue
                effect_cls: "ScrollEffect"
                scroll_type: ['bars']
                GridLayout:
                    cols: 1
                    id:drum_container
                    size_hint_y: None
                    height: 40
<CutSheetWindow>:
    id: CutSheet
    name: 'CutSheet'
    BoxLayout:
        orientation: "vertical"
        size: self.size
        canvas.before:
            Color:
                rgba: (1,1,1,1)
            Rectangle:
                size: self.size
                pos: self.pos
        BoxLayout:
            size_hint_y: None
            height: 100
            spacing: 10
            canvas.before:
                Color:
                    rgba: (1,0,0,1)
                Rectangle:
                    size: self.size
                    pos: self.pos
            Image:
                source: "logo.jpg"
                size_hint_x: .4
                #align: left
            Label:
                text: "Cut Sheet"
                bold: True
                font_size: 16
                size_hint_x: .5
            FlatButton:
                text: "x"
                size_hint_x: .1
                on_release: root.home()
        BoxLayout:
            orientation: 'vertical'
            size_hint_y: None
            height: 60
            BoxLayout:
                padding: 10
                spacing: 10
                canvas.before:
                    Color:
                        rgba: (0,0,0,1)
                    Rectangle:
                        size: self.size
                        pos: self.pos
                FlatButton:
                    id: test
                    size_hint_x: .2
                    text: "Incoming Number"
                    on_release: root.ogsend()
                TextInput:
                    id: ic_field
                    size_hint_x: .2
                    hint_text: "Incoming No"
                    multiline: False
                    focus: True

                Button:
                    value: False
                    text: "Submit"
                    size_hint_x: .1
                    background_color: (1,0,0,1)
                    background_normal: ''
                    on_release: root.lbupdate()
        BoxLayout:
            orientation: 'vertical'
            size_hint_y: None
            height: 25
            BoxLayout:
                padding: 10
                spacing: 10
                canvas.before:
                    Color:
                        rgba: (0,0,0,1)
                    Rectangle:
                        size: self.size
                        pos: self.pos
                FlatButton:
                    text: "Incoming Number"
                FlatButton:
                    text: "Product Code"
                FlatButton:
                    text: "Length"
                FlatButton:
                    text: "Start Mark"
                FlatButton:
                    text: "End Mark"
        BoxLayout:
            orientation: 'vertical'
            size_hint_y: None
            height: 25
            font_size: 10
            BoxLayout:
                padding: 10
                spacing: 10
                canvas.before:
                    Color:
                        rgba: (0,0,0,1)
                    Rectangle:
                        size: self.size
                        pos: self.pos
                FlatButton:
                    text: "Incoming Number"
                    id: ic_hold
                FlatButton:
                    text: "Product Code"
                    id: pc_hold
                FlatButton:
                    text: "Length"
                    id: l_hold
                FlatButton:
                    text: "Start Mark"
                    id: sm_hold
                FlatButton:
                    text: "End Mark"
                    id: em_hold
        GridLayout:
            cols: 1
            rows: 1
            ScrollView:
                bind: True
                size_hint: (1, .9)
                bar_width: 100
                bar_color: 1, 0, 0, 1   # red
                bar_inactive_color: 0, 0, 1, 1   # blue
                effect_cls: "ScrollEffect"
                scroll_type: ['bars']
                GridLayout:
                    orientation: 'vertical'
                    cols: 4
                    id:drum_container
                    size_hint_y: None
                    height: 40

I get no error messages, just a straight up crash. The code runs perfectly on Windows and Linux (Lubuntu 18.04), but can't do anything on Android.
