Giter VIP home page Giter VIP logo

kvdroid's Introduction

KvDroid

A re-implementation of android java API in python with easy access to some Android functionality like Notification, Reading of Contacts, accessing Webview Cookies, etc...

The aim is to provide full access to Android API which can be used together with Python frameworks like: kivy, kivymd, etc... Or as a standalone, in which Android native UI is created with only python codes.

Compiling into APK

To compile, kivy p4a or kivy buildozer is required, and bootstrap must be set to sdl2

Dependencies

Android min-api21

Installation

pip install kvdroid

or

pip install https://github.com/kvdroid/Kvdroid/archive/refs/heads/master.zip # master version
# Note: this works on android only, but you can install it on your desktop for code completion assistance

Buildozer Requirement

requirement = kvdroid

or

requirement = https://github.com/kvdroid/Kvdroid/archive/refs/heads/master.zip

Usage

To send notification

from kvdroid.jclass.android.graphics import Color
from kvdroid.tools.notification import (
    create_notification, 
    get_notification_reply_text,
    KVDROID_TAP_ACTION_NOTIFICATION,
    KVDROID_ACTION_1_NOTIFICATION,
    KVDROID_REPLY_ACTION_NOTIFICATION
)
from kvdroid.tools import get_resource
from kvdroid.tools.broadcast import BroadcastReceiver
from android.activuty import bind as activity_bind  # noqa


def perform_intent_action(intent):
    if extras := intent.getExtras():
        if value := extras.getString("tap"):
            # replace below code with whatever action you want to perform
            print("it is a tap")
            # incase you want to use the value too
            print(value)
        elif value := extras.getString("action1"):
            # replace below code with whatever action you want to perform
            print("it is an action1")
            # incase you want to use the value too
            print(value)
        elif value := extras.getString("reply"):
            # replace "TEST_KEY" with whatever 'key_reply_text' you used in creating
            # your notification
            reply = get_notification_reply_text(intent, "TEST_KEY")
            print(reply)
            # incase you want to use the value too
            print(value)


def get_notification_intent(intent):
    perform_intent_action(intent)


def get_notification_broadcast(context, intent):
    perform_intent_action(intent)
    
# This should be binded only once, else you get weird behaviors
# if you are creating different notifications for different purpose,
# you can bind different functions but only bind them once
activity_bind(on_new_intent=get_notification_intent)

br = BroadcastReceiver(
    callback=get_notification_broadcast, 
    actions=[
        KVDROID_TAP_ACTION_NOTIFICATION,
        KVDROID_ACTION_1_NOTIFICATION,
        KVDROID_REPLY_ACTION_NOTIFICATION
    ],
    use_intent_action=False
)
# start BroadcastReceiver before launching your notification.
br.start()

"""
stop your broad cast receiver when your app is closed
>>>
def on_stop(self):
    br.stop()
>>>
"""

create_notification(
    small_icon=get_resource("mipmap").icon,  # replace `.icon` with the image filename you set as your app icon without the file extension (e.g without .png, .jpg ...)
    channel_id="ch1", # you must set this to any string value of your choice
    title="You have a message", # title of your notification
    text="hi, just wanted to check on you", # notification content text
    ids=1, # notification id, can be used to update certain notification
    channel_name=f"message", # provides a user-friendly label for the channel, helping users understand the purpose or category of notifications associated with that channel.
    large_icon="assets/image.png",
    small_icon_color=Color().rgb(0x00, 0xC8, 0x53),  # 0x00 0xC8 0x53 is same as 00C853
    big_picture="assets/image.png",
    action_title1="action1",
    reply_title="reply",
    key_text_reply="TEST_KEY",
    # for effective use of this, please read the extras section of the documentation below
    # There are only 3 actions and 1 reply, but the 3 actions cannot exist together all at once
    # together with the reply. 1 of the actions must go.
    # The 3 actions must be declared with this names: 'action1', 'action2', 'action3'
    # the reply must retain the name: 'reply'. Same with tap: 'tap'
    extras={
        "tap": ("tap", "I tapped the notification"), 
        "action1": ("action1", "I pressed action1 button"),
        "reply": ("reply", "use get_notification_reply_text(intent, key_text_reply) to get my text")
    },
    # if you set this to true, it means that you don't want your app to open
    # when you tap on the notification or tap on any of the action button or reply
    # so you don't need to bind an intent function, here you make use of BrodcastReceiver
    # check the above code
    broadcast=False
)

Further notification description

:Parameters:
    `small_icon`: int
        The icon that appears at the top left conner of the android notification.
        Icon can be accessed by calling `get_resource(resource, activity_type=activity)`
        from kvdroid.tools module
    `channel_id`: str
        In Android, a channel ID is used to categorize and manage notifications.
        It's a unique identifier associated with a notification channel, which is
        a way to group and configure notifications in a specific way. Notification
        channels were introduced in Android Oreo (API level 26) to give users more
        control over how they receive and interact with notifications.
    `title`: str
        The title is a short, descriptive text that provides context for the
        notification's content. It's often displayed prominently at the top of the notification.
    `text`: str
        Text provides additional information related to the notification's title and
        helps users understand the purpose or context of the notification.
    `ids`: int
        The ids is an identifier used to uniquely identify a notification.
        It allows you to manage and update notifications, especially when you have
        multiple notifications displayed or want to update an existing notification with a new one.
    `channel_name`: str
        The channel_name is a human-readable name or description associated with a notification
        channel. It provides a user-friendly label for the channel, helping users understand
        the purpose or category of notifications associated with that channel.
    `large_icon`: Union[int, str, InputStream()]
        The large_icon is an optional image or icon that can be displayed alongside the
        notification's content. It's typically a larger image than the smallIcon and
        is used to provide additional context or visual appeal to the notification.
    `big_picture`: Union[int, str, InputStream()]
        the big_picture is a style of notification that allows you to display a large
        image, often associated with the notification's content. This style is
        particularly useful for notifications that include rich visual content,
        such as image-based messages or news articles.
    `action_title1`: str
        text that are displayed on notification buttons, used to also create notification
        buttons too.
    `action_title2`: str
        text that are displayed on notification buttons, used to also create notification
        buttons too.
    `action_title3`: str
        text that are displayed on notification buttons, used to also create notification
        buttons too.
    `key_text_reply`: str
        When you want to enable users to reply to notifications by entering text,
        you can use Remote Input, which is a feature that allows you to capture text input
        from users in response to a notification. key_text_reply is a symbolic
        representation or a constant used in your code to identify and process the
        user's text input when responding to notifications.
    `reply_title`: str
        text that is displayed on notification reply buttons, used to also create notification
        reply buttons too.
    `auto_cancel`: bool
        In Android notifications, the auto_cancel behavior is typically implemented by
        setting the setAutoCancel(true) method on the notification builder. When you
        set autoCancel to true, it means that the notification will be automatically
        canceled (dismissed) when the user taps on it. This is a common behavior for
        notifications where tapping the notification is expected to take the user to a
        corresponding activity or open a specific screen within the app.
    `extras`: dict
        A dictionary of string (keys) and tuple (values). Must be in this format
        ```python
        {
            "tap": (key, value),
            "action1": (key, value),
            "action2": (key, value),
            "action3": (key, value),
            "action1": (key, value),
            "reply": (key, value)
        }

        or 

        {"action1": (key, value)} or {"reply": (key, value)} or
        {"action1": (key, value), "reply": (key, value)} ...
        ```
        Extras are used to add additional data or key-value pairs to a notification.
        This allows you to attach custom data to a notification so that you can retrieve
        and process it when the user interacts with the notification
    `small_icon_color`: int
        the small_icon_color is primarily used to set the background color for the
        small icon in the notification header. It influences the color of the small
        circle that appears behind the small icon in the notification.

        Example using Color class from kvdroid.jclass.android module:
        `Color().BLUE`, `Color().rgb(0x00, 0xC8, 0x53),  # 0x00 0xC8 0x53 is same as 00C853`
    `java_class`: object
        an activity or any suitable java class
    `priority`: int
        the priority is used to set the priority level of a notification. The priority
        level determines how the notification should be treated in terms of importance
        and visibility. It helps the Android system and user to understand
        the significance of the notification.

        Here are the values that cn be used `from kvdroid.jclass.androidx` module:

        `NotificationCompat().PRIORITY_DEFAULT`:
            This is the default priority level. Notifications
            with this priority are treated as regular notifications. They are displayed in the
            notification shade but do not make any special sound or vibration. The user may see
            these notifications if they expand the notification shade.

        `NotificationCompat().PRIORITY_LOW`:
            Notifications with this priority are considered
            low-priority. They are displayed in a less prominent way and do not typically make a
            sound or vibration. They are often used for less important notifications that the user
            may not need to see immediately.

        `NotificationCompat().PRIORITY_MIN`:
            This is the minimum priority level. Notifications with
            this priority are considered the least important. They are not shown to the user unless the
            user explicitly opens the notification shade.

        `NotificationCompat().PRIORITY_HIGH:
            Notifications with this priority are considered high-priority.
            They are displayed prominently, may make a sound or vibration, and are intended to grab the user's
            attention. These are often used for important notifications that require immediate user interaction.

        `NotificationCompat().PRIORITY_MAX`:
            This is the maximum priority level. Notifications with this priority are treated as the most
            important and are displayed prominently with sound and vibration. They are typically used for
            critical notifications that require immediate attention.
    `defaults`: int
        the setDefaults() method is used to set the default behavior for a notification, such as whether
        it should make a sound, vibrate, or use the device's LED indicator. This method allows you to
        specify a combination of default notification behaviors.

        Here are the values that cn be used `from kvdroid.jclass.androidx` module:

        `NotificationCompat().DEFAULT_SOUND`: Use the default notification sound.
        `NotificationCompat().DEFAULT_VIBRATE: Make the device vibrate.
        `NotificationCompat().DEFAULT_LIGHTS`: Use the device's LED indicator (if available).
        `NotificationCompat().DEFAULT_ALL`: Use all default behaviors (sound, vibration, and LED).
    `broadcast`: bool
        sends out a broadcast message to your app to perform an action when an action button is
        clicked or reply is sent from your apps notification
:return: notification_manager

To read Contacts

from kvdroid.tools.contact import get_contact_details
#add this in buildozer permission 'android.permission.READ_CONTACTS'


def request_android_permissions(self):
    #call this function on_start function
    from android.permissions import request_permissions, Permission
    def callback(permissions, results):
        if all([res for res in results]):
            print("callback. All permissions granted.")
        else:
            print("callback. Some permissions refused.")

request_permissions([Permission.READ_CONTACTS, Permission.WRITE_CONTACTS, ], callback)


get_contact_details("phone_book") # gets a dictionary of all contact both contact name and phone mumbers
get_contact_details("names") # gets a list of all contact names
get_contact_details("mobile_no") # gets a list of all contact phone numbers

To get a list of all installed packages (Applications)

from kvdroid.tools.package import all_packages

print(all_packages())

"""
['com.google.android.carriersetup',
 'com.android.cts.priv.ctsshim',
 'com.google.android.ext.services',
 'com.android.providers.telephony',
 'com.android.providers.calendar'...]
"""

To get all main activities

from kvdroid.tools.package import all_main_activities

print(all_main_activities())

"""
[{'com.android.settings': 'com.android.settings.Settings'},
 {'com.android.vending': 'com.android.vending.AssetBrowserActivity'},
 {'com.google.android.contacts': 'com.android.contacts.activities.PeopleActivity'},
 {'com.google.android.deskclock': 'com.android.deskclock.DeskClock'}...]
"""

To check if the package is a system application

from kvdroid.tools.package import is_system_package

print(is_system_package("com.android.settings"))

To check if the package is enabled

from kvdroid.tools.package import is_package_enabled

print(is_package_enabled("com.android.settings"))

To get a specific app details

from kvdroid.tools.package import package_info

print(package_info("com.android.settings"))

"""
{'activities': ['org.chromium.settings.SettingsBlackHoleActivity',
                'com.android.settings.Settings$NetworkDashboardActivity',
                'com.android.settings.network.NetworkSettings',
                'com.android.settings.Settings$AdvancedAppsActivity',
                'com.android.settings.app.AdvancedAppsSettings'...],
 'dataDir': '/data/user_de/0/com.android.settings',
 'loadIcon': <android.graphics.drawable.Drawable at 0x7e8e15bac8b0 jclass=android/graphics/drawable/Drawable jself=<LocalRef obj=0x6196 at 0x7e8e15f63e30>>,
 'loadLabel': 'Settings',
 'packageName': 'com.android.settings',
 'permissions': ['org.chromium.settings.ENABLE_INPUT_METHOD',
                 'android.permission.REQUEST_NETWORK_SCORES',
                 'android.permission.WRITE_MEDIA_STORAGE',
                 'android.permission.WRITE_EXTERNAL_STORAGE'...],
 'processName': 'com.android.settings',
 'publicSourceDir': '/system/priv-app/ArcSettings/ArcSettings.apk',
 'sharedLibraryFiles': None,
 'sourceDir': '/system/priv-app/ArcSettings/ArcSettings.apk'}
"""

To get an activity info

from kvdroid.tools.package import activity_info

print(activity_info("com.android.settings","com.android.settings.network.NetworkSettings"))

"""
{'loadIcon': <android.graphics.drawable.Drawable at 0x7e8e15c46db0 jclass=android/graphics/drawable/Drawable jself=<LocalRef obj=0x6156 at 0x7e8e15c8c8b0>>,
 'loadLabel': 'Network and Internet'}
"""

To save a drawable object to given path as png

from kvdroid.tools.package import package_info
from kvdroid.tools.graphics import save_drawable

app = package_info("com.android.settings")
app_icon = app["loadIcon"]

# <android.graphics.drawable.Drawable at 0x7e8e15c46db0 jclass=android/graphics/drawable/Drawable jself=<LocalRef obj=0x6156 at 0x7e8e15c8c8b0>>

save_drawable(app_icon, "< path >", "< file_name >")

# That will save the app icon to given path and return the path + filename
# can be used like

from kivy.uix.image import Image

Image(source=save_drawable(app_icon, "< path >", "< file_name >"))

To check if the given app is installed from PlayStore

from kvdroid.tools.package import package_source

print(package_source("< package_name >"))

To get Android WebView Cookies

from kvdroid.tools.webkit import get_cookies

get_cookies("https://google.login")

To detect keyboard height

from kvdroid.tools import keyboard_height

print(keyboard_height())

To detect if app is installed from Play Store or not

from kvdroid.tools.appsource import app_source

print(app_source())

To get application infos

name pkg_name version_name version_code

from kvdroid.tools.appsource import app_info

print(app_info("name"))

To get application directories

data app files cache ext_files ext_cache

from kvdroid.tools.appsource import app_dirs

print(app_dirs("files")) #/data/data/package/files
print(app_dirs("ext_files"), slash = True) #/storage/sdcard0/Android/data/package/files/

To get absolute screen size in dp-pixel and detect current orientation

from kvdroid.tools.metrics import Metrics
screen = Metrics()

print(screen.orientation())
print(screen.width_dp())
print(screen.height_px())
print(screen.resolution())

To check if device has a data connection.

from kvdroid.tools.network import network_status, wifi_status, mobile_status, get_wifi_signal

print(network_status())  # for both wifi and mobile
print(wifi_status())    # only for wifi
print(mobile_status())    # only for mobile
print(get_wifi_signal())    # only for wifi

To get Wi-Fi signal strenght.

from kvdroid.tools.network import  get_wifi_signal

print(get_wifi_signal()) 

To get network latency.

from kvdroid.tools.network import  network_latency

print(network_latency()) 

To check if device is in dark mode or not

from kvdroid.tools.darkmode import dark_mode

print(dark_mode())

To get device informations. Available options are; 'model','brand','manufacturer','version','sdk','product','base','rom','security','hardware','tags','sdk_int','total_mem','used_mem','avail_ram','total_ram','used_ram','bat_level','bat_capacity','bat_temperature','bat_voltage','bat_technology', 'bat_status', 'bat_health'

from kvdroid.tools.deviceinfo import device_info

print(device_info("model"))
print(device_info("avail_ram", convert=True))

To enable immersive mode

from kvdroid.tools import immersive_mode

immersive_mode()

To launch an application

from kvdroid.tools import launch_app

launch_app("< app_package >")

To launch a specific application activity

from kvdroid.tools import launch_app_activity

launch_app_activity("< app_package >", "< app_activity >")

To open target app's details page

from kvdroid.tools import app_details

app_details("< app_package >")

To detect current device's language

from kvdroid.tools.lang import device_lang

print(device_lang())    # en
print(device_lang("DisplayLanguage"))    # English
print(device_lang(option = "DisplayLanguage", display_lang = "fr"))     # Anglais

"""
Available options are ;

Language           ---> en      
ISO3Language       ---> eng 
Country            ---> US 
ISO3Country        ---> USA 
DisplayCountry     ---> United States 
DisplayName        ---> English (United States) 
String             ---> en_US
DisplayLanguage    ---> English
LanguageTag        ---> en-US
"""

To get a list of supported languages on the device

from kvdroid.tools.lang import supported_languages
print(supported_languages())

"""
['af', 'agq', 'ak', 'am', 'ar', 'as', 'asa', 'ast'...]
"""

To set statusbar color

from kvdroid.tools import change_statusbar_color

change_statusbar_color("#FFFFFF", "black")

To set navigationbar color

from kvdroid.tools import navbar_color

navbar_color("#FFFFFF")

To display a toast message

from kvdroid.tools import toast

toast("hello world")

To get absolute sdcard path and media directories

alarm dcim download documents movies music notifications pictures podcasts ringtones

from kvdroid.tools.path import sdcard

print(sdcard()) #/storage/sdcard0
print(sdcard("download")) #/storage/sdcard0/Download
print(sdcard("download", slash = True)) #/storage/sdcard0/Download/

To get absolute external_sdcard

from kvdroid.tools.path import external_sdcard

print(external_sdcard()) 

To get file mime Type

from kvdroid.tools import mime_type

mime_type = mime_type("path/to/file")
print(mime_type)

To change default wallpaper

from kvdroid.tools import set_wallpaper

set_wallpaper("/sdcard/test.jpg")

To use text-to-speech

from kvdroid.tools import speech

speech("hello world", "en")

To use default Download Manager

from kvdroid.tools import download_manager

download_manager("< title >", "< description >", "< URL >", "< path >", "< file >")

To restart the app

from kvdroid.tools import restart_app

restart_app()

To share text via Android Share menu

from kvdroid.tools import share_text

share_text("hello world", title="Share", chooser=False, app_package=None,
           call_playstore=False, error_msg="application unavailable")

To share any file via Android Share menu

from kvdroid.tools import share_file

share_file(
    "< path - to - file >", "< title >", "< chooser >", "< app - package: open -with-default - app >",
    "< call_playstore >", "< error_msg >")
share_file("/sdcard/test.pdf", title='Share', chooser=False, app_package=None,
           call_playstore=False, error_msg="application unavailable")

To play supported music format or radio stream through Android Media Player

player.mPLayer = Android Media PLayer

from kvdroid.tools.audio import Player

player = Player()
player.play("< path - to - music - file >")
player.stream("https://bit.ly/3mHQdzZ")  # radio
player.pause()
player.resume()
player.seek(2) # seconds
player.do_loop(True)  # default is False
player.is_playing()
player.get_duration()
player.current_position()

To use system-provided fonts

⚠️ That function is so experimental. It should work for Android 7 and above but not been tested on much devices. It is actually for multilingual purposes to use system-provided fonts for no Latin languages. system_font() will always return the supported font from /system/fonts for the current device language. Also, you could use any language-supported font from the system just by calling the system_font function with the target language's iso639-1 or iso639-2 abbreviation such as font_name = system_font('zh') or system_font('zho').

from kivy.uix.label import Label
from kvdroid.tools.font import system_font

# that will return the default font for the device's current language.
Label(text = "example", font_name = system_font())

# for the specific language font
Label(text = "你好世界", font_name = system_font('zho')) # Language definition must be iso639-1 or iso639-2 abbreviation.  https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes

To cast Java Object

from kvdroid.cast import cast_object
from kvdroid.jclass.android import Uri

uri = Uri().fromFile("/home/java/my_document.pdf")
parcelable = cast_object("parcelable", uri)

# Above code  is same as below code::

from kvdroid.jclass.android import Uri
from jnius import cast

uri = Uri().fromFile("/home/java/my_document.pdf")
parcelable = cast("android.os.Parcelabel", uri)

'''
 the difference is, you dont have to remember the package name, just only the name and 
 you are good to go. This will also be helpful for python devs who do have zero knowledge on java
 
 Note:: 
 not all castable java object are included you can open an issue to include all missing 
 castables
'''

To access WebView cookies

(i.e if you compiled your app with webview bootstrap or have Webview in your app)

from kvdroid.tools.webkit import get_cookies

print(get_cookies("https://google.com"))

To access android package resource folders like:

  • drawable
  • layout
  • menu
  • values
  • mipmap
  • etc....
from kvdroid.tools import get_resource

drawable = get_resource("drawable")

To get Wi-Fi IP Address

from kvdroid.tools.network import get_wifi_ip_address
print(get_wifi_ip_address())

To send email

from kvdroid.tools.email import send_email
send_email(
    recipient=["[email protected]"], 
    subject="Hello there", 
    body="This is kvdroid"
)

To send an email with an attachment (androidx is required)

Also note before you can share files on Android version greater
than 10, you must specify a provider in the AndroidManifest.xml
inside the <application> tag e.g

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepath" />
</provider>

and also specify file path in the res/xml/filepath.xml of the android project folder e.g

<paths>
    <files-path name="document" path="app" />
</paths>

refer to android developer FileProvder Documentation to know more

from kvdroid.tools.email import send_email
from os import getenv
from os.path import join
send_email(
    recipient=["[email protected]"], 
    subject="Hello there", 
    body="This is kvdroid",
    file_path=join(getenv("PYTHONHOME"), "test.txt")
)

To read all SMS

from kvdroid.tools.sms import get_all_sms
from android.permissions import Permission, request_permissions  # NOQA
# remember to add READ_SMS to your buildozer `android.permissions`

request_permissions([Permission.READ_SMS])
print(get_all_sms()) # returns a tuple of message count and messages

To read all Call Log

from kvdroid.tools.call import get_call_log
from android.permissions import Permission, request_permissions  # NOQA
# remember to add READ_CALL_LOG to your buildozer `android.permissions`

request_permissions([Permission.READ_CALL_LOG])
print(get_call_log()) # returns a tuple of call log count and call_log

Since the release of Android 11 (API 30), the way file are stored became different

License

MIT

kvdroid's People

Contributors

aqulline avatar deepsourcebot avatar kengoon avatar lacxa avatar sahil-pixel avatar victorvickie avatar yunus-ceyhan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

kvdroid's Issues

TTS on androd 11 not workng

just tried below code from kvdroid docs , it is not working , there is no error , but no sound too . maybe because of android version 11 .

from kvdroid.tools import speech
speech("hello world", "en")

how to solve this issue ..?

and

i came across below comments on android 11 ,
where can i find that " manifest file " and where actually should i add those lines of codes

"
You may also need to add this code to your manifest file for the TTS to work if you are targeting Android 11:

"

get_call_log on other devices than Samsung

Hi.
I've got Samsung A70 and kvdroid get_call_log() is printing entire call register very fine.
But on other phones (not Samsung) e.g. Motorola e22 get_call_log() is printing nothing.
Samsung A70 is running on Android 11 (API 30); Motorola e22 = Android 12 (API 31).
For both Androids READ_CALL_LOG permission is granted.

You wrote in short manual: Since the release of Android 11 (API 30), the way file are stored became different.
What does that mean?
Any tips?

I've checked whole case on my friend's Samsung A53 (Android 13, API 33) and everything is fine - same as on Samsung A70 mentioned above.

Thanks in advance and take a look at this issue.
Best regards.

Scaling Kvdroid to A standalone Framework

@yunus-ceyhan

You must have seen a whole lot of changes on my fork of your project, I want to scale it into something bigger. I renamed the fork due to your long absence from merging my previous PR(I saw your revert on my PR which shows you noticed). My Initial plan was not to pull away from Kvdroid, but due to your absence which made me think you might likely be abandoning Kvdroid, I decided to rename it on my own fork.

I want the Kvdroid Community to take the Kvdroid project to a framework level. I have noticed a few things while developing android software with Kivy, P4A and Buildozer; most of the time I tend to use more of Android Native code functionality more than Kivy's and also to enhance speed in some certain areas I use Android Native Widgets(Java) instead of Kivy widgets. This has made me to think of the possibility of scaling Kvdroid into a standalone framework which you can use in any Android project that is being compiled with P4A or Buildozer as just a package that will handle some Native code calls OR as As a direct GUI Application runner just like kivy, flutter, react native, etc... In the sense that it will be responsible for the UI of your Android Project. How is that possible you might ask? Just like every other event based application, we will make use of a while loop to retain the UI until an exit event occurs...... would discuss in details openly later(i.e if you bu the idea)

The major changes that I made in the past months you were not around

  • Created a jclass and jimplement packages. The jclass package will be responsible of reimplementing the Android API(Java precisely) into python and the separation of Android API classes (i.e Java Classes) into separate folder inside of the jclass package is the best practice for now due to the fact that when autoclassing a Java class in pyjnius it wastes some time thereby causing freezing on low end devices(sometimes on higher devices if there are many autoclass to be done). The jimplement package is responsible for direct access to an already implemented Android Java functionality in Python(like notification and reading of contact)

PS: I would be waiting for your consent Also look into my fork to know more

error in Readme about dark_mode

In Readme:

To check if device is in dark mode or not
from kvdroid.tools.darkmode import dark_mode
print(dark_mode)

It's an error in the last line. dark_mode is a function that returns True or False. Hence, it should be:

print(dark_mode())

it is high time we start adding Inline code documentation

This project is getting bigger, and I think it already high time we start adding inline code documentations inside of the project, it will really help, when someone wants to contribute to the project

PS: This Issue should not be closed and no PR should be merged until all existing code has an inline documentation. Future PR's should contain inline documentation, we can borrow formats of inline documentation from kivy and kivymd source code

How to add buffer on player.stream ?

Im trying to make online music that stream music format .mp3 from url. but player.stream() doesnt play music if the music not fully downloaded its mean on low speed connection the music would not played

how to add buffer so user can stream music even on low speed connection?

save_drawable() not working properly

i was saving drawable image to device's folder
some image save but for some app stopped working showing no python error .
i have get some error by
adb logcat *:E | grep 'packagename'

Unknown bits set in runtime_flags: 0x40000000
05-19 22:45:01.478 9112 9112 E .hiddensettings: Invalid ID 0x00000000.
05-19 22:45:01.513 9112 9112 E .hiddensettings: ofbOpen failed with error=No such file or directory
05-19 22:45:01.513 9112 9112 E .hiddensettings: sysOpen failed with error=No such file or directory
05-19 22:45:01.513 9112 9112 E .hiddensettings: sharedImFd failed with error=Permission denied
05-19 22:45:04.527 9112 9169 F .hiddensettings: java_vm_ext.cc:591] JNI DETECTED ERROR IN APPLICATION: can't call int android.graphics.drawable.BitmapDrawable.getIntrinsicHeight() on instance of android.graphics.drawable.VectorDrawable
[22:47]
please see some error is this from permission . but i have give all permission
[22:48]
] JNI DETECTED ERROR IN APPLICATION: can't call int android.graphics.drawable.BitmapDrawable.getIntrinsicHeight() on instance of android.graphics.drawable.VectorDrawable

if platform=='android':
            packages=all_packages()
            j=0
            path_app=package_info('org.test.myapp')["dataDir"]
            print("*",path_app)

            for i in packages:
                print(i)
                _p=package_info(i)

                lpakages.append(i)
                lbl=_p['loadLabel']
                dp=p["loadIcon"]
                dp_path=save_drawable(dp, path_app+'/', str(j))
                #print("---",)
                ldpes.append(dp_path)
                lnames.append(lbl)
                lnoactivities.append('{} Activities'.format(len(_p['activities'])))
                j+=1

Testing done in Android 13

notification import error

Hello, when I run buildozer -v android deploy run logcat command this error occurs: ImportError: cannot import name 'create_notification' from 'kvdroid.tools.notification'.

Persistant notifications

Hi , I am working on uploads and downloads operations in my app . I have researched and found out that persistant notifications are only way to keep app services active even if app is closed for continued uploading and downloading . Can we open up a persistant notification ?

Check data connection always return False

im using

from kvdroid.tools.network import network_status, wifi_status, mobile_status

print(network_status())  # for both wifi and mobile
print(wifi_status())    # only for wifi
print(mobile_status())    # only for mobile

but always return False any idea how to fix this?

Screenshot_7

Create a separate python File for each function and class

Creating a separate python file for each function and class will make the kivy app not to freeze due to too many pyjnius thread on_ui_thread processes and also it helps to avoid putting unnecessary permission not required by an app.

My kivy app crashes due to the network_state function. I understand pyjnius and that is how I figured out, that I need to request for ACCESS_NETWORK_STATE but for kivy noobs who don't understand will get frustrated. Please do consider this, or can I create a pull request because I'm already working on it

App crahs at launch

@kengoon

The issue is related to the previous merge I think which at that time I wasn't available to test in detail.

10-19 19:13:32.690  3896  3936 I python  :    File "/home/yunus/Kivy/new/.buildozer/android/platform/build-arm64-v8a/build/python-installs/sets/arm64-v8a/kvdroid/tools/graphics.py", line 8, in <module>
10-19 19:13:32.690  3896  3936 I python  :    File "/home/yunus/Kivy/new/.buildozer/android/platform/build-arm64-v8a/build/python-installs/sets/arm64-v8a/kvdroid/tools/notification.py", line 9, in <module>
10-19 19:13:32.692  3896  3936 I python  :  ImportError: cannot import name 'bitmap_to_drawable' from partially initialized module 'kvdroid.tools.graphics' (most likely due to a circular import) (/data/user/0/com.ceyhan.sets/files/app/_python_bundle/site-packages/kvdroid/tools/graphics.pyc)

Imports are not working

from kvdroid.tools import navbar_color

Traceback (most recent call last):
   File "/data/user/0/ru.iiec.pydroid3/files/temp_iiec_codefile.py", line 2, in <module>
     from kvdroid.tools import navbar_color
   File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/site-packages/kvdroid/tools/__init__.py", line 3, in <module>
     from kvdroid.jclass.android import Intent, Context
   File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/site-packages/kvdroid/jclass/android/__init__.py", line 5, in <module>
     from .app import *
   File "/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/site-packages/kvdroid/jclass/android/app.py", line 3, in <module>
     from kvdroid.jclass.android import VERSION
 ImportError: cannot import name 'VERSION' from partially initialized module 'kvdroid.jclass.android' (most likely due to a circular import) (/data/user/0/ru.iiec.pydroid3/files/aarch64-linux-android/lib/python3.9/site-packages/kvdroid/jclass/android/__init__.py)

@kengoon have you tested it before pull requests?

can't have get_ressource("drawable") working, JVM exception occurred: Didn't find class `app.hamta.hypload.R$drawable`

in my buildozer.spec file i added this line :
android.add_resources = assets/hypload_icon_foreground.png:drawable/hypload_icon_foreground.png
to add an image to my drawable content

and in my main.py i'm using :

    try:
        create_notification(
            small_icon=get_ressource("drawable").hypload_icon_foreground,
            channel_id="ch1",
            title="HypLoad",
            text=f"{'Download' if options_json['language'] == 'en' else 'Télécharge'} {content}",
            ids=1,
            channel_name=f"lil_notif",
            priority=NotificationCompat().PRIORITY_LOW
        )

but i can't stop getting this error :

 JVM exception occurred: Didn't find class "app.hamta.hypload.R$drawable" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64, /system/lib64, /system_ext/lib64]] java.lang.ClassNotFoundException

Any one has an idea ?? i find the doc on this point not really accurate

launch_app_activity and launch_app doesnt work from a serviceforeground on Android 13

13
14
15

from kvdroid.tools import launch_app
from kvdroid.tools.package import all_main_activities
from kvdroid.tools.package import package_info
from kvdroid.tools import launch_app_activity
while True:
    time.sleep(30)

    s = all_main_activities()
    print('this is my the activity in the background____:',s[-1])

    print('______________________________________lunch activity method')
    launch_app_activity('org.syncinterpck.syncinter', 'org.kivy.android.PythonActivity')   
    print('_______________________________________lunch app method')
    launch_app("org.syncinterpck.syncinter")
    print('app started')



    # this the debug of of the service foreground

    # adb logcat -s Lunaser3       
    # 01-05 21:29:27.479 11165 11187 I Lunaser3: this is my the activity in the background____: {'org.syncinterpck.syncinter': 'org.kivy.android.PythonActivity'}
    # 01-05 21:29:27.479 11165 11187 I Lunaser3: ______________________________________lunch activity method
    # 01-05 21:29:27.493 11165 11187 I Lunaser3: _______________________________________lunch app method
    # 01-05 21:29:27.501 11165 11187 I Lunaser3: app started

after i start the app manually and sent it back with the home screen it doesnt start from the service

12

Notification arguments

Hello. I tried using the example of the create_notification() and changed big_picture and large_icon to my png icons but your example still doesn't work on android and actually crashed app when starting, also when its added to the the background service.
Do I need some special formatting when adding path to the file?

There is no explanation how it really works and it would be really great to add some commenting or documentation for this feature.
Are the arguments in your example mandatory and if so are those put in your example enough to test the notification feature? If not please give a proper explanation.

Until now I used plyer module for notifying but it's not perfect and has bugs when trying to use different icons.

Thank you for your hard work on the project! Best Regards!

Listener for network

It will useful if we can add a listener for network
if the state changes it will trigger the func that we passed in

Faster Kvdroid

          @kengoon btw i have an idea but don't know if it's ridiculous.

We have a big performance issue when we intend to do some tasks with pyjnius. For instance, I needed to get all the installed apps activities for one of my apps. When I do that task with pyjnius it nearly takes 10 seconds to complete, but when I execute the same task with pure java it only takes 1 or 2 seconds. So I had to do that task for my app by calling that java function in PythonActivity.java at startup.

So my question is what if we find another way to communicate with Java to do those tasks kvdroid provides?
How to create that channel?

I tried it with OSC protocol just like how we do it to communicate with service.py and actually, it worked but I'm not sure if it's a good approach.

It could be a separate project as well.

what do you think?

Originally posted by @yunus-ceyhan in #47 (comment)

Cannot import kvdroid

Hello, I have been trying to import kvdroid into my app but this is the error I get:
ImportError: cannot import name 'activity' from 'kvdroid' (C:\Users\siuba\AppData\Local\Programs\Python\Python37\lib\site-packages\kvdroid\__init__.py)

It makes sense, because there is no activity.py inside the module folder!

Priority not working on Android version 8 and above

Hey !
I resolved the previous issues i had,
Now i get it working in some ways, but i need help for a few details :

  1. Here is my code in python :
@mainthread 
def send_notification(content):
    print("notification about to be sent")
    create_notification(
        small_icon=get_resource("drawable").ic_launcher,
        channel_id="ch1",  # you must set this to any string value of your choice
        title="HypLoad",  # title of your notification
        text=f"{content}",  # notification content text
        ids=1,  # notification id, can be used to update certain notification
        channel_name=f"message",
        action_title1="action1",
        priority=NotificationCompat().PRIORITY_MIN
    )
    print("notification sent")

I use the decorator @mainthread to get it working, because notifications have to be sent with the main thread, otherwise i get all the problems i was talking about before (can't use create_notification because the function can't access some androidx and android values)
Whereas, i want the notification to be sent when the app is left but still opened
But if i launch them with the main thread, they only appear when i go back to the app, because the main thread is stopped when the app is left.
So do you have any ideas on how i could proceed to have notifications sent when the app is active but not opened ?

  1. When i use get_resource("drawable").ic_launcher (ic_launcher.png being my resource added as a drawable), the icon appears but is totally grey, instead of having its colors of origin.

  2. NotificationCompat().PRIORITY_MIN works just as NotificationCompat().PRIORITY_LOW that works just as if no priority was set. How can i get it working (i don't want it to show up on the screen, but just to appear in the status bar)

IMPORTANT FACT : with android.api = 34, for me, create_notification was not creating any error but didn't do anything. Now that i have android.api = 32, notifications are sent but i still have issues mentionned above

Thanks for your time

Not An Issue, Just Trying to get in touch with you

@yunus-ceyhan please contact me via email [email protected] would like to discuss some relevant stuff with you.

Headline

You must have seen a whole lot of changes on my fork of your project, I want to scale it into something bigger. I renamed the fork due to your long absence from merging my previous PR(I saw your revert on my PR which shows you noticed). My Initial plan was not to pull away from Kvdroid, but due to your absence which made me think you might likely be abandoning Kvdroid, I decided to rename it on my own fork.

PS: I would be waiting for your message

[Import Error]:SystemError: NULL result without error in PyObject_Call

I got this error

Traceback (most recent call last):
  File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 31, in <module>
    start(fakepyfile,mainpyfile)
  File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 30, in start
    exec(open(mainpyfile).read(),  __main__.__dict__)
  File "<string>", line 1, in <module>
  File "/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.9/site-packages/kvdroid/__init__.py", line 5, in <module>
    from jnius import autoclass
  File "/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.9/site-packages/jnius/__init__.py", line 42, in <module>
    from .reflect import *  # noqa
  File "/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.9/site-packages/jnius/reflect.py", line 20, in <module>
    class Class(with_metaclass(MetaJavaClass, JavaClass)):
  File "/data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/lib/python3.9/site-packages/six.py", line 872, in __new__
    return meta(name, resolved_bases, d)
  File "jnius/jnius_export_class.pxi", line 119, in jnius.jnius.MetaJavaClass.__new__
SystemError: NULL result without error in PyObject_Call

[Program finished]

status bar not hiding

immersive_mode(immerse=True) not hiding status bar in android 8
this is my VideoPy app in playstore i am updating .
see the image top portion status bar blocking kivy ui
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.