내 앱을 연결하려는 사용자 지정 파일 형식 / 확장자가 있습니다.
내가 아는 한, 데이터 요소는 이러한 목적으로 만들어졌지만 작동하지 않습니다.
http://developer.android.com/guide/topics/manifest/data-element.html
문서 및 많은 포럼 게시물에 따르면 다음과 같이 작동합니다.
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="application/pdf" />
</intent-filter>
음, 작동하지 않습니다. 내가 뭘 잘못 했어? 내 자신의 파일 형식을 선언하고 싶습니다.
답변
처리하려는 다양한 상황을 해결하려면 여러 인 텐트 필터가 필요합니다.
예 1, MIME 유형없이 http 요청 처리 :
<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>
접미사가 관련없는 MIME 유형으로 처리합니다.
<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>
파일 브라우저 앱의 인 텐트 처리 :
<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>
답변
다른 솔루션은 다음을 추가 할 때까지 안정적으로 작동하지 않았습니다.
android:mimeType="*/*"
그 전에는 일부 응용 프로그램에서 작동했지만 일부에서는 작동하지 않았습니다.
나를위한 완벽한 솔루션 :
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.EXT" android:mimeType="*/*" />
</intent-filter>
답변
에 의해 주어진 answeres Phyrum 차 및 신용장은 이미 매우 유익하다.
Android 7.0 Nougat 부터 앱 간 파일 공유가 처리되는 방식이 변경 되었음을 추가하고 싶습니다 .
공식 Android 7.0 변경 사항 :
Android 7.0을 대상으로하는 앱의 경우 Android 프레임 워크는 앱 외부에 file : // URI를 노출하는 것을 금지하는 StrictMode API 정책을 시행합니다. 파일 URI가 포함 된 인 텐트가 앱을 떠나면 앱은 FileUriExposedException 예외와 함께 실패합니다.
애플리케이션간에 파일을 공유하려면 content : // URI를 전송하고 URI에 대한 임시 액세스 권한을 부여해야합니다. 이 권한을 부여하는 가장 쉬운 방법은 FileProvider 클래스를 사용하는 것입니다. 권한 및 파일 공유에 대한 자세한 내용은 파일 공유를 참조하십시오.
당신이 사용자 정의 파일을 특정하지 않고 종료하는 경우 mime-type
(또는 심지어 하나 생각) 당신은 두 번째 추가 할 수 있습니다 scheme
당신의 가치를 intent-filter
그와 함께 작동하도록 FileProviders
너무.
예:
<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: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:host="*" />
<data android:pathPattern=".*\\.sfx" />
<data android:pathPattern=".*\\..*\\.sfx" />
<data android:pathPattern=".*\\..*\\..*\\.sfx" />
<data android:pathPattern=".*\\..*\\..*\\..*\\.sfx" />
<!-- keep going if you need more -->
</intent-filter>
여기서 중요한 것은
<data android:scheme="content" />
필터에.
이전 버전에서는 모든 것이 정상인 동안 Android 7.0 기기에서 내 활동이 열리지 않도록하는이 작은 변경 사항에 대해 알아 내기가 어려웠습니다. 누군가에게 도움이되기를 바랍니다.
답변
내 결과 :
파일을 검색하는 다양한 방법을 처리하려면 여러 필터가 필요합니다. 즉, gmail 첨부 파일, 파일 탐색기, HTTP, FTP … 모두 매우 다른 의도를 보냅니다.
그리고 활동 코드에서 활동을 트리거하는 인 텐트를 필터링해야합니다.
아래 예에서는 가짜 파일 형식 new.mrz를 만들었습니다. 그리고 Gmail 첨부 파일과 파일 탐색기에서 검색했습니다.
onCreate ()에 추가 된 활동 코드 :
Intent intent = getIntent();
String action = intent.getAction();
if (action.compareTo(Intent.ACTION_VIEW) == 0) {
String scheme = intent.getScheme();
ContentResolver resolver = getContentResolver();
if (scheme.compareTo(ContentResolver.SCHEME_CONTENT) == 0) {
Uri uri = intent.getData();
String name = getContentName(resolver, uri);
Log.v("tag" , "Content intent detected: " + action + " : " + intent.getDataString() + " : " + intent.getType() + " : " + name);
InputStream input = resolver.openInputStream(uri);
String importfilepath = "/sdcard/My Documents/" + name;
InputStreamToFile(input, importfilepath);
}
else if (scheme.compareTo(ContentResolver.SCHEME_FILE) == 0) {
Uri uri = intent.getData();
String name = uri.getLastPathSegment();
Log.v("tag" , "File intent detected: " + action + " : " + intent.getDataString() + " : " + intent.getType() + " : " + name);
InputStream input = resolver.openInputStream(uri);
String importfilepath = "/sdcard/My Documents/" + name;
InputStreamToFile(input, importfilepath);
}
else if (scheme.compareTo("http") == 0) {
// TODO Import from HTTP!
}
else if (scheme.compareTo("ftp") == 0) {
// TODO Import from FTP!
}
}
Gmail 첨부 파일 필터 :
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content" />
<data android:mimeType="application/octet-stream" />
</intent-filter>
- 로그 : 콘텐츠 의도 감지 : android.intent.action.VIEW : content : //gmail-ls/l.foul@gmail.com/messages/2950/attachments/0.1/BEST/false : application / octet-stream : new. mrz
파일 탐색기 필터 :
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:pathPattern=".*\\.mrz" />
</intent-filter>
- 로그 : 파일 의도 감지 : android.intent.action.VIEW : file : ///storage/sdcard0/My%20Documents/new.mrz : null : new.mrz
HTTP 필터 :
<intent-filter android:label="@string/rbook_viewer">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:pathPattern=".*\\.mrz" />
</intent-filter>
위에 사용 된 개인 기능 :
private String getContentName(ContentResolver resolver, Uri uri){
Cursor cursor = resolver.query(uri, null, null, null, null);
cursor.moveToFirst();
int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
if (nameIndex >= 0) {
return cursor.getString(nameIndex);
} else {
return null;
}
}
private void InputStreamToFile(InputStream in, String file) {
try {
OutputStream out = new FileOutputStream(new File(file));
int size = 0;
byte[] buffer = new byte[1024];
while ((size = in.read(buffer)) != -1) {
out.write(buffer, 0, size);
}
out.close();
}
catch (Exception e) {
Log.e("MainActivity", "InputStreamToFile exception: " + e.getMessage());
}
}
답변
그만큼 pathPattern
<data android:pathPattern=".*\\.pdf" />
파일 경로에 “.pdf”앞에 하나 이상의 점이 있으면 작동하지 않습니다.
이것은 작동합니다.
<data android:pathPattern=".*\\.pdf" />
<data android:pathPattern=".*\\..*\\.pdf" />
<data android:pathPattern=".*\\..*\\..*\\.pdf" />
<data android:pathPattern=".*\\..*\\..*\\..*\\.pdf" />
더 많은 점을 지원하려면 더 추가하십시오.
답변
나는 이것이 오랫동안 작동하도록 노력해 왔으며 기본적으로 모든 제안 된 솔루션을 시도했지만 여전히 Android가 특정 파일 확장자를 인식하도록 할 수 없습니다. 나는 "*/*"
작동하는 것처럼 보이는 유일한 MIME 유형을 가진 인 텐트 필터를 가지고 있으며 파일 브라우저는 이제 파일 열기 옵션으로 내 앱을 나열하지만 이제 내 앱은 모든 종류의 파일을 여는 옵션으로 표시됩니다. pathPattern 태그를 사용하여 특정 파일 확장자를 지정했습니다. 지금까지 연락처 목록에서 연락처를 보거나 편집하려고 할 때도 Android에서 내 앱을 사용하여 연락처를 볼 것인지 묻는 메시지가 표시되며, 이는 이러한 상황이 발생하는 여러 상황 중 하나 일뿐입니다.
결국 나는 실제 Android 프레임 워크 엔지니어가 답변 한 비슷한 질문이있는이 Google 그룹 게시물을 발견했습니다. 그녀는 Android는 파일 확장자에 대해 아무것도 모르고 MIME 유형 ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ) 만 알 수 있다고 설명합니다 .
그래서 제가보고 시도하고 읽은 것에서 안드로이드는 단순히 파일 확장자를 구별 할 수 없으며 pathPattern 태그는 기본적으로 엄청난 시간과 에너지 낭비입니다. 운 좋게도 특정 MIME 유형 (예 : 텍스트, 비디오 또는 오디오)의 파일 만 필요하다면 MIME 유형과 함께 인 텐트 필터를 사용할 수 있습니다. 특정 파일 확장자 또는 Android에서 알지 못하는 MIME 유형이 필요한 경우 운이 좋지 않습니다.
내가 이것에 대해 틀렸다면 지금까지 모든 게시물을 읽고 내가 찾을 수있는 모든 제안 된 솔루션을 시도했지만 아무것도 작동하지 않았습니다.
이런 종류의 일들이 Android에서 얼마나 흔한 지, 개발자 경험이 얼마나 망가 졌는지에 대해 한두 페이지 더 쓸 수는 있지만, 제 분노한 소리를 저장해 드리겠습니다.). 누군가 문제를 해결했으면 좋겠어요
답변
Markus Ressel이 맞습니다. Android 7.0 Nougat는 더 이상 파일 URI를 사용하는 앱 간 파일 공유를 허용하지 않습니다. 콘텐츠 URI를 사용해야합니다. 그러나 콘텐츠 URI는 파일 경로 공유를 허용하지 않고 MIME 유형 만 허용합니다. 따라서 콘텐츠 URI를 사용하여 앱을 자체 파일 확장자와 연결할 수 없습니다.
Drobpox는 Android 7.0에서 흥미로운 동작을합니다. 알 수없는 파일 확장자를 만나면 파일 URI 인 텐트를 형성하는 것처럼 보이지만 인 텐트를 시작하는 대신 운영 체제를 호출하여 인 텐트를 수락 할 수있는 앱을 찾습니다. 해당 파일 URI를 수락 할 수있는 앱이 하나만있는 경우 명시 적 콘텐츠 URI를 해당 앱에 직접 보냅니다. 따라서 Dropbox를 사용하기 위해 앱에서 인 텐트 필터를 변경할 필요가 없습니다. 콘텐츠 URI 인 텐트 필터가 필요하지 않습니다. 앱이 콘텐츠 URI를 수신 할 수 있고 자체 파일 확장자를 가진 앱이 Android 7.0 이전과 마찬가지로 Dropbox에서 작동하는지 확인하세요.
다음은 콘텐츠 URI를 허용하도록 수정 된 파일로드 코드의 예입니다.
Uri uri = getIntent().getData();
if (uri != null) {
File myFile = null;
String scheme = uri.getScheme();
if (scheme.equals("file")) {
String fileName = uri.getEncodedPath();
myFile = new File(filename);
}
else if (!scheme.equals("content")) {
//error
return;
}
try {
InputStream inStream;
if (myFile != null) inStream = new FileInputStream(myFile);
else inStream = getContentResolver().openInputStream(uri);
InputStreamReader rdr = new InputStreamReader(inStream);
...
}
}