[android] 특정 파일 확장자에 대한 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 문서에 따르면 속성이 작동 하려면 hostscheme속성이 모두 필요 pathPattern하므로 모든 항목과 일치하도록 와일드 카드로 설정하면됩니다.

이제 .kdbLinda File Manager와 같은 앱에서 파일 을 선택하면 내 앱이 옵션으로 표시됩니다. 이것만으로는 브라우저에서이 파일 형식을 다운로드 할 수 없다는 점에 유의해야합니다. 이것은 파일 체계에만 등록되기 때문입니다. 전화에 Linda File Manager와 같은 앱이 있으면 일반적으로 모든 파일 형식을 다운로드 할 수 있습니다.


답변

이 주제에 대한 많은 잘못된 정보가 있습니다. 특히 Google의 자체 문서에 있습니다. 이상한 논리를 감안할 때 가장 좋은 것은 소스 코드뿐입니다.

텐트 필터 구현 에는 설명을 거의 무시하는 논리가 있습니다. 파서 코드는 퍼즐의 다른 관련 작품이다.

다음 필터는 현명한 행동에 매우 가깝습니다. "file"스키마 의도에 대한 경로 패턴이 적용됩니다 .

전역 MIME 유형 패턴 일치는 파일 확장자가 일치하는 한 모든 유형과 일치합니다. 이것은 완벽하지는 않지만 ES 파일 탐색기와 같은 파일 관리자의 동작을 일치시키는 유일한 방법이며 URI / 파일 확장자가 일치하는 의도로 제한됩니다.

나는 "http"여기 와 같은 다른 구성표를 포함하지 않았지만 아마도 이러한 모든 필터에서 잘 작동 할 것입니다.

이상한 구성표는이며 "content", 필터에서 확장을 사용할 수 없습니다. 그러나 공급자가 MIME 유형을 명시하는 한 (예 : Gmail은 방해받지 않고 첨부 파일에 대해 MIME 유형을 전달합니다) 필터가 일치합니다.

주의해야 할 사항 :

  1. 필터에서 일관되게 작동하는 것은 없으며 특수한 경우의 미로이며 최소한의 놀라움 원칙 위반을 설계 목표로 취급합니다. 패턴 일치 알고리즘 중 어떤 것도 동일한 구문이나 동작을 따르지 않습니다. 필드의 부재는 때때로 와일드 카드이고 때로는 그렇지 않습니다. 데이터 요소 내의 속성은 때때로 함께 연결되어야하고 때로는 그룹화를 무시해야합니다. 정말 더 잘할 수있었습니다.
  2. scheme과는 host지정해야합니다 path규칙 (현재 구글의 API 가이드에 반하는)와 일치 할 수 있습니다.
  3. 최소한 ES 파일 탐색기는 MIME 유형이 ""인 인 텐트를 생성합니다.이 유형은와 매우 다르게 필터링 null되고 명시 적으로 일치하는 것이 불가능하며 위험한 "*/*"필터에 의해서만 일치 될 수 있습니다 .
  4. "*/*"필터는 함께 텐트를 일치하지 않습니다 null전혀 MIME 타입이 특정 사건에 대해 별도의 필터가 필요합니다 – MIME 타입.
  5. "content"원본 파일 이름 (적어도 Gmail을) 의도에서 사용할 수 없기 때문에 계획은, MIME 타입과 일치 할 수 있습니다.
  6. 별도의 속성 그룹화 "data"요소는 특정의의를 제외하고, 해석에 (거의) 무관 hostport– 함께 쌍을 할 수있다. 다른 모든 것은 "data"요소 내에서 또는 "data"요소 간에 특정 연관이 없습니다 .

이 모든 것을 염두에두고 다음은 주석이있는 예입니다.

<!--
     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:pathtry 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 유형이 필요하면 운이 좋지 않습니다.

내가 이것에 대해 틀렸다면 지금까지 모든 게시물을 읽고 내가 찾을 수있는 모든 제안 된 솔루션을 시도했지만 아무것도 작동하지 않았습니다.

이런 종류의 일들이 Android에서 얼마나 흔한 지, 개발자 경험이 얼마나 망가 졌는지에 대해 한두 페이지 더 쓸 수는 있지만, 제 분노한 외침을 구해 드리겠습니다.). 누군가 문제를 해결했으면 좋겠습니다.


답변

2020 업데이트

Android는 인 텐트 필터 용 콘텐츠 URI 및 MIME 유형으로 이동했습니다.

문제

콘텐츠 URI는 반드시 파일의 확장자 나 이름을 포함 할 필요는 없으며 콘텐츠 / 파일을 제공하는 다른 응용 프로그램간에 다릅니다.

다음은 동일한 이메일 첨부 파일에 대한 여러 이메일 애플리케이션의 콘텐츠 URI 예입니다 .

Gmail-> content://com.google.android.gm.sapi/some_email@gmail.com/message_attachment_external/%23thread-a%3Ar332738858767305663/%23msg-a%3Ar-5439466788231005876/0.1?account_type=com.google&mimeType=application%2Foctet-stream&rendition=1

전망-> content://com.microsoft.office.outlook.fileprovider/outlookfile/data/data/com.microsoft.office.outlook/cache/file-download/file--2146063402/filename.customextention

삼성 이메일 앱-> content://com.samsung.android.email.attachmentprovider/1/1/RAW

보시다시피 그들은 모두 다르며 실제 파일과 관련된 내용을 포함한다고 보장하지 않습니다. 따라서 android:pathPattern대부분이 제안한 것처럼 사용할 수 없습니다 .

이메일 첨부 파일에 대한 해결 방법

<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"/>
    <data android:host="*"/>

    <!--  Required for Gmail and Samsung Email App  -->
    <data android:mimeType="application/octet-stream"/>

    <!--  Required for Outlook  -->
    <data android:mimeType="application/my-custom-extension"/>
</intent-filter>

테스트를 통해 Gmail, Outlook 및 Samsung Email에서 사용하는 MIME 유형을 찾아서 인 텐트 필터에 추가했습니다.

주의 사항 / Gotchas

  • 위의 솔루션으로 바이너리 유형의 파일을 열면 자동으로 앱이 실행된다는 것을 알았습니다. 파일을 구문 분석 할 수없는 경우 실패 상태를 표시하여 내 활동에서 이것을 처리했습니다. 나는 이것이 매우 드문 이벤트라고 생각했기 때문에 받아 들일 것입니다.

  • <data android:mimeType="*/*"/>텐트 필터를 추가하지 않고는 파일 브라우저를 통해 내 앱을 실행할 수있는 방법을 찾을 수 없습니다 . 사용자가 휴대폰에서 파일을 클릭 때마다 내 앱이 실행되기 때문에 사용할 수 없었습니다 (사용자 지정 파일 확장 파일뿐만 아니라). 나는 이것을 의도 필터에 추가하지 않는 것이 좋습니다.

마지막 생각들

  • 현재 Android의 특정 확장 유형과 앱을 연결하는 우아한 솔루션은 없습니다. 제 상황에서 할 수있는 최선의 방법이었습니다.