특정 파일 확장자에 대한 Android 인 텐트 필터?
나는 'net에서 특정 확장자를 가진 파일을 다운로드하고 그것을 처리하기 위해 내 응용 프로그램으로 전달하고 싶지만 의도 필터를 알아낼 수 없었습니다. 파일 유형은 MIME 유형에 포함되어 있지 않으며
<data android:path="*.ext" />
그러나 나는 그것을 작동시킬 수 없었다.
이 작업을 수행하기 위해 AndroidManifest.xml에서 내 활동을 정의하는 방법은 다음과 같습니다.
<activity android:name="com.keepassdroid.PasswordActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.kdb" />
<data android:host="*" />
</intent-filter>
</activity>
scheme
의는 file
로컬 파일 (오히려 HTTP와 같은 프로토콜보다) 열 때 이런 일이되어야 함을 나타냅니다.
mimeType
\*/\*
모든 MIME 유형과 일치 하도록 설정할 수 있습니다 .
pathPattern
일치시킬 확장자를 지정하는 위치입니다 (이 예에서 .kdb
). .*
시작 부분에 문자의 squence 일치합니다. 이러한 문자열에는 이중 이스케이프가 필요하므로 \\\\.
리터럴 마침표와 일치합니다. 그런 다음 파일 확장자로 끝납니다. pathPattern의 한 가지주의 사항 .*
은 이것이 정규 표현식 인 경우 예상 할 수있는 욕심 많은 일치가 아니라는 것입니다. 이 패턴은을 포함하는 경로와 일치 할 수 없게됩니다 .
전과를 .kdb
. 이 문제 및 해결 방법에 대한 자세한 설명은 여기를 참조 하십시오.
마지막으로 Android 문서에 따르면 속성이 작동 하려면 host
및 scheme
속성이 모두 필요 pathPattern
하므로 모든 항목과 일치하도록 와일드 카드로 설정하면됩니다.
이제 .kdb
Linda File Manager와 같은 앱에서 파일 을 선택하면 내 앱이 옵션으로 표시됩니다. 이것만으로는 브라우저에서이 파일 유형을 다운로드 할 수 없다는 점에 유의해야합니다. 이것은 파일 스키마에만 등록되기 때문입니다. 전화에 Linda File Manager와 같은 앱이 있으면 일반적으로 모든 파일 형식을 다운로드 할 수 있습니다.
이 주제에 대한 많은 잘못된 정보가 있으며, 특히 Google의 자체 문서가 있습니다. 이상한 논리를 감안할 때 가장 좋은 것은 소스 코드뿐입니다.
인 텐트 필터 구현 에는 설명을 거의 무시하는 논리가 있습니다. 파서 코드는 퍼즐의 다른 관련 작품이다.
다음 필터는 현명한 행동에 매우 가깝습니다. 경로 패턴은 "파일"체계 의도에 적용됩니다.
전역 MIME 유형 패턴 일치는 파일 확장자가 일치하는 한 모든 유형과 일치합니다. 이것은 완벽하지는 않지만 ES 파일 탐색기와 같은 파일 관리자의 동작을 일치시키는 유일한 방법이며 URI / 파일 확장자가 일치하는 의도로 제한됩니다.
여기에 "http"와 같은 다른 스키마를 포함하지 않았지만 이러한 모든 필터에서 제대로 작동 할 것입니다.
이상한 계획은 "내용"으로, 필터에서 확장을 사용할 수 없습니다. 그러나 공급자가 MIME 유형을 명시하는 한 (예 : Gmail은 방해받지 않고 첨부 파일에 대해 MIME 유형을 전달 함) 필터가 일치합니다.
주의해야 할 사항 :
- 필터에서 일관되게 작동하는 것은 없으며, 스펙 컬 케이스의 미로이며, 최소 놀라움 원칙 위반을 설계 목표로 취급합니다. 패턴 일치 알고리즘 중 어떤 것도 동일한 구문이나 동작을 따르지 않습니다. 필드의 부재는 때때로 와일드 카드이고 때로는 그렇지 않습니다. 데이터 요소 내의 속성은 때때로 함께 연결되어야하며 때로는 그룹화를 무시해야합니다. 정말 더 잘할 수있었습니다.
- 경로 규칙이 일치하려면 스키마와 호스트를 지정해야합니다 (현재 Google의 API 가이드와 반대).
- 적어도 ES 파일 탐색기는 MIME 유형이 ""인 인 텐트를 생성합니다. 이는 null로 매우 다르게 필터링되고 명시 적으로 일치하는 것이 불가능하며 위험한 "* / *"필터에 의해서만 일치 될 수 있습니다.
- "* / *"필터는 Null MIME 유형이있는 인 텐트와 일치하지 않습니다.이 경우 MIME 유형이 전혀없는이 특정 경우에 대해 별도의 필터가 필요합니다.
- 원래 파일 이름은 인 텐트에서 사용할 수 없기 때문에 (적어도 Gmail에서는) '콘텐츠'체계는 MIME 유형으로 만 일치시킬 수 있습니다.
- 별도의 "데이터"요소에있는 속성 그룹은 (거의) 해석과 무관합니다. 단, 호스트와 포트는 서로 쌍을 이룹니다. 다른 모든 것은 "데이터"요소 내에서 또는 "데이터"요소간에 특정 연관이 없습니다.
이 모든 것을 염두에두고 여기에 주석이있는 예가 있습니다.
<!--
Capture content by MIME type, which is how Gmail broadcasts
attachment open requests. pathPattern and file extensions
are ignored, so the MIME type *MUST* be explicit, otherwise
we will match absolutely every file opened.
-->
<intent-filter
android:icon="@drawable/icon"
android:label="@string/app_name"
android:priority="50" >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:mimeType="application/vnd.my-type" />
</intent-filter>
<!--
Capture file open requests (pathPattern is honoured) where no
MIME type is provided in the Intent. An Intent with a null
MIME type will never be matched by a filter with a set MIME
type, so we need a second intent-filter if we wish to also
match files with this extension and a non-null MIME type
(even if it is non-null but zero length).
-->
<intent-filter
android:icon="@drawable/icon"
android:label="@string/app_name"
android:priority="50" >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:host="*" />
<!--
Work around Android's ugly primitive PatternMatcher
implementation that can't cope with finding a . early in
the path unless it's explicitly matched.
-->
<data android:pathPattern=".*\\.my-ext" />
<data android:pathPattern=".*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
</intent-filter>
<!--
Capture file open requests (pathPattern is honoured) where a
(possibly blank) MIME type is provided in the Intent. This
filter may only be necessary for supporting ES File Explorer,
which has the probably buggy behaviour of using an Intent
with a MIME type that is set but zero-length. It's
impossible to match such a type except by using a global
wildcard.
-->
<intent-filter
android:icon="@drawable/icon"
android:label="@string/app_name"
android:priority="50" >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:host="*" />
<data android:mimeType="*/*" />
<!--
Work around Android's ugly primitive PatternMatcher
implementation that can't cope with finding a . early in
the path unless it's explicitly matched.
-->
<data android:pathPattern=".*\\.my-ext" />
<data android:pathPattern=".*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
</intent-filter>
Android의 파일 시스템에서 이메일과 파일의 첨부 파일을 여는 간단한 작업이 그 어느 때보 다 미친 경험 중 하나 였다는 것을 인정해야합니다. 너무 많은 파일을 처리하거나 너무 적은 파일을 처리하기 쉽습니다. 하지만 제대로하는 것은 어렵습니다. stackoverflow에 게시 된 대부분의 솔루션이 제대로 작동하지 않았습니다.
내 요구 사항은 다음과 같습니다.
- 내 앱이 내 앱에서 공유 한 첨부 파일을 처리하도록합니다.
- 내 앱이 내 앱에서 생성하고 특정 확장자를 가진 filestorage의 파일을 처리하도록합니다.
아마도이 작업을 수행하는 가장 좋은 방법은 첨부 파일에 대한 사용자 지정 MIME 유형을 지정하는 것입니다. 또한 사용자 정의 파일 확장자를 사용하도록 선택할 수도 있습니다. 따라서 우리의 앱이 "Cool App"이고 끝에 ".cool"가있는 첨부 파일을 생성한다고 가정 해 보겠습니다.
이것은 내가 내 목표에 가장 가깝고 작동합니다 ... 만족 스럽습니다.
<!-- Register to handle email attachments -->
<!-- WARNING: Do NOT use android:host="*" for these as they will not work properly -->
<intent-filter>
<!-- needed for properly formatted email messages -->
<data
android:scheme="content"
android:mimeType="application/vnd.coolapp"
android:pathPattern=".*\\.cool" />
<!-- needed for mangled email messages -->
<data
android:scheme="content"
android:mimeType="application/coolapp"
android:pathPattern=".*\\.cool" />
<!-- needed for mangled email messages -->
<data
android:scheme="content"
android:mimeType="application/octet-stream"
android:pathPattern=".*\\.cool" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
<!-- Register to handle file opening -->
<intent-filter>
<data android:scheme="file"
android:mimeType="*/*"
android:pathPattern=".*\\.cool"
android:host="*"/>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
노트:
pathPattern
첨부 파일에 대해 다소 무시 되는 것 같습니다 (사용시android:scheme="content"
). 누군가가 특정 패턴에만 응답하는 pathPattern을 얻는다면 나는 그 방법을보고 기뻐할 것입니다.android:host="*"
속성을 추가하면 Gmail 앱이 선택기에서 내 앱을 나열하는 것을 거부했습니다 .- 이
intent-filter
블록이 병합 되면 여전히 작동 하지만 이것을 확인하지 않았습니다. - 파일을 다운로드 할 때 브라우저의 요청을 처리하려면를
android:scheme="http"
사용할 수 있습니다. 특정 브라우저는android:mimeType
실험을 엉망android:mimeType="*/*"
으로 만들고 디버거에서 실제로 전달되는 내용을 확인한 다음 필터링을 강화하여 모든 것을 처리하는 성가신 앱이되지 않도록합니다 . - 특정 파일 탐색기는 파일의 MIME 유형도 엉망으로 만듭니다. 위의 내용
intent-filter
은 Galaxy S3에서 삼성의 "내 파일"앱으로 테스트되었습니다. FX Explorer는 여전히 파일을 제대로 열지 못하며 앱 아이콘이 파일에 사용되지 않는 것으로 나타났습니다. 다시 말하지만, 누구든지 작동하게되면 아래에 댓글을 달아주세요.
이 기능이 유용하고 가능한 모든 조합을 통해 하루를 낭비하지 않아도되기를 바랍니다. 개선의 여지가 있으므로 의견을 환영합니다.
위의 Brian의 대답은 저에게 90 %를 얻었습니다. 끝내기 위해 MIME 유형에 대해
android:mimeType="*/*"
나는 이전 포스터가 동일한 세부 사항을 게시하려고 시도했지만 별표 슬래시 별을 코드로 평가하지 않아도 stackoverflow는 단순히 슬래시로 표시합니다.
대신 이 특정 콘텐츠의 MIME 유형 값을 사용하여 android:path
시도 android:mimeType
하십시오. 또한 android:path
와일드 카드를 허용하지 않습니다 android:pathPattern
.이를 위해 사용하십시오 .
나는 이것이 오랫동안 작동하도록 노력해 왔으며 기본적으로 모든 제안 된 솔루션을 시도했지만 여전히 Android가 특정 파일 확장자를 인식하도록 할 수 없습니다. 나는 "*/*"
작동하는 것처럼 보이는 유일한 MIME 유형을 가진 인 텐트 필터를 가지고 있으며 파일 브라우저는 이제 파일 열기 옵션으로 내 앱을 나열하지만 이제 내 앱은 모든 종류의 파일을 여는 옵션으로 표시됩니다. pathPattern 태그를 사용하여 특정 파일 확장자를 지정했습니다. 지금까지 연락처 목록에서 연락처를 보거나 편집하려고 할 때도 Android에서 내 앱을 사용하여 연락처를 볼 것인지 묻는 메시지가 표시되며, 이는 이러한 상황이 발생하는 여러 상황 중 하나 일뿐입니다.
결국 나는 실제 Android 프레임 워크 엔지니어가 답변 한 비슷한 질문이있는이 Google 그룹 게시물을 발견했습니다. 그녀는 Android는 파일 확장자에 대해 아무것도 모르고 MIME 유형 ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ) 만 알 수 있다고 설명합니다 .
그래서 제가보고 시도하고 읽은 것에서 안드로이드는 단순히 파일 확장자를 구별 할 수 없으며 pathPattern 태그는 기본적으로 엄청난 시간과 에너지 낭비입니다. 운 좋게도 특정 MIME 유형 (예 : 텍스트, 비디오 또는 오디오)의 파일 만 필요하다면 MIME 유형과 함께 인 텐트 필터를 사용할 수 있습니다. 특정 파일 확장자 또는 Android에서 알지 못하는 MIME 유형이 필요한 경우 운이 좋지 않습니다.
If I'm wrong about any of this please tell me, so far I've read every post and tried every proposed solution I could find but none have worked.
I could write another page or two about how common these kinds of things seem to be in Android and how screwed up the developer experience is, but I'll save you my angry rantings ;). Hope I saved someone some trouble.
Brian's answer is very close, but here's a clean and error-free way to have your app invoked when trying to open a file with your own custom extension (no need for scheme or host):
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="*/*" />
<data android:pathPattern="*.*\\.kdb" />
</intent-filter>
On Android 4 the rules became more strict then they used to be. Use:
<data
android:host=""
android:mimeType="*/*"
android:pathPattern=".*\\.ext"
android:scheme="file"
></data>
I've been struggling with this quite a bit for a custom file extension, myself. After a lot of searching, I found this web page where the poster discovered that Android's patternMatcher class (which is used for the pathPattern matching in Intent-Filters) has unexpected behavior when your path contains the first character of your match pattern elsewhere in the path (like if you're trying to match "*.xyz", the patternMatcher class stops if there's an "x" earlier in your path). Here's what he found for a workaround, and worked for me, although it is a bit of a hack:
PatternMatcher is used for pathPattern at IntentFilter But, PatternMatcher's algorithm is quite strange to me. Here is algorithm of Android PatternMatcher.
If there is 'next character' of '.*' pattern in the middle of string, PatternMatcher stops loop at that point. (See PatternMatcher.java of Android framework.)
Ex. string : "this is a my attachment" pattern : ".att.". Android PatternMatcher enter loop to match '.' pattern until meet the next character of pattern (at this example, 'a') So, '.' matching loop stops at index 8 - 'a' between 'is' and 'my'. Therefore result of this match returns 'false'.
Quite strange, isn't it. To workaround this - actually reduce possibility - developer should use annoying stupid pathPattern.
Ex. Goal : Matching uri path which includes 'message'.
<intent-filter>
...
<data android:pathPattern=".*message.*" />
<data android:pathPattern=".*m.*message.*" />
<data android:pathPattern=".*m.*m.*message.*" />
<data android:pathPattern=".*m.*m.*m.*message.*" />
<data android:pathPattern=".*m.*m.*m.*m.*message.*" />
...
</intent-filter>
This is especially issued when matching with custom file extention.
None of the above work properly, for VIEW or SEND actions, if the suffix is not registered with a MIME type in Android's system=wide MIME database. The only settings I've found that fire for the specified suffix include android:mimeType="*/*"
, but then the action fires for ALL files. Clearly NOT what you want!
I can't find any proper solution without adding the mime and suffix to the Android mime database, so far, I haven't found a way to do that. If anyone knows, a pointer would be terrific.
When an Intent meets a intent-filter
, these are the intent-filter
requirements: (imagine a checklist).
- Any matching
<action>
- Any matching
<category>
- Any matching
<data mimeType>
(easy fix: "/") Optionally:
Any matching
<data scheme>
(easy fix:<data android:scheme="file" /> <data android:scheme="content" />
)Any matching
<data host>
(easy fix: "*")- Any matching
<data pathPattern/etc.>
(for example.*\\.0cc
)
Defining multiple <data $type="">
elements checks the $type box iff any <data $type=>
matches the Intent
.
Omitting mimeType breaks your intent-filter
, even though it's seemingly redundant. Omitting <data scheme/host/pathPattern>
causes your filter to match everything.
https://f-droid.org/en/packages/de.k3b.android.intentintercept/ is an app designed to receive all intents, and allows you to inspect the intent. I learned that unrecognized file extensions opened via Simple File Manager are delivered with MIME type application/octet-stream
.
https://stackoverflow.com/a/4621284/2683842 reports that <data pathPattern=>
.*xyz
aborts at the first x
it sees, and will fail immediately if not followed by yz
. So /sdcard/.hidden/foo.0cc
will not pass .*\\.0cc
unless you try .*\\..*\\.0cc
instead.
- I did not verify whether this workaround is necessary.
End result:
<activity android:name=".Ft2NsfActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:host="*" />
<data android:pathPattern=".*\\.ftm"/>
<data android:pathPattern=".*\\..*\\.ftm"/>
<data android:pathPattern=".*\\..*\\..*\\.ftm"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\.ftm"/>
<data android:pathPattern=".*\\.0cc"/>
<data android:pathPattern=".*\\..*\\.0cc"/>
<data android:pathPattern=".*\\..*\\..*\\.0cc"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\.0cc"/>
<data android:mimeType="*/*" />
</intent-filter>
</activity>
If you want the files to be opened directly from Gmail, dropbox or any of the buildin android file tools, then use the following code (delete 'android:host="*"' that made the file unreachable for gmail) :
<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="content" android:pathPattern=".*\\.kdb"
android:mimeType="application/octet-stream"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="file" android:mimeType="*/*"
android:pathPattern=".*\\.kdb"/>
</intent-filter>
The data filter must be written in one statement as per Android version 4.x
Using the filter as below to open from browser, gmail & file browser (Tested). NOTE: Please do not merge two filters, that will make browser ignored your app(Tested).
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="file" android:pathPattern=".*\\.ext" android:mimeType="application/*"/>
<data android:scheme="content" android:pathPattern=".*\\.ext" android:mimeType="application/*"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http"
android:host="*"
android:pathPattern=".*\\.ext" />
<data android:scheme="https"
android:host="*"
android:pathPattern=".*\\.ext" />
<data android:scheme="ftp"
android:host="*"
android:pathPattern=".*\\.ext" />
</intent-filter>
참고URL : https://stackoverflow.com/questions/1733195/android-intent-filter-for-a-particular-file-extension
'program tip' 카테고리의 다른 글
외부 파일의 Log4Net 구성이 작동하지 않습니다. (0) | 2020.09.09 |
---|---|
디렉토리를 삭제하는 것보다 iPhone Simulator 캐시를 지우는 더 빠르고 더 좋은 방법이 있습니까? (0) | 2020.09.09 |
소프트 키보드 팝업시 페이지 스크롤 (0) | 2020.09.09 |
ADO.NET에서 출력 매개 변수 값 가져 오기 (0) | 2020.09.09 |
쉬운 디버깅을 위해 Rails에서 객체의 내용을 어떻게 인쇄합니까? (0) | 2020.09.09 |