Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in android : can not import ScreenManager #5701

Closed
ghost opened this issue Apr 18, 2018 · 13 comments
Closed

Error in android : can not import ScreenManager #5701

ghost opened this issue Apr 18, 2018 · 13 comments
Labels

Comments

@ghost
Copy link

ghost commented Apr 18, 2018

Versions

  • Python: 3.6
  • OS: windows
  • Kivy: 1.10.1
  • Kivy installation method: pip.install
  • Buildozer : for python 3 with crystax

Have created an App.
Built it with buildozer (for python3), without any problem
Ran OK in my android devices

then I triedl to add the settings management of the app by using kivy.uix.settings functionnalities
So I've add edfrom kivy.uix.settings import SettingsWithSidebar and then all the code to built the settings panel.

Running in Windows : no issue
Building with buildozer : no issue
Running on android : crash with error message : (adb logs)

 6487  6519 I python  :      from kivy.uix.screenmanager import ScreenManager, Screen
04-13 13:49:12.525  6487  6519 I python  :  ImportError: cannot import name 'ScreenManager'

The problem is from the from kivy.uix.settings import SettingsWithSidebar which itself tries to import ScreenManager and other modules. But the import failed

What I'm quite confused about is that these modules/librairies are part of the Kivy core product so why it failed ? Do I need to add some requirements to buildozer or this is clearly a bug in buildozer when creating the APK ?

Below my buildozer requirements :
requirements = python3crystax,kivy,pyjnius

Rgds

@welcome
Copy link

welcome bot commented Apr 18, 2018

👋 Thanks for opening your first issue here! Be sure to follow the issue template!

@kuzeyron
Copy link
Contributor

Does it do the same with git+link?

requirements = python3crystax, git+https://github.com/kivy/kivy.git, pyjnius

@ghost
Copy link
Author

ghost commented Apr 19, 2018

Dear,

not sure to understand how to set this requirement.
Buidozer reports :

The requirements (git+https://github.com/kivy/kivy.git) don't have recipes, attempting to install them with pip

@ghost
Copy link
Author

ghost commented Apr 19, 2018

came up with error

 INFO]:    -> running virtualenv --python=python2.7 venv
[INFO]:    Creating a requirements.txt file for the Python modules
[INFO]:    Installing Python modules with pip
[INFO]:    If this fails with a message about /bin/false, this probably means the package cannot be installed with pip as it needs a compilation recipe.
[INFO]:    -> running bash -c source venv/bin/activate && env CC=/bin/false CXX=/bin/false PYTHONPA...(and 235 more)
           working: Collecting git+https://github.com/kivy/kivy.git (from -Exception in thread background thread for pid 17529:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/local/lib/python2.7/dist-packages/sh.py", line 2170, in background_thread
    handle_exit_code(exit_code)
  File "/usr/local/lib/python2.7/dist-packages/sh.py", line 1929, in fn
    return self.command.handle_command_exit_code(exit_code)
  File "/usr/local/lib/python2.7/dist-packages/sh.py", line 672, in handle_command_exit_code
    raise exc
ErrorReturnCode_1: 

  RAN: /bin/bash -c source venv/bin/activate && env CC=/bin/false CXX=/bin/false PYTHONPATH=/home/kivy/python/myapps/.buildozer/android/platform/build/build/python-installs/jejesh26 pip install --target '/home/kivy/python/myapps/.buildozer/android/platform/build/build/python-installs/jejesh26' --no-deps -r requirements.txt

  STDOUT:
Collecting git+https://github.com/kivy/kivy.git (from -r requirements.txt (line 1))
  Cloning https://github.com/kivy/kivy.git to /tmp/pip-nCcZX1-build
fatal: unable to access 'https://github.com/kivy/kivy.git/': Could not resolve host: github.com
Command "git clone -q https://github.com/kivy/kivy.git /tmp/pip-nCcZX1-build" failed with error code 128 in None

I can access the website from my virtual machine. So I don't understand why it failed in resolving github.com

@kuzeyron
Copy link
Contributor

Seems like SSL is failing for you. I made a quick search for you: Git stopped working over SSL ..

@ghost
Copy link
Author

ghost commented Apr 20, 2018

I have overcame the proxy issue, so I moved one step forward : the Git repository is downloaded

But now, build fails with error something like "no Cython installed. Kivy needs Cython the be compiled"

The problem is : I have Cython installed.... Even when I tried to do a pip install of Cython, system informs me that it is already up to date.

I'm really lost...

@kuzeyron
Copy link
Contributor

We can only hope if @dolang is able to help you with this.

@ghost
Copy link
Author

ghost commented Apr 20, 2018

I am not sure what exactly the issue is here, but the best idea I have for the Cython issue is that requirements = python3crystax will use Python 3.5, and you list 3.6 in the issue report. You probably need python3crystax==3.6 to match the system Python, or downgrade system to 3.5 and install Cython there. Also worth trying p4a.branch = master in your spec file, some build issues may have been fixed since the most recent released version.

If that still doesn't help, please post a full build log with log_level 2

@ghost
Copy link
Author

ghost commented Apr 20, 2018

Also worth noting that Cython 0.28.x is not extensively tested; it works for me on desktop, but there could be differences for mobile, maybe uninstall it and try pip install Cython==0.27.3

@ghost
Copy link
Author

ghost commented Apr 21, 2018

Have install Cython 0.27.3, and applied the p4a.branch = master
Same error : Cython module missing, Detailed logs below
ImportError: No module named Cython.Distutils

However, something is not clear to me:

  • I have developped the app in python 3.6
  • I'm using the virtual machine provided in Kivy - Buildozer doc, for whom the default interpreter in python 2.7
  • I checked that python 3.5 is installed in the VM
  • Seems that buldozer is using the default interpeter (so python 2.7)

Maybe issue is coming from here ?

But again, what is weird is that the program on andoid failed only if I try to import screenmanager module...


[INFO]:    Copying pyjnius java class to classes build dir
[INFO]:    -> directory context /home/kivy/python/myapps/.buildozer/android/platform/build/build/other_builds/pyjnius-python3crystax-sdl2/armeabi-v7a/pyjnius
[INFO]:    -> running cp -a jnius/src/org /home/kivy/python/myapps/.buildozer/android/platform/buil...(and 28 more)
[INFO]:    <- directory context /home/kivy/python/myapps/.buildozer/android/platform/python-for-android-new-toolchain
[INFO]:    # Installing pure Python modules
[INFO]:    The requirements (git+https://github.com/kivy/kivy.git) don't have recipes, attempting to install them with pip
[INFO]:    If this fails, it may mean that the module has compiled components and needs a recipe.
[INFO]:    -> directory context /home/kivy/python/myapps/.buildozer/android/platform/build/build
[INFO]:    -> running virtualenv --python=python2.7 venv
[INFO]:    Creating a requirements.txt file for the Python modules
[INFO]:    Installing Python modules with pip
[INFO]:    If this fails with a message about /bin/false, this probably means the package cannot be installed with pip as it needs a compilation recipe.
[INFO]:    -> running bash -c source venv/bin/activate && env CC=/bin/false CXX=/bin/false PYTHONPA...(and 235 more)
           working:         from Cython.Distutils iException in thread background thread for pid 5528:                        
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/local/lib/python2.7/dist-packages/sh.py", line 2170, in background_thread
    handle_exit_code(exit_code)
  File "/usr/local/lib/python2.7/dist-packages/sh.py", line 1929, in fn
    return self.command.handle_command_exit_code(exit_code)
  File "/usr/local/lib/python2.7/dist-packages/sh.py", line 672, in handle_command_exit_code
    raise exc
ErrorReturnCode_1: 

  RAN: /bin/bash -c source venv/bin/activate && env CC=/bin/false CXX=/bin/false PYTHONPATH=/home/kivy/python/myapps/.buildozer/android/platform/build/build/python-installs/jejesh26 pip install --target '/home/kivy/python/myapps/.buildozer/android/platform/build/build/python-installs/jejesh26' --no-deps -r requirements.txt

  STDOUT:
Collecting git+https://github.com/kivy/kivy.git (from -r requirements.txt (line 1))
  Cloning https://github.com/kivy/kivy.git to /tmp/pip-req-build-os8M6i
    Complete output from command python setup.py egg_info:
    Using distutils
    
    Cython is missing, it's required for compiling kivy !
    
    
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-req-build-os8M6i/setup.py", line 227, in <module>
        from Cython.Distutils import build_ext
    ImportError: No module named Cython.Distutils
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-req-build-os8M6i/


  STDERR:


Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/kivy/python/myapps/.buildozer/android/platform/python-for-android-new-toolchain/pythonforandroid/toolchain.py", line 978, in <module>
    main()
  File "/home/kivy/python/myapps/.buildozer/android/platform/python-for-android-new-toolchain/pythonforandroid/toolchain.py", line 975, in main
    ToolchainCL()
  File "/home/kivy/python/myapps/.buildozer/android/platform/python-for-android-new-toolchain/pythonforandroid/toolchain.py", line 512, in __init__
    getattr(self, args.subparser_name.replace('-', '_'))(args)
  File "/home/kivy/python/myapps/.buildozer/android/platform/python-for-android-new-toolchain/pythonforandroid/toolchain.py", line 149, in wrapper_func
    build_dist_from_args(ctx, dist, args)
  File "/home/kivy/python/myapps/.buildozer/android/platform/python-for-android-new-toolchain/pythonforandroid/toolchain.py", line 193, in build_dist_from_args
    build_recipes(build_order, python_modules, ctx)
  File "pythonforandroid/build.py", line 592, in build_recipes
  File "pythonforandroid/build.py", line 633, in run_pymodules_install
  File "pythonforandroid/logger.py", line 175, in shprint
  File "/usr/local/lib/python2.7/dist-packages/sh.py", line 720, in next
    self.wait()
  File "/usr/local/lib/python2.7/dist-packages/sh.py", line 651, in wait
    self.handle_command_exit_code(exit_code)
  File "/usr/local/lib/python2.7/dist-packages/sh.py", line 672, in handle_command_exit_code
    raise exc
sh.ErrorReturnCode_1: 

  RAN: /bin/bash -c source venv/bin/activate && env CC=/bin/false CXX=/bin/false PYTHONPATH=/home/kivy/python/myapps/.buildozer/android/platform/build/build/python-installs/jejesh26 pip install --target '/home/kivy/python/myapps/.buildozer/android/platform/build/build/python-installs/jejesh26' --no-deps -r requirements.txt

  STDOUT:
Collecting git+https://github.com/kivy/kivy.git (from -r requirements.txt (line 1))
  Cloning https://github.com/kivy/kivy.git to /tmp/pip-req-build-os8M6i
    Complete output from command python setup.py egg_info:
    Using distutils
    
    Cython is missing, it's required for compiling kivy !
    
    
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-req-build-os8M6i/setup.py", line 227, in <module>
        from Cython.Distutils import build_ext
    ImportError: No module named Cython.Distutils

@ghost
Copy link
Author

ghost commented Apr 22, 2018

Seems that buldozer is using the default interpeter (so python 2.7)

I am not familiar with buildozer, but last I set up p4a, using system Python 3.4 did not work for building with Python 3.5 crystax. I have no idea what the relation to the ScreenManager thing is, if any, but certainly it's worth testing. I'd try uninstalling buildozer, and reinstall it using the pip from the interpreter version you are going to use. Also uninstall p4a if it's installed, just to make sure it's not some weird issue related to that.

I used pyenv to install Python 3.5, set it as default interpreter, and then install p4a. To use 3.6 I think the only required change in configuration is python3crystax==3.6 in requirements, but I never actually built that.

@ghost
Copy link
Author

ghost commented Apr 26, 2018

Dears,

finally I fixed the issue by recreating my own virtual environment on ubunto 16.04, using Python 3.6.5.

It took ages to finalize it as there are many tiny things to adjust on buildozer, but finally I made it.

Now application is running well, but can not find the settings of my app in the Samsung Galaxy

Here is the main.py for reference

# -*- coding: utf-8 -*-

import kivy
from kivy.app import App
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
from kivy.properties import ListProperty,StringProperty
from kivy.core.window import Window
from random import randint, randrange,uniform
from os.path import join, dirname,splitext, abspath
from kivy.uix.scatter import Scatter
from glob import glob 
from kivy.core.audio import SoundLoader
from kivy.utils import platform
import json
import time
from kivy.uix.settings import SettingsWithSidebar


settings_json = json.dumps([
    {
        'type': 'title',
        'title': 'Overall settings'
    },
    {   'type': 'path',
        'title': 'Path to Images',
        'desc': 'Images path :',
        'section': 'First section',
        'key': 'pathtoimages'
    },    
    {   'type': 'path',
        'title': 'Path to text',
        'desc': 'Images path :',
        'section': 'First section',
        'key': 'pathtotext'
    },    
    {   'type': 'path',
        'title': 'Path to Music',
        'desc': 'Music path :',
        'section': 'First section',
        'key': 'pathtomusic'
    },
    ])


Builder.load_string('''
#:kivy 1.0
#:import kivy kivy
#:import win kivy.core.window

<RootWidget>
	FloatLayout:
		size: 100,100

<Picture>:
	on_size: self.center = win.Window.center
	size: image.size
	size_hint: None, None
    Image:
		id: image
		source: root.source
		size: win.Window.size
        keep_ratio: True

<TransLabel>:
    Label:
        id: label
        text: root.thetext
		color: root.textcolor
        font_size: 200
        font_name: "simfang.ttf"
        bold: True
''')
curdir = dirname(abspath(__file__))
imgfolder = join(curdir,'static','img')
musicfolder = join(curdir,'static','mp3')
textfolder = join(curdir,'static','texts')

def getMusicFile():
    
    filenames=[]
    for filename in glob(join(musicfolder,'*.*')):
        if splitext(filename)[1].upper() =='.MP3' :
            filenames.append(filename)
    return filenames


def chooseText():
    filename = join(textfolder,'texts.txt')
    tabText = [line.rstrip('\n') for line in open(filename, encoding='utf-8', errors='ignore')]
    random_index = randrange(0,len(tabText))
    return tabText[random_index]

def generatecolor():
	l =[uniform(0, 1) for _ in range(3)] 	
	l.append(1)
	return l


class MusicPlayerAndroid(object):
    def __init__(self):

        from jnius import autoclass
        MediaPlayer = autoclass('android.media.MediaPlayer')
        self.mplayer = MediaPlayer()

        self.secs = 0
        self.actualsong = ''
        self.length = 0
        self.isplaying = False
        self.mplayer.setLooping(False)

    def __del__(self):
        self.stop()
        self.mplayer.release()

    def load(self, filename):
        try:
            self.actualsong = filename
            self.secs = 0
            self.mplayer.setDataSource(filename)        
            self.mplayer.prepare()
            self.length = self.mplayer.getDuration()
            return True
        except:
            return False

    def unload(self):
            self.mplayer.reset()

    def play(self):
        self.mplayer.start()
        self.isplaying = True

    def stop(self):
        self.mplayer.stop()
        self.secs=0
        self.isplaying = False

    def seek(self,timepos_secs):
        self.mplayer.seekTo(timepos_secs * 1000)

    def getCurrentPosition(self):
        return self.mplayer.getCurrentPosition()


def getPicture():
    filenames=[]
    for filename in glob(join(imgfolder,'*.*')):
        if splitext(filename)[1].upper() =='.JPG' :
            filenames.append(filename)
    random_index = randrange(0,len(filenames))
    return filenames[random_index]


class RootWidget(FloatLayout):
    def __init__(self, **kwargs):
        super(RootWidget,self).__init__(**kwargs)
        p= Picture()
        l = TransLabel()
        self.musicfiles = getMusicFile()
        random_index = randrange(0,len(self.musicfiles))           
        self.file = self.musicfiles[random_index]

        if platform != 'android':
            self.mplayer = SoundLoader.load(self.file)
            self.mplayer.play()
        else:
            self.mplayer = MusicPlayerAndroid()
            try:
                if self.mplayer.load(self.file):
                    self.mplayer.play()
            except Exception as e:
                print('')

        
        Clock.schedule_interval(self.check_sound,1)

        self.add_widget(p)
        self.add_widget(l)

    def check_sound(self, dt=None):
        if platform !='android' :
            if self.mplayer.get_pos() ==0 :
                self.mplayer.unload()
                random_index = randrange(0,len(self.musicfiles))           
                self.file = self.musicfiles[random_index]
                self.mplayer = SoundLoader.load(self.file)
                self.mplayer.play()
        else:
            dur = self.mplayer.getCurrentPosition()
            if self.mplayer.length <= dur:
                self.mplayer.unload()
                random_index = randrange(0,len(self.musicfiles))           
                self.file = self.musicfiles[random_index]
                try:
                    if self.mplayer.load(self.file):
                        self.mplayer.play()
                except Exception as e:
                    print('')

class Picture(Scatter):
    source = StringProperty(None)
    def __init__(self, **kwargs):
        super(Picture,self).__init__(**kwargs)	
        self.source = getPicture()
        Clock.schedule_interval(self.updatePicture, 8.)

    def updatePicture(self, *args):
        self.source = getPicture()


class TransLabel(Label):
	velocity = ListProperty([2,1])
	thetext = StringProperty()
	textcolor = ListProperty([0,0,0,1])

	def __init__(self, **kwargs):
		super(TransLabel,self).__init__(**kwargs)
		Clock.schedule_interval(self.updatePOS, 1./60.)
		self.x = randint(0, self.width)
		self.y = randint(0, self.height)
		self.Label = self.ids.label
		self.thetext= chooseText()
		self.textcolor = generatecolor()

		
		Clock.schedule_interval(self.updateTEXT, 9.)
		Clock.schedule_interval(self.updateCOLOR, 3.)
		
	
	def updatePOS(self,*args):
		self.x += self.velocity[0]
		self.y += self.velocity[1]
        
		if self.x <0 or (self.x + self.Label.width*1.5) > Window.width:
			self.velocity[0] *= -1

		if self.y <0 or (self.y + self.Label.height) > Window.height:
			self.velocity[1] *= -1

		self.Label.pos = [self.x, self.y]

	def updateTEXT(self, *args):
		self.thetext= chooseText()
	
	def updateCOLOR(self,*args):
	    self.textcolor = generatecolor()

class PicturesApp(App):
    def build(self):
        self.use_kivy_settings = False
        return RootWidget()

    def build_config(self,config):
        config.setdefaults('First section', 
                           {
                               'pathtoimages': imgfolder,
                                'pathtotext': textfolder,
                                 'pathtomusic': musicfolder
                            }
                           )
        return True
        
    def build_settings(self, settings):
        settings.add_json_panel('JejeSH26 settings',
                                self.config,
                                data=settings_json
                                )
        return True

if __name__=="__main__":
	PicturesApp().run()

@support
Copy link

support bot commented Jun 14, 2018

👋 We use the issue tracker exclusively for bug reports and feature requests. However, this issue appears to be a support request. Please use our support channels to get help with the project.

If you're having trouble installing Kivy, make sure to check out the installation docs for Windows, Linux and macOS.

Let us know if this comment was made in error, and we'll be happy to reopen the issue.

@support support bot closed this as completed Jun 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants