Skip to content

Snappy1

  • Home
  • Android
  • What
  • How
  • Is
  • Can
  • Does
  • Do
  • Why
  • Are
  • Who
  • Toggle search form

[FIXED] python – Downloaded files not appearing in the Downloads application in android kivy

Posted on November 11, 2022 By

Solution 1 :

FYI on Android >= 11 copying to the Downloads folder has no utility.
Other apps can’t read a file in Downloads even if they have READ_EXTERNAL_STORAGE. The traditional use of Downloads as a pool of shared files no longer works. Since only your app can read the file there is no point in putting it there. The idea is Downloads is only a cache for files your app downloaded.

Problem :

I am trying to inform the download application that files have appeared in the Downloads folder, but after copying the file to this folder and using the code below, the file does not appear. For android version below 10 I get an error: jnius.jnius.JavaException: No methods matching your arguments, requested: (<java.lang.String at 0x796d9637c0 jclass=java/lang/String jself=<LocalRef obj=0x6516 at 0x796d9c6e10>>, <java.lang.String at 0x796d9637c0 jclass=java/lang/String jself=<LocalRef obj=0x6516 at 0x796d9c6e10>>, True, <java.lang.String at 0x796d963950 jclass=java/lang/String jself=<LocalRef obj=0x6502 at 0x796d957870>>, '/storage/emulated/0/Download/surface.stl', <java.lang.Integer at 0x796d963270 jclass=java/lang/Integer jself=<LocalRef obj=0x6522 at 0x796d957850>>, True), available: ['(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;JZ)J', '(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;JZLandroid/net/Uri;Landroid/net/Uri;)J']. I would some thing like MediaScannerConnection.scanFile.

from kivy.app import App
from kivy import platform
from plyer import storagepath
import mimetypes
import shutil
import os

if platform == "android":
    from jnius import autoclass, cast
    from android.permissions import request_permissions, Permission

    PythonActivity = autoclass('org.kivy.android.PythonActivity')
    activity = PythonActivity.mActivity
    Intent = autoclass('android.content.Intent')
    currentActivity = cast('android.app.Activity', activity)
    Build = autoclass('android.os.Build')
    ContentValues = autoclass('android.content.ContentValues')
    MediaStore = autoclass('android.provider.MediaStore')
    context = cast('android.content.Context', currentActivity.getApplicationContext())
    Downloads = autoclass('android.provider.MediaStore$Downloads')
    Environment = autoclass('android.os.Environment')
    Integer = autoclass('java.lang.Integer')
    String = autoclass('java.lang.String')
    File = autoclass('java.io.File')
    DownloadManager = autoclass('android.app.DownloadManager')
    Context = autoclass("android.content.Context")
    VERSION = autoclass('android.os.Build$VERSION')
    VERSION_CODES = autoclass('android.os.Build$VERSION_CODES')


class TestApp(App):
    def on_start(self):
        if platform == 'android':
            request_permissions([Permission.WRITE_EXTERNAL_STORAGE])

        self.add_file_to_download('test.txt')

    def add_file_to_download(self, filename: str):
        download_dir = str(storagepath.get_downloads_dir())
        file_in_download = os.path.join(download_dir, filename)

        if not os.path.exists(file_in_download):
            shutil.copy(filename, file_in_download)
        else:
            print(f'File already in {download_dir}')

        file_size = os.path.getsize(file_in_download)
        mime_type = mimetypes.guess_type(file_in_download)[0]
        if not mime_type:
            mime_type = "text/plain"

        if platform == 'android':
            file_size = Integer(file_size)
            filename = String(filename)
            mime_type = String(mime_type)

            if VERSION.SDK_INT >= VERSION_CODES.Q:
                print('Use new solution')

                content_values = ContentValues()
                content_values.put(Downloads.TITLE, filename)
                content_values.put(Downloads.DISPLAY_NAME, filename)
                content_values.put(Downloads.MIME_TYPE, mime_type)
                content_values.put(Downloads.SIZE, file_size)

                # If  you downloaded to a specific folder inside "Downloads" folder
                # content_values.put(Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + File.separator + "Temp")

                database = context.getContentResolver()
                database.insert(Downloads.EXTERNAL_CONTENT_URI, content_values)

            else:
                print('Use old solution')

                downloader_manager = context.getSystemService(Context.DOWNLOAD_SERVICE)
                if downloader_manager:
                    downloader_manager.addCompletedDownload(filename, filename, True, mime_type, file_in_download,
                                                            file_size, True)

        print('File copied')


TestApp().run()

buildozer.spec

source.include_exts = py,png,jpg,kv,atlas,txt
android.permissions = WRITE_EXTERNAL_STORAGE,READ_EXTERNAL_STORAGE,DOWNLOAD_WITHOUT_NOTIFICATION
requirements = kivy,plyer,pyjnius,android
android.api = 32
android.ndk = 23b
p4a.branch = develop

I use this solution for java

READ  [FIXED] java - Can not insert the value for Android Studio
Powered by Inline Related Posts

EDIT:

Now old solution works fine for android 10 and below. On Android 10 new solution have no effect. And on Android S I get error: jnius.jnius.JavaException: JVM exception occurred: Invalid column null java.lang.IllegalArgumentException in this line resolver.insert(Downloads.EXTERNAL_CONTENT_URI, content_values)

from kivy.app import App
from kivy import platform
from plyer import storagepath
import mimetypes
import shutil
import os

if platform == "android":
    from jnius import autoclass, cast
    from android.permissions import request_permissions, Permission

    PythonActivity = autoclass('org.kivy.android.PythonActivity')
    activity = PythonActivity.mActivity
    Intent = autoclass('android.content.Intent')
    currentActivity = cast('android.app.Activity', activity)
    Build = autoclass('android.os.Build')
    ContentValues = autoclass('android.content.ContentValues')
    context = cast('android.content.Context', currentActivity.getApplicationContext())
    Downloads = autoclass('android.provider.MediaStore$Downloads')
    Environment = autoclass('android.os.Environment')
    Integer = autoclass('java.lang.Integer')
    String = autoclass('java.lang.String')
    File = autoclass('java.io.File')
    DownloadManager = autoclass('android.app.DownloadManager')
    Context = autoclass("android.content.Context")
    VERSION = autoclass('android.os.Build$VERSION')
    VERSION_CODES = autoclass('android.os.Build$VERSION_CODES')


class TestApp(App):
    def on_start(self):
        if platform == 'android':
            request_permissions([Permission.WRITE_EXTERNAL_STORAGE])

        self.add_file_to_download('test.txt')

    def add_file_to_download(self, path: str):
        """
        :param path: file near the main.py
        :return:
        """

        download_dir = str(storagepath.get_downloads_dir())
        filename, ext = os.path.splitext(path)
        full_file_name = filename + ext

        file_in_download = os.path.join(download_dir, full_file_name)

        if os.path.exists(file_in_download):
            os.remove(file_in_download)
            print(f'File already in {download_dir}')

        shutil.copy(full_file_name, file_in_download)

        file_size = os.path.getsize(file_in_download)
        mime_type = mimetypes.guess_type(file_in_download)[0]
        if not mime_type:
            mime_type = "text/plain"

        if platform == 'android':
            Integer_file_size = Integer(file_size)
            Integer_pending = Integer(1)

            if VERSION.SDK_INT >= VERSION_CODES.Q:
                print('Use new solution')
                
                content_values = ContentValues()

                content_values.put(Downloads.TITLE, full_file_name)
                content_values.put(Downloads.DISPLAY_NAME, full_file_name)
                content_values.put(Downloads.MIME_TYPE, mime_type)
                content_values.put(Downloads.SIZE, Integer_file_size)
                content_values.put(Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
                content_values.put(Downloads.IS_PENDING, Integer_pending)

                print(f'content_values {content_values}')

                # If  you downloaded to a specific folder inside "Downloads" folder
                # content_values.put(Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + File.separator + "Temp")

                database = context.getContentResolver()
                database.insert(Downloads.EXTERNAL_CONTENT_URI, content_values)
            else:
                print('Use old solution')

                downloader_manager = context.getSystemService(Context.DOWNLOAD_SERVICE)
                is_media_scanner_scannable = True
                notification = False

                if downloader_manager:
                    downloader_manager.addCompletedDownload(full_file_name,
                                                            full_file_name,
                                                            is_media_scanner_scannable,
                                                            mime_type,
                                                            file_in_download,
                                                            file_size,
                                                            notification,
                                                            )

        print('File copied')


TestApp().run()
Android Tags:android, kivy, pyjnius, python, python-for-android

Post navigation

Previous Post: [FIXED] android – W/Firestore: (24.1.2) [CustomClassMapper]: No setter/field for about found on class
Next Post: [FIXED] android – FusedLocationProviderClient and LocationCallback() object queries

Related Posts

[FIXED] Why split unit tests and instrumented tests folders in Android? Android
[FIXED] android – RecyclerView with Multiple View Type with continued position counting Android
[FIXED] Call an activity to make a photo calls onCreate() twice on Android 10 Android
[FIXED] android – ViewGroup.addview() is working but child view is not showing Android
[FIXED] Android: How to prevent lag or animation skip on Fragment transaction when inflating RecyclerView inside? Android
[FIXED] How to read an image stored in Android application’s folder in Internal Shared Storage using html? Android

Archives

  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022

Categories

  • ¿Cómo
  • ¿Cuál
  • ¿Cuándo
  • ¿Cuántas
  • ¿Cuánto
  • ¿Qué
  • Android
  • Are
  • At
  • C'est
  • Can
  • Comment
  • Did
  • Do
  • Does
  • Est-ce
  • Est-il
  • For
  • Has
  • Hat
  • How
  • In
  • Is
  • Ist
  • Kann
  • Où
  • Pourquoi
  • Quand
  • Quel
  • Quelle
  • Quelles
  • Quels
  • Qui
  • Should
  • Sind
  • Sollte
  • Uncategorized
  • Wann
  • Warum
  • Was
  • Welche
  • Welchen
  • Welcher
  • Welches
  • Were
  • What
  • What's
  • When
  • Where
  • Which
  • Who
  • Who's
  • Why
  • Wie
  • Will
  • Wird
  • Wo
  • Woher
  • you can create a selvedge edge: You can make the edges of garter stitch more smooth by slipping the first stitch of every row.2022-02-04
  • you really only need to know two patterns: garter stitch

Recent Posts

  • Which is stronger 19 gauge or 23 gauge?
  • Does BMW still use GM transmissions?
  • Is primary or secondary market research better?
  • What does it mean when ADT says low battery?
  • Can a baby sleep on a regular mattress?

Recent Comments

No comments to show.

Copyright © 2023 Snappy1.

Powered by PressBook Grid Dark theme