I'm a student of Bachelor of Engineering and still in my second year, but I'm trying to develop a basic Assistant app using Python and Kivy (which I tried to learn on my own).
I have the code written for the app which works perfectly fine on my windows system but for packaging the source code into an apk, I used Google Collab account and installed the Ubuntu and buildozer environment. The apk is also generated successfully but upon installing on any android device, the app crashes immediately after showing "(Kivy Logo)Loading..."
I tried changing parts of code and also the spec file contents but nothing helped. I am new to Kivy and app development so I (honestly) don't know much about the logcat and debugging the apk.
I would be very grateful if anyone can me help with it.
This is my code :
from kivy.app import App
from kivy.config import Config
Config.set('graphics','resizable',True)
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.pagelayout import PageLayout
from kivy.uix.gridlayout import GridLayout
import datetime
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
import os
from kivy.clock import Clock
from kivy.core.window import Window
OldNameOfFile=""
OldText=""
firsttime=1
pcheck=0
FileListString=""
class MyLayout(FloatLayout):
def ButtonMaker(self):
self.Timeb=Button(
text="Time",size_hint=(.3,.3),pos_hint={"x":.09,"y":.6})
self.WriteB=Button(
text="Press here to \nwrite a note",size_hint=(.3,.3),pos_hint={"x":.6,"y":.6})
self.NoteB=Button(
text="Press here to view\n a written note",size_hint=(.3,.3),pos_hint={"x":.09,"y":.2})
self.SWB=Button(
text="Press here for \nStop-Watch",size_hint=(.3,.3),pos_hint={"x":.6,"y":.2})
self.STOPWATCHStartB=Button(
text="Start",size_hint=(.25,.20),pos_hint={"x":.04,"y":.3})
self.STOPWATCHStopB=Button(
text="Stop",size_hint=(.25,.20),pos_hint={"x":.36,"y":.3})
self.STOPWATCHCloseB=Button(
text="Close",size_hint=(.25,.20),pos_hint={"x":.68,"y":.3})
self.STOPWATCHPauseB=Button(
text="Pause",size_hint=(.25,.20),pos_hint={"x":.2,"y":.05})
self.STOPWATCHResetB=Button(
text="Reset",size_hint=(.25,.20),pos_hint={"x":.53,"y":.05})
self.STOPWATCHDisp=TextInput(
text=" 00:00:00:00",size_hint=(.9,.3),font_size='125sp',readonly=True,pos_hint={"x":.05,"y":.6})
self.TimeBTime=Button(
text="The time is :",background_color="black",font_size=40,pos_hint={"x":0,"y":.3})
self.TimeBCloseB=Button(
text="Click to close",size_hint=(.2,.2),pos_hint={"x":.35,"y":.2})
self.WriteBNameB=Button(
text="Enter name of file here : (or Enter name of already existing file to edit before entering text)",size_hint=(1,.09),background_color="black",pos_hint={"x":0.01,"y":.9})
self.WriteBTIB=Button(
text="Enter text here :",size_hint=(1,.09),background_color="black",pos_hint={"x":0.01,"y":.78})
self.WriteBSubmitB=Button(
text="Save",size_hint=(.4,.1),pos_hint={"x":0.07,"y":.1})
self.WriteBCloseB=Button(
text="Close",size_hint=(.4,.1),pos_hint={"x":.53,"y":.1})
self.WriteBTI=TextInput(
font_size=30,size_hint=(.95,.55),pos_hint={"x":0.02,"y":.25},multiline=True)
self.WriteBName=TextInput(
font_size=20,size_hint=(.95,.07),pos_hint={"x":0.02,"y":.85})
self.WriteBp=Button(
text="Empty name error...",background_color="black",size_hint=(.4,.08),pos_hint={"x":0.3,"y":0.01})
self.NoteBName=TextInput(
text="Select a file name from below files",font_size=20,size_hint=(.95,.07),pos_hint={"x":.02,"y":.85})
self.NoteBNameB=Button(
text="Enter name of file here :",size_hint=(1,.09),background_color="black",pos_hint={"x":0.01,"y":.9})
self.NoteBTextData=TextInput(
font_size=20,size_hint=(.95,.55),pos_hint={"x":0.02,"y":.25},readonly=True,multiline=True)
self.NoteBTextDataB=Button(
text="Data of files :",size_hint=(1,.09),background_color="black",pos_hint={"x":0.01,"y":.78})
self.NoteBSubmitB=Button(
text="Submit",size_hint=(.4,.1),pos_hint={"x":0.07,"y":.13})
self.NoteBCloseB=Button(
text="Close",size_hint=(.4,.1),pos_hint={"x":0.53,"y":.13})
self.NoteBDeleteB=Button(
text="Delete this",size_hint=(.38,.09),pos_hint={"x":0.3,"y":0.02})
self.NoteBp=Button(
text="Empty name error...",background_color="black",size_hint=(.4,.1),pos_hint={"x":0.3,"y":0.02})
self.HomePage1List=[
self.Timeb,self.WriteB,self.NoteB,self.SWB]
self.STOPWATCHList=[
self.STOPWATCHStartB,self.STOPWATCHStopB,self.STOPWATCHCloseB,self.STOPWATCHPauseB,self.STOPWATCHResetB,self.STOPWATCHDisp]
self.TimeBList=[
self.TimeBTime,self.TimeBCloseB]
self.WriteBList=[
self.WriteBNameB,self.WriteBTIB,self.WriteBName,self.WriteBTI,self.WriteBSubmitB,self.WriteBCloseB]
self.NoteBList=[
self.NoteBNameB,self.NoteBName,self.NoteBTextDataB,self.NoteBTextData,self.NoteBSubmitB,self.NoteBCloseB,self.NoteBDeleteB]
def BindButtons(self):
self.SWB.bind(on_press=self.StopWatchPress)
self.Timeb.bind(on_press=self.TimeBPress)
self.WriteB.bind(on_press=self.WriteBPress)
self.NoteB.bind(on_press=self.NoteBPress)
self.STOPWATCHStartB.bind(on_press=self.OnStart)
self.STOPWATCHStopB.bind(on_press=self.OnStop)
self.STOPWATCHResetB.bind(on_press=self.OnReset)
self.STOPWATCHPauseB.bind(on_press=self.OnPause)
self.STOPWATCHCloseB.bind(on_press=self.StopWatchClose)
self.TimeBCloseB.bind(on_press=self.TimeBClose)
self.WriteBCloseB.bind(on_press=self.WriteBClose)
self.WriteBSubmitB.bind(on_press=self.Saveandwrite)
self.NoteBSubmitB.bind(on_press=self.OpenFile)
self.NoteBCloseB.bind(on_press=self.NoteBClose)
self.NoteBDeleteB.bind(on_press=self.NoteBDelete)
def AddHomePage1(self):
for b in self.HomePage1List:
self.add_widget(b)
def RemHomePage1(self):
for b in self.HomePage1List:
self.remove_widget(b)
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.ButtonMaker()
self.BindButtons()
self.AddHomePage1()
def StopWatchPress(self,button):
self.RemHomePage1()
self.STOPWATCHpause=0
self.STOPWATCHstop=0
Clock.unschedule(self.increment_STOPWATCHtime)
self.STOPWATCHtime=["00","00","00","0"]
self.STOPWATCHDisp.text=" 00:00:00:00"
for b in self.STOPWATCHList:
self.add_widget(b)
def TimeBPress(self,button):
self.RemHomePage1()
time=datetime.datetime.now()
time=time.strftime("%H:%M:%S")
self.TimeBTime.text=self.TimeBTime.text[:13]+str(time)
for b in self.TimeBList:
self.add_widget(b)
def WriteBPress(self,button):
self.RemHomePage1()
global firsttime
firsttime=1
for b in self.WriteBList:
self.add_widget(b)
def NoteBPress(self,button):
self.RemHomePage1()
path=os.getcwd()
FileList=os.listdir(path)
global FileListString
FileListString="Names of all files are : \n"
for k in FileList:
if k[-4:]==".txt":
FileListString=FileListString+k+"\n"
self.NoteBTextData.text=FileListString
for b in self.NoteBList:
self.add_widget(b)
def StopWatchClose(self,button):
for b in self.STOPWATCHList:
self.remove_widget(b)
self.AddHomePage1()
def TimeBClose(self,button):
self.remove_widget(self.TimeBCloseB)
self.remove_widget(self.TimeBTime)
self.AddHomePage1()
def Saveandwrite(self,button):
global OldNameOfFile
global OldText
global firsttime
if firsttime==1 or (OldNameOfFile!=self.WriteBName.text.strip() or OldText!=self.WriteBTI.text):
file="new"
NameOfFile=self.WriteBName.text.strip()
else:
file="old"
if file=="old":
return
global pcheck
OldNameOfFile=NameOfFile
if NameOfFile=="":
if pcheck==0:
self.add_widget(self.WriteBp)
pcheck=1
return
if NameOfFile!="":
self.remove_widget(self.WriteBp)
pcheck=0
if NameOfFile[-4:]==".txt":
NameOfFile=NameOfFile[:-4]
try:
NewF=open(NameOfFile+".txt","r")
if self.WriteBTI.text=="":
self.WriteBTI.text=NewF.read()
NewF.close()
except:
pass
NewF=open(NameOfFile+".txt","w")
self.WriteBName.text=NameOfFile
Text=self.WriteBTI.text
OldText=Text
NewF.write(Text)
NewF.close()
firsttime=0
return
def WriteBClose(self,button):
for b in self.WriteBList:
self.remove_widget(b)
global pcheck
global OldNameOfFile
global firsttime
firsttime=1
OldNameOfFile=""
self.WriteBName.text=""
self.WriteBTI.text=""
if pcheck==1:
pcheck=0
self.remove_widget(self.WriteBp)
self.AddHomePage1()
def OpenFile(self,button):
global FileListString
NameOfFile=self.NoteBName.text.strip()
global pcheck
if NameOfFile=="":
if pcheck==0:
self.add_widget(self.NoteBp)
pcheck=1
return
if NameOfFile!="":
self.remove_widget(self.NoteBp)
pcheck=0
try:
if NameOfFile[-4:]==".txt":
NameOfFile=NameOfFile[:-4]
NewF=open(NameOfFile+".txt","r")
self.NoteBTextData.text=NewF.read()
except FileNotFoundError:
self.NoteBTextData.text=FileListString
self.NoteBName.text="No Such File.. Select a name from below files.."
def NoteBDelete(self,button):
NameOfFile=self.NoteBName.text.strip()
if NameOfFile[-4:]==".txt":
NameOfFile=NameOfFile[:-4]
try:
os.remove(NameOfFile+".txt")
except:
pass
path=os.getcwd()
FileList=os.listdir(path)
global FileListString
FileListString="Names of all files are : \n"
for k in FileList:
if k[-4:]==".txt":
FileListString=FileListString+k+"\n"
self.NoteBTextData.text=FileListString
self.NoteBName.text="Select a file name from below files"
def NoteBClose(self,button):
for b in self.NoteBList:
self.remove_widget(b)
global pcheck
global FileListString
FileListString=""
self.NoteBName.text="Select a file name from below files"
if pcheck==1:
pcheck=0
self.remove_widget(self.NoteBp)
self.AddHomePage1()
def increment_STOPWATCHtime(self,interval):
if int(self.STOPWATCHtime[3])<75:
self.STOPWATCHtime[3]=str(int(self.STOPWATCHtime[3])+2)
else:
self.STOPWATCHtime[3]=str(int(self.STOPWATCHtime[3])+4)
if int(self.STOPWATCHtime[3])>90:
self.STOPWATCHtime[2]=str(int(self.STOPWATCHtime[2])+1)
self.STOPWATCHtime[3]="00"
if self.STOPWATCHtime[2]=="60":
self.STOPWATCHtime[1]=str(int(self.STOPWATCHtime[1])+1)
self.STOPWATCHtime[2]="00"
self.STOPWATCHtime[3]="30"
if self.STOPWATCHtime[1]=="60":
self.STOPWATCHtime[0]=str(int(self.STOPWATCHtime[0])+1)
self.STOPWATCHtime[1]="00"
if self.STOPWATCHtime[0]=="24":
self.STOPWATCHtime=["00","00","00","00"]
for k in range(4):
if int(self.STOPWATCHtime[k])<10:
self.STOPWATCHtime[k]="0"+str(int(self.STOPWATCHtime[k]))
self.STOPWATCHDisp.text=" "
for k in range(4):
self.STOPWATCHDisp.text+=self.STOPWATCHtime[k]
if k<3: self.STOPWATCHDisp.text+=":"
def OnPause(self,button):
self.STOPWATCHpause=1
Clock.unschedule(self.increment_STOPWATCHtime)
def OnReset(self,button):
Clock.unschedule(self.increment_STOPWATCHtime)
self.STOPWATCHtime=["00","00","00","00"]
self.STOPWATCHDisp.text=" 00:00:00:00"
self.STOPWATCHpause=0
def OnStart(self,button):
Clock.unschedule(self.increment_STOPWATCHtime)
if self.STOPWATCHpause==0 and self.STOPWATCHstop!=1:
self.STOPWATCHtime=["00","00","00","00"]
self.STOPWATCHDisp.text=" 00:00:00:00"
elif self.STOPWATCHstop==1:
self.STOPWATCHtime=["00","00","00","00"]
self.STOPWATCHDisp.text=" 00:00:00:00"
Clock.schedule_interval(self.increment_STOPWATCHtime,0.02)
self.STOPWATCHpause=0
self.STOPWATCHstop=0
def OnStop(self,button):
Clock.unschedule(self.increment_STOPWATCHtime)
self.STOPWATCHstop=1
self.STOPWATCHpause=0
class DemoApp(App):
def build(self):
return MyLayout()
if __name__=="__main__":
demo=DemoApp()
demo.run()
I also have to add recipe for os module, if I'm not wrong but I don't know the process of that either. Any help would be really appreciated.
Thank you.
I found the answer.
https://play.google.com/store/apps/details?id=com.apptiva.logviewer
Using the above app, I found the logs of the app when it crashed and understood the error that was happening. And it was : the background_color of a button can be string on windows but it needed an rgba code to run on Android. Maybe android hasn't added that feature yet, to accept strings too for colors. In the above code I gave it as "black" which I had to change to (0,0,0,1). Basically, the error with this was "cannot convert string to float : b" and that's how I understood that the problem was with "black".
And special praise to Kivy launcher app: https://play.google.com/store/apps/details?id=org.kivy.pygame Helped a lot in checking if the errors are rectified without actually packaging the app, which takes lot of time.
And I also changed the path to create and save files and then again read them.