【问题标题】:How can I build Android application for Oracle database using Buildozer?如何使用 Buildozer 为 Oracle 数据库构建 Android 应用程序?
【发布时间】:2017-04-22 03:07:22
【问题描述】:

我在 Kivy 上有一个大问题。你能帮帮我吗?

我为我的公司开发库存控制应用程序。我的公司使用 Oracle 数据库。我用 Kivy、Python 编写代码,并使用 cx_Oracle 连接我们的数据库。它在我的电脑上完美运行。但它不适用于我的 Android 手机。我使用 Buildozer 构建了一个 APK。在我接受错误后,我写日志。这就是我得到的错误:

python  :  ImportError: No module named cx_Oracle

我的 Android 手机没有找到 cx_Oracle。我无法通过手机访问 Oracle 数据库,并且应用程序无法运行。有什么方法可以推荐吗?

    #!/usr/local/bin/python
    # -*- coding: UTF-8 -*-

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
    from kivy.uix.relativelayout import RelativeLayout
    from kivy.properties import StringProperty
    from kivy.network.urlrequest import UrlRequest
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.label import Label
    from kivy.uix.dropdown import DropDown
    from kivy.uix.textinput import TextInput
    from kivy.properties import ListProperty
    from kivy.uix.floatlayout import FloatLayout
    import cx_Oracle
    import os, sys

    Builder.load_string('''

    #:import Button kivy.uix.button.Button

    <GirisEkrani>:
        BoxLayout:
            id: login_layout
            orientation: 'vertical'
            padding: [10,50,10,50]
            spacing: 50

            BoxLayout:
                orientation: 'vertical'

                Label:
                    text: '*'
                    font_size: 18
                    halign: 'left'
                    text_size: root.width-20, 20

                TextInput:
                    id: username
                    multiline:False
                    font_size: 28
            BoxLayout:
                orientation: 'vertical'

                Label:
                    text: '*'
                    halign: 'left'
                    font_size: 18
                    text_size: root.width-20, 20
                TextInput:
                    id: passwd
                    multiline:False
                    password:True
                    font_size: 28

            Button:
                text: "*"
                font_size: 24
                on_press: root.login()


    <GirisOnayEkrani>:
        karsilama_yazisi: karsilama_yazisi

        BoxLayout:
            id: kutu
            orientation: "vertical"
            padding: [10,50,10,50]
            spacing: 50

            Image:
                source: "./dogru.png"
            Label:
                id: karsilama_yazisi
                text: "*"

            Button:
                text: "Stok Kontrol"
                font_size: 24
                on_press: root.envanter()

            Button:
                text: "*"
                font_size: 24
                on_press: root.talepsikayet()



    <GirisRedEkrani>:
        BoxLayout:
            orientation: "vertical"
            Image:
                source: "./yanlis.png"
            Label:
                text: "*"
            Button:
                text: "*"
                on_press: root.anaEkranaDon()

    <EnvanterKontrolEkrani>:
        BoxLayout:
            orientation: "vertical"
            padding: [50,150,50,150]
            spacing: 300

            Button:
                text: "*"
                size_hint_y: None
                font_size: 20
                on_press: root.ekle()

            AnchorLayout:
                anchor_x: 'center'
                anchor_y: 'center'

                ScrollView:
                    size_hint_y: None
                    height: '500dp'

                    MyGrid:
                        cols: 3
                        size_hint_y: None
                        height: self.minimum_height
                        spacing: '2dp'

    <EklemeEkrani>:
        BoxLayout:
            id: login_layout
            orientation: 'vertical'
            padding: [10,50,10,50]
            spacing: 30

            BoxLayout:
                orientation: 'vertical'

                Label:
                    text: "*"
                    font_size: 18
                    halign: 'left'
                    text_size: root.width-20, 20

                TextInput:
                    id: partno
                    multiline:False
                    font_size: 28
            BoxLayout:
                orientation: 'vertical'

                Label:
                    text: '*'
                    halign: 'left'
                    font_size: 18
                    text_size: root.width-20, 20
                TextInput:
                    id: miktar
                    multiline:False
                    font_size: 28

            BoxLayout:
                orientation: 'vertical'

                Label:
                    text: '*'
                    halign: 'left'
                    font_size: 18
                    text_size: root.width-20, 20
                TextInput:
                    id: tarih
                    multiline:False
                    font_size: 28

            Button:
                text: "*"
                font_size: 24
                on_press: root.eklemek()



    <TalepSikayetEkrani>:
        BoxLayout:
            id: login_layout
            orientation: 'vertical'
            padding: [10,50,10,50]
            spacing: 15


            BoxLayout:
                orientation: 'vertical'

                Label:
                    text: '*'
                    halign: 'left'
                    font_size: 16
                    text_size: root.width-20, 20

                ComboEdit:
                    id: birim
                    multiline:False
                    font_size: 20
                    options:
                        [Button(text = '*', size_hint_y=None, height=30),
                        Button(text = '*', size_hint_y=None, height=30),
                        Button(text = '*', size_hint_y=None, height=30)]

            BoxLayout:
                orientation: 'vertical'

                Label:
                    text: '*'
                    halign: 'left'
                    font_size: 16
                    text_size: root.width-20, 20

                ComboEdit:
                    id: form
                    multiline:False
                    font_size: 20
                    options:
                        [Button(text = '*', size_hint_y=None, height=30),
                        Button(text = '*', size_hint_y=None, height=30),
                        Button(text = '*', size_hint_y=None, height=30)]

            BoxLayout:
                orientation: 'vertical'

                Label:
                    text: '*'
                    halign: 'left'
                    font_size: 16
                    text_size: root.width-20, 20

                ComboEdit:
                    id: onem
                    multiline:False
                    font_size: 20
                    options:
                        [Button(text = '*', size_hint_y=None, height=30),
                        Button(text = '*', size_hint_y=None, height=30),
                        Button(text = '*', size_hint_y=None, height=30)]

            BoxLayout:
                orientation: 'vertical'           
                Label:
                    text: '*'
                    halign: 'left'
                    font_size: 18
                    text_size: root.width-20, 20
                TextInput:
                    id: konu
                    multiline:False
                    font_size: 20


            BoxLayout:
                orientation: 'vertical'           
                Label:
                    text: '*'
                    halign: 'left'
                    font_size: 18
                    text_size: root.width-20, 20
                TextInput:
                    id: mesaj
                    multiline:False
                    font_size: 20

            Button:
                text: "*"
                font_size: 24
                on_press: root.formekle()


    <TalepSikayetOnayEkrani>:
        karsilama_yazisi: karsilama_yazisi

        BoxLayout:
            id: kutu
            orientation: "vertical"
            padding: [10,50,10,50]
            spacing: 50

            Image:
                source: "./true.png"
            Label:
                id: karsilama_yazisi
                text: "*"

            Button:
                text: "Anasayfaya Don"
                font_size: 24
                on_press: root.anasayfa()



    <PlayerRecord>:
        size_hint_y: None
        height: '30dp'
        width: '100dp'

        canvas.before:
            Color:
                rgb: 0.2, 0.2, 0.2
            Rectangle:
                pos: self.pos
                size: self.size


    <RootWidget>:
        canvas.before:
            Color:
                rgba: 0, 0, 0, 1
            Rectangle:
                pos: self.pos
                size: self.size
        id: kok
        GirisEkrani:
            id: giris
            name: "giris_ekrani"
        GirisOnayEkrani:
            id: onay
            name: "giris_basarili"
        GirisRedEkrani:
            id: red
            name: "giris_hatali"
        EnvanterKontrolEkrani:
            id:envanter
            name: "envanter_kontrol"
        EklemeEkrani:
            id:ekle
            name: "ekleme"
        TalepSikayetEkrani:
            id:talepsikayet
            name: "talep_sikayet"

        TalepSikayetOnayEkrani:
            id:talepsikayetonay
            name: "talep_onay"

    ''')




    class GirisEkrani(Screen):
        def login(self):
            if self.ids.username.text == "*" and\
                self.ids.passwd.text == "*":

                self.manager.current = "giris_basarili"

            else:
                self.manager.current = "giris_hatali"


    class GirisOnayEkrani(Screen):
        def envanter(self):
            self.manager.current = "envanter_kontrol"
        def talepsikayet(self):
            self.manager.current = "talep_sikayet"

    class EnvanterKontrolEkrani(Screen):
        def ekle(self):
            self.manager.current = "ekleme"

    class TalepSikayetEkrani(Screen):
        def formekle(self):
            if len(self.ids.birim.text) > 0 and\
               len(self.ids.form.text) > 0 and\
               len(self.ids.onem.text) > 0 and\
               len(self.ids.konu.text) > 0 and\
               len(self.ids.mesaj.text) > 0:
                con = cx_Oracle.connect('*/*@*/*')
                rows = [(str(self.ids.birim.text), str(self.ids.form.text), str(self.ids.onem.text), str(self.ids.konu.text), str(self.ids.mesaj.text))]
                cur = con.cursor()
                cur.executemany("INSERT INTO * (birim , form, onem, konu, mesaj) VALUES (:1, :2, :3, :4, :5)", rows)
                con.commit()
                self.manager.current = "talep_onay"
                self.ids.birim.text = ""
                self.ids.form.text = ""
                self.ids.onem.text = ""
                self.ids.konu.text = ""
                self.ids.mesaj.text = ""
            else:
                self.manager.current = "giris_hatali"


    class ComboEdit(TextInput):

        options = ListProperty(('', ))

        def __init__(self, **kw):
            ddn = self.drop_down = DropDown()
            ddn.bind(on_select=self.on_select)
            super(ComboEdit, self).__init__(**kw)

        def on_options(self, instance, value):
            ddn = self.drop_down
            ddn.clear_widgets()
            for widg in value:
                widg.bind(on_release=lambda btn: ddn.select(btn.text))
                ddn.add_widget(widg)

        def on_select(self, *args):
            self.text = args[1]

        def on_touch_up(self, touch):
            if touch.grab_current == self:
                self.drop_down.open(self)
            return super(ComboEdit, self).on_touch_up(touch)


    class TalepSikayetOnayEkrani(Screen):
        def anasayfa(self):
            self.manager.current = "giris_ekrani"


    class EklemeEkrani(Screen):
        def eklemek(self):
            if len(self.ids.partno.text) > 1 and\
               len(self.ids.miktar.text) > 1 and\
               len(self.ids.tarih.text) > 1:
                con = cx_Oracle.connect('*/*@*/*')
                rows = [(str(self.ids.partno.text), str(self.ids.miktar.text), str(self.ids.tarih.text))]
                cur = con.cursor()
                cur.executemany("INSERT INTO * (part_no, qty_on_hand, tarih) VALUES (:1, :2, :3)", rows)
                con.commit()
                self.manager.current = "giris_basarili"
                self.ids.partno.text = ""
                self.ids.miktar.text = ""
                self.ids.tarih.text = ""
            else:
                self.manager.current = "giris_hatali"




    class GirisRedEkrani(Screen):
        def anaEkranaDon(self):
            self.manager.current = "giris_ekrani"


    class RootWidget(ScreenManager):
        pass


    class TableHeader(Label):
        pass


    class PlayerRecord(Label):
        pass


    class MyGrid(GridLayout):

        def __init__(self, **kwargs):
            super(MyGrid, self).__init__(**kwargs)
            self.fetch_data_from_database()
            self.display_scores()

        def fetch_data_from_database(self):
            con = cx_Oracle.connect('*/*@*/*')

            cur=con.cursor()
            cur.execute('''select part_no, qty_on_hand, tarih from *''')

            liste =[{'Part No': 'Part No', 'Quantity On Hand': 'Quantity On Hand', 'Expiration Date': 'Expiration Date'}]


            for result in cur:

                liste.append({'Part No': result[0], 'Quantity On Hand': str(result[1]), 'Expiration Date': str(result[2])})

            self.data = liste


        def display_scores(self):
            self.clear_widgets()
            for i in range(len(self.data)):           
                row = self.create_player_info(i)
                for item in row:
                    self.add_widget(item)


        def create_player_info(self, i):
            first_column = PlayerRecord(text=self.data[i]['Part No'])
            second_column = PlayerRecord(text=self.data[i]['Quantity On Hand'])
            third_column = PlayerRecord(text=self.data[i]['Expiration Date'])
            return [first_column, second_column, third_column]

    class CemApp(App):
        def build(self):
            return RootWidget()

    if __name__ in ('__main__','__android__'):
        CemApp().run()

注意:我用“*”隐藏了我的公司数据

【问题讨论】:

    标签: android python oracle kivy buildozer


    【解决方案1】:

    您需要在 APK 中包含 cx_Oracle 模块。但是,cx_Oracle 是一个已编译的 C 模块,因此 python-for-android 需要一个 recipe 才能编译它(供参考,here 是所有现有配方)。目前还没有这样的食谱,但你可以尝试写一个。你可能想要CompiledComponentsPythonRecipe

    【讨论】:

    • 感谢您的回答!很难为我写一个食谱,因为我的水平较低。有没有其他方法可以在 Android 手机中添加 cx_Oracle ?
    猜你喜欢
    • 2022-09-23
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 2013-11-19
    • 2011-12-19
    • 1970-01-01
    相关资源
    最近更新 更多