Android Intent Filter: Associate App With File Extension

Android intent filter: associate app with file extension

You need multiple intent filters to address different situation you want to handle.

Example 1, handle http requests without mimetypes:

  <intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:host="*" />
<data android:pathPattern=".*\\.pdf" />
</intent-filter>

Handle with mimetypes, where the suffix is irrelevant:

  <intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:host="*" />
<data android:mimeType="application/pdf" />
</intent-filter>

Handle intent from a file browser app:

  <intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:host="*" />
<data android:pathPattern=".*\\.pdf" />
</intent-filter>

Intent Filter of File Extension for specific activity

There is no direct solution to this issue by using Intent Filters per Activity, So I have created FileIntentActivity which accepts following Intent Filter

<intent-filter
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />

<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>

This FileIntentActivity is used to accept any file format and then decides further action based on file extension converted from Content URI using Cursors referred from this answer

fun getFileName(uri: Uri): String {
lateinit var cursor: Cursor
lateinit var result: String
try {
cursor = appContext.contentResolver.query(uri, null, null, null, null)
if(cursor!=null && cursor.moveToFirst()){
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
}
return result
} finally {
cursor.close()
}
}

private fun getFileType(fileName: String): FileType {
return when (fileExtension) {
FileFormats.ABC_FILE_FORMAT -> FileType.ABC
FileFormats.XYZ_FILE_FORMAT -> FileType.XYZ
else -> FileType.UNKNOWN
}
}

And open the Activity1 or Activity2 based on FileType

private fun openActivityByType(fileType: FileType) {
when (fileType) {
FileType.ABC -> startActivity1()
FileType.XYZ -> startActivity2()
FileType.UNKNOWN -> showFileUnsupportedMessage()
}
}

This approach at least makes User Interaction less confusing by showing only 1 File Intent Activity instead of Multiple Activities of Single app in Android's Intent Chooser.

Issue with intent filter for opening a file in Android app

Remove:

<data android:host="*" />

from both <intent-filter> entries and:

<data android:pathPattern=".*\\.conf" />

from the content one.

File extensions are not used much on Android. Starting with Android Q, files are not used much on Android. There is no requirement for a ContentProvider to put a file-like extension on a content Uri, as you can see from the Uri in your screenshot.

If you wish to support common Intent actions like ACTION_VIEW, your best bet is to save the file in a common meta-format (e.g., JSON, XML) with a file extension that matches, then have your <intent-filter> filter on the corresponding MIME type. You will need to deal with the possibility that the user chooses a file that was not created by your app, though technically you need to deal with that even with your custom extension.



Related Topics



Leave a reply



Submit