Support Native Media Gallery Indexing / scanFile API on Android (Serious Python)
還沒有人認領這個 Issue。
評估
研究方向
先追蹤 Flutter 用戶端的 Dart 端 handler 與提議的 MethodChannel 進入點,接著檢查 Serious Python 如何向 Python 公開服務。當跨平台媒體掃描 API 被公開,且 Android 檔案無需 PyJNIus 變通方案即可對原生 MediaStore 可見時,即表示完成。
由索引模型根據 Issue 內容生成。
描述
Context
When building multi-platform Python applications with Flet and compiling them for Android using Serious Python, apps often need to download or save media files (videos, photos, audio) to public user directories (such as the standard Download/ folder).
The Problem
When a file is downloaded or created directly on the filesystem under public storage (e.g., /storage/emulated/0/Download/), other Android apps (like WhatsApp, Instagram, TikTok) and the native system Gallery do not show the new file automatically.
The files are technically present on disk, but they remain invisible to other apps until the user manually opens the Android system File Manager. Opening the File Manager forces a system-level ContentObserver folder scan, which finally registers the files in the Android MediaStore database.
What We Tried (And the JNI / PyJNIus Traps)
We attempted to solve this within Python code using PyJNIus (jnius) to manually trigger the Android MediaScannerConnection.scanFile() API. However, doing this from Python runs into several major JNI and Serious Python structural blocks:
1. PyJNIus Background Thread Attachment Trap
Flet events and background tasks run on Python background worker threads (like asyncio or threading loops). PyJNIus calling Java methods from a background thread fails silently or crashes unless jnius.attach_thread() is explicitly called beforehand.
import jnius
jnius.attach_thread() # Required, but undocumented and highly prone to runtime errors
2. Changing Host Activity Class Names
To initialize MediaScannerConnection, we need the application Context. In Serious Python, finding the host activity via class lookups is brittle because class names vary between Serious Python versions:
- Older:
com.flet.serious_python_android.PythonActivity - Newer:
com.flet.serious_python.PythonActivity - Fallback lookups like
android.app.ActivityThread.currentApplication()frequently returnnullwhen called from Python worker threads.
3. JNI Signature Matching Failures
PyJNIus has trouble converting Python list structures to Java String[] array signatures expected by scanFile(Context, String[], String[], OnScanCompletedListener). Developers have to construct Java arrays manually via JNI reflection:
Array = autoclass('java.lang.reflect.Array')
String = autoclass('java.lang.String')
paths_arr = Array.newInstance(String, len(file_paths)) # Brittle reflection setup
4. Android 9+ Implicit Intent Blocks
Fallback intent broadcasts like android.intent.action.MEDIA_SCANNER_SCAN_FILE are ignored on Android 9+ unless explicitly targeted to the Media Provider package (-p com.android.providers.media), making shell-based workarounds highly complex and security-restricted.
Proposed Solution (Feature Request)
To make Flet a truly first-class framework for mobile development, Flet should expose a native, cross-platform media indexing API (for example, page.scan_media(path) or a new page.storage_paths.scan_file(path) service method).
How it should work under the hood:
- The Flet Flutter client should handle the media scanner connection natively on the Dart side.
- In Dart, triggering a media scan on Android is extremely simple and does not suffer from classloader or background-thread JNI issues:
// Dart side handler import 'package:flutter/services.dart'; // Native MethodChannel triggers MediaScannerConnection.scanFile on the Android Activity thread - By delegating this to the Flutter shell, Python developers wouldn't need to write brittle PyJNIus wrappers, deal with JNI JVM thread-attachments, or worry about changing package class names between Serious Python releases.
This feature is essential for any Flet application that downloads user-facing files (photos, videos, PDF documents, audio) to public directories on Android.
- 主要語言
- Dart
- 星號
- 325
- 分支
- 46
- 平均合併
- 19 小時 50 分鐘
- 30 天內合併 PR
- 4
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 沒有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
flet-dev/serious-python 的其他 Issue
-
難度 5/5 一週以上 新手友好度 38/100
flet-dev/serious-python#255 ·
-
難度 2/5 1-3 小時 新手友好度 55/100
flet-dev/serious-python#254 ·
-
難度 4/5 3-5 天 新手友好度 35/100
flet-dev/serious-python#169 ·
-
iOS Build Failure: Missing site-xcframeworks Directory in serious_python_darwin PhaseScriptExecution未關閉
難度 3/5 1-2 天 新手友好度 42/100
flet-dev/serious-python#168 ·
-
Update docs for site-packages可能重新可做 @FeodorFitsner 於 573 天前認領,目前沒有進行中的 PR。 未關閉documentation
flet-dev/serious-python#157 · 1 則留言 · 已指派 1 人 ·
查看 flet-dev/serious-python 的全部 Issue
相似的 Issue
-
bug documentation
難度 2/5 1-3 小時 新手友好度 70/100
fdittgen-png/deskilo#2605 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 85/100
維護者通常 1 天內回覆
-
[Bug]: The daily reminder keeps its old language after the app language changes可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉backlog:low bug localization
難度 2/5 1-3 小時 新手友好度 72/100
simonoppowa/OpenNutriTracker#1366 ·
維護者通常 1 天內回覆
-
Mobile reading view shows a sender without display name as "<[email protected]>" with angle brackets未關閉ai-driven-qa bug Cosmetic
難度 2/5 1-3 小時 新手友好度 72/100
linagora/tmail-flutter#4999 ·
維護者通常 1 天內回覆
-
waiting for response
難度 2/5 1 小時以內 新手友好度 72/100
flutter/flutter#194381 · 1 則留言 ·
維護者通常 1 天內回覆