How to detect screen resolution in Android at python/kivy/pyjnius?

749 Views Asked by At

I need to know screen resolution in pixels in application that is created in Python with Kivy. The specific question concerns Android. Kivy itself unfortunately doesn't want to transfer information obtained from GL to user, so I have to use workarounds. Under Android it's pyjnius, according to pyjnius manual and DisplayMetrics manual I've tried this code:

from kivy.app import App
from kivy.uix.button import Button
from kivy.utils import platform
from kivy.core.window import Window
from kivy.graphics import Canvas, Rectangle, Color

myheight=-100
mywidth=-100
myDPI=-100
gDPI=-100
Window.fullsceen = True

if platform == 'android':
    from jnius import autoclass
    DisplayMetrics = autoclass('android.util.DisplayMetrics')
    metrics = DisplayMetrics()
    gDPI=metrics.getDeviceDensity()
    myheight = metrics.heightPixels
    mywidth = metrics.widthPixels
    myDPI = metrics.densityDpi

class MainApp(App):
  def build(self):
    b = Button(text="Height: "+ str(myheight) + "\nWidth: " + str(mywidth) + "\nDPI: " + str(myDPI) + "\ngetDPI: " + str(gDPI)
+ '\nWindow.size:' + str(Window.size), color = [0,0,0,1])
    with b.canvas:
       Color(0,1,1, .2)
       Rectangle(size = Window.size, pos = (0,0))
    return b

MainApp().run()

But in the result I have all three values = 0, and window size = 800px independently from platfrom. Pyjnius manual use method getDeviceDensity() that is not documented in DisplayMetrics methods. Are there any alternative methods how can I detect screen resolution in kivy under android? Can I call directly SDL2 to detect screen resolution and where it has to be done properly? The screenshot (as requested) is attached.enter image description here

Thanks in advance.

3

There are 3 best solutions below

0
On

This worked for me:

DisplayMetrics = autoclass('android.util.DisplayMetrics')
Context = autoclass('android.content.Context')
PythonActivity = autoclass("org.kivy.android.PythonActivity")

metrics = DisplayMetrics()
a = PythonActivity.mActivity
wm = a.getSystemService(Context.WINDOW_SERVICE)
d = wm.getDefaultDisplay()
d.getMetrics(metrics)
0
On

This example will work

from kivy.lang import Builder

from kivy.app import App

from jnius import autoclass

PythonActivity = autoclass("org.kivy.android.PythonActivity")
activity = PythonActivity.mActivity
displayMetrics = activity.getContext().getResources().getDisplayMetrics()

KV = '''
Screen:
    BoxLayout:
        id: container
        orientation: 'vertical'
        padding: dp(10)
        spacing: dp(10)
        
        Label:
            id: lbl
            halign: 'center'

        Widget:
'''


class Test(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)

        self.screen.ids.lbl.text += f'Width: {self.get_screen_width_dpi()}\n'
        self.screen.ids.lbl.text += f'Height: {self.get_screen_height_dpi()}\n'
        self.screen.ids.lbl.text += f'DPI: {displayMetrics.densityDpi}\n'

    @staticmethod
    def get_screen_width_dpi():
        return displayMetrics.widthPixels / displayMetrics.density

    @staticmethod
    def get_screen_height_dpi():
        return displayMetrics.heightPixels / displayMetrics.density

    def build(self):
        return self.screen


Test().run()
12
On

Kivy itself unfortunately doesn't want to transfer information obtained from GL to user

I'm not sure what you mean by this, kivy.core.window.Window.size should give the gl display size. This is not, of course, the same thing as the screen resolution that you asked for - I'm not sure if that matters to you.

But in the result I have all three values = 0

This appears to be for the reason described e.g. in this question.