OSS Contributions / 7 menit baca
Making Amaze Discoverable as a File Manager on Android TV
This article covers the analysis and fix for Amaze File Manager issue #4079, where Amaze was installed on Android TV but other applications still reported that no file manager was available.
Status at the time of writing: the implementation and local verification are complete and ready for a pull request. The change is not part of an official release until it has been reviewed and merged by the maintainers.
Summary
The problem occurred because Amaze only advertised ACTION_GET_CONTENT as a file-selection contract. Some Android TV applications and firmware use ACTION_OPEN_DOCUMENT when looking for a file picker. Android therefore did not include Amaze among the matching handlers even though the application was installed.
The fix has three parts:
- Advertise
ACTION_OPEN_DOCUMENTonMainActivity. - Route that action through Amaze's existing file-selection flow.
- Add regression tests for manifest resolution and file-picking mode.
Tests on two physical devices showed Amaze alongside Material Files in the Android resolver. After selecting ALWAYS, a subsequent OPEN_DOCUMENT request launched Amaze directly without showing the resolver again.
The Android TV Problem
The issue reporter used Android TV devices, including devices such as Chromecast, that do not always ship with a file manager. Amaze could be installed and launched normally, but other applications continued to claim that no file manager was installed.
Material Files was discovered on the same device. This difference suggested that the problem was not TV launcher support, but the intent contracts advertised by each application.
Android does not provide a universal system role named “default file manager.” In the context of this issue, the term means that:
- Amaze is discovered as a document-selection handler;
- Amaze appears in the Android resolver;
- the user can select
ALWAYSso matching intents are routed directly to Amaze; - the selected file is returned to the calling application.
Root Cause Investigation
Before the fix, MainActivity already supported several relevant intents:
MAIN,LAUNCHER, andLEANBACK_LAUNCHERfor normal startup;ACTION_GET_CONTENTfor file selection;VIEWfor opening supported files;SENDandSEND_MULTIPLEfor sharing files.
However, the manifest did not advertise ACTION_OPEN_DOCUMENT. The MainActivity implementation also enabled result-returning mode only when it received ACTION_GET_CONTENT.
Adding an intent filter alone would not be sufficient. If Amaze appeared in the resolver without entering file-picker mode, selecting a file could open it normally instead of returning it to the caller.
The root cause therefore had two parts:
- Discovery: Android could not find Amaze for
ACTION_OPEN_DOCUMENT. - Behavior:
MainActivitydid not recognizeACTION_OPEN_DOCUMENTas a request to select and return a file.
Implementing the Fix
1. Advertising ACTION_OPEN_DOCUMENT
The following filter was added to MainActivity:
<intent-filter>
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<data android:mimeType="*/*" />
<category android:name="android.intent.category.OPENABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>The / MIME type allows the filter to match callers requesting any file type. Android can also match it when a caller requests a more specific type such as image/*.
2. Using one helper for file-picker intents
Action recognition was centralized in a small helper:
private static boolean isFilePickerIntent(@Nullable String actionIntent) {
return Intent.ACTION_GET_CONTENT.equals(actionIntent)
|| Intent.ACTION_OPEN_DOCUMENT.equals(actionIntent);
}The helper is used by both permission handling and checkForExternalIntent(). As a result, GET_CONTENT and OPEN_DOCUMENT share the same behavior without duplicating conditions.
Using the existing Intent.ACTION_* constants also avoids introducing hardcoded action strings. This change adds no new user-facing text.
3. Reusing the existing URI result flow
Amaze already had a mechanism to:
- enable
mReturnIntent; - select one or more files;
- create URIs for selected files;
- grant read permission;
- return the result and finish the Activity.
The fix reuses this mechanism instead of creating a second file picker. This keeps the change small and preserves the existing GET_CONTENT behavior.
Why Not Add OPEN_DOCUMENT_TREE?
ACTION_OPEN_DOCUMENT_TREE selects a directory tree rather than a file. It has a different result contract and normally requires a tree URI and persistable permissions.
ACTION_CREATE_DOCUMENT and a full DocumentsProvider implementation are also separate features with a much larger scope.
Issue #4079 can be reproduced through ACTION_OPEN_DOCUMENT. Advertising additional contracts without fully implementing them could make Amaze appear for workflows it cannot correctly complete.
Regression Tests
The new tests verify two essential behaviors:
- Package manager resolution finds
MainActivityforACTION_OPEN_DOCUMENT, theOPENABLEcategory, and the/MIME type. - Launching the Activity with
ACTION_OPEN_DOCUMENTenablesmReturnIntentwithout enabling ringtone-picker mode.
Related result tests also verify that:
- selecting one file returns one URI;
- selecting multiple files returns a collection of URIs;
- null results or files that cannot be converted do not crash the application.
The local verification commands were:
./gradlew :app:testFdroidDebugUnitTest \
--tests com.amaze.filemanager.ui.activities.MainActivityTest \
--tests com.amaze.filemanager.ui.fragments.MainFragmentReturnIntentResultsTest./gradlew spotlessCheck
./gradlew assembledebug assembleFdroidDebug
```
The targeted tests, formatting check, and both builds completed successfully.
Physical Device Verification
The fix was tested on two devices running different Android versions:
| Device | System | API | Result |
|---|---|---|---|
| Polytron PLD 43S883MBN | Android TV 7.1.2 | 25 | Passed |
| Amlogic Media Player Android Box | Android 9 | 28 | Passed |
Testing used the F-Droid debug variant:
adb install -r app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apkInspecting resolver registration
The installed manifest was inspected with:
adb shell dumpsys package com.amaze.filemanager.debug \
| sed -n '/Activity Resolver Table:/,/Receiver Resolver Table:/p' \
| rg -C 6 'OPEN_DOCUMENT|GET_CONTENT'The picker was then launched with:
adb shell "am start -W \
-a android.intent.action.OPEN_DOCUMENT \
-c android.intent.category.OPENABLE \
-t '*/*'"The complete remote command is passed as one string so that the device shell does not expand the / wildcard.
On the API 28 Android Box, the resolver displayed Amaze Debug alongside Material Files. This is direct evidence that Amaze was discovered for the previously unsupported contract.
Verifying the default handler
Amaze was selected in the resolver and the ALWAYS button was used. The next request produced:
Activity: com.amaze.filemanager.debug/com.amaze.filemanager.ui.activities.MainActivityResolverActivity was no longer shown. Amaze had become the default handler for that action, category, and MIME-type combination.
Successful Test Scenarios
Manual verification covered:
- a cold
OPEN_DOCUMENTrequest with/; OPEN_DOCUMENTwith specific MIME types such asimage/*and PDF;- the existing
GET_CONTENTflow; - single-file selection;
- selecting two files with
EXTRA_ALLOW_MULTIPLE; - delivering an intent to an existing
MainActivityinstance; - D-pad navigation;
- cancellation with the Back button;
- selecting a file after Amaze became the default handler;
- logcat inspection for crashes and ANRs.
An APK was selected as a document on the Android Box. Amaze finished and returned to the launcher without opening the package installer. This matters because file-picker mode must return a file as a result rather than execute it.
The tests found no:
FATAL EXCEPTION;- ANR;
SecurityException;- unintended image viewer, media player, or package installer launch.
An ADB shell command is not an Activity caller that can directly inspect the returned result URI. The shape of single- and multiple-selection results is therefore also covered by Robolectric tests. Testing with the reporter's original calling application remains a useful additional check when that application is available.
Impact and Regression Risk
The implementation changes only:
app/src/main/AndroidManifest.xml
app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java
app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.ktThere are no UI, database, data-model, filesystem-operation, or launcher-navigation changes. GET_CONTENT, normal launcher startup, and LEANBACK_LAUNCHER retain their existing behavior.
The primary risk is advertising an action that the application cannot actually complete. The fix addresses this by routing OPEN_DOCUMENT through the URI-returning flow and adding tests that confirm file-picker mode is active.
Conclusion
Issue #4079 was not caused by Amaze being unable to run on Android TV. It was caused by an incomplete set of advertised file-picker intent contracts. By adding ACTION_OPEN_DOCUMENT and routing it through the existing result flow, Amaze can be discovered, selected, and configured as the default matching handler on the tested Android TV and Android Box devices.
The implementation is small, covered by regression tests, passes builds and formatting checks, and has been verified on two physical devices. The remaining contribution steps are opening the pull request, waiting for repository CI, and addressing maintainer review.