Android 인 텐트 필터 : 앱을 파일 확장자와 연결
내 앱을 연결하려는 사용자 지정 파일 형식 / 확장자가 있습니다.
내가 아는 한, 데이터 요소는 이러한 목적으로 만들어졌지만 작동하지 않습니다. 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);
...
}
}
추가 시도
<action android:name="android.intent.action.VIEW"/>
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/pdf" /> <!-- .pdf -->
<data android:mimeType="application/msword" /> <!-- .doc / .dot -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" /> <!-- .docx -->
<data android:mimeType="application/vnd.ms-excel" /> <!-- .xls / .xlt / .xla -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" /> <!-- .xlsx -->
<data android:mimeType="application/vnd.ms-powerpoint" /> <!-- .ppt / .pps / .pot / .ppa -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" /> <!-- .pptx -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" /> <!-- .ppsx -->
<data android:mimeType="application/zip" /> <!-- .zip -->
<data android:mimeType="image/jpeg" /> <!-- .jpeg -->
<data android:mimeType="image/png" /> <!-- .png -->
<data android:mimeType="image/gif" /> <!-- .gif -->
<data android:mimeType="text/plain" /> <!-- .txt / .text / .log / .c / .c++ / ... -->
필요한만큼 MIME 유형을 추가하십시오. 내 프로젝트에만 필요합니다.
<!--
Works for Files, Drive and DropBox
-->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:mimeType="*/*" />
<data android:host="*" />
<data android:pathPattern=".*\\.teamz" />
</intent-filter>
<!--
Works 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:host="gmail-ls" android:scheme="content" android:mimeType="application/octet-stream"/>
</intent-filter>
이렇게하면 앱이 모든 Gmail 첨부 파일을 열게되므로 해결할 방법이 없습니다.
@yuku 및 @ phyrum-tea가 대답했듯이 다른 파일 관리자 \ Explorer 앱에 문제가있는 사람들
이것은 LG 기본 파일 관리자 앱에서 작동합니다.
<intent-filter android:label="@string/app_name_decrypt">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:pathPattern=".*\\.lock" />
<data android:pathPattern=".*\\..*\\.lock" />
<data android:pathPattern=".*\\..*\\..*\\.lock" />
</intent-filter>
하지만 ES 파일 탐색기 및 기타 파일 관리자에서 작동하지 않아서 추가했습니다.
android:mimeType="*/*"
그런 다음 ES Explorer에서 작동하지만 LG 파일 관리자가 파일 유형을 감지하지 못하여 내 솔루션은
<intent-filter android:label="@string/app_name_decrypt">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:pathPattern=".*\\.lock" />
<data android:pathPattern=".*\\..*\\.lock" />
<data android:pathPattern=".*\\..*\\..*\\.lock" />
</intent-filter>
<intent-filter android:label="@string/app_name_decrypt">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file"/>
<data android:scheme="content" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.lock" />
<data android:pathPattern=".*\\..*\\.lock" />
<data android:pathPattern=".*\\..*\\..*\\.lock" />
</intent-filter>
콘텐츠 URI ftw 및 매니페스트의 인 텐트 필터 ... 파일에 사용자 지정 확장자 .xyz가있는 경우 일치하는 MIME 유형을 추가합니다.
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="*"
android:mimeType="application/xyz"
android:scheme="content" />
</intent-filter>
이메일과 같은 일부 앱은 확장 프로그램을 MIME 유형으로 변환하는 것 같습니다. 이제 이메일의 첨부 파일을 클릭하여 내 앱에서 열 수 있습니다.
You try this it will help for you.Instead of pdf you can use other extensions also. First you have to add read external storage permission in androidmanifest.xml file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Then in the androidmanifest file in the Activity tag, you add an intent-filter as shown below.
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType= "application/pdf" />
<data android:host="*" />
</intent-filter>
Finally in your code, you get path of the pdf file as shown below:
Intent intent=getIntent();
if(intent!=null) {
String action=intent.getAction();
String type=intent.getType();
if(Intent.ACTION_VIEW.equals(action) && type.endsWith("pdf")) {
// Get the file from the intent object
Uri file_uri=intent.getData();
if(file_uri!=null)
filepath=file_uri.getPath();
else
filepath="No file";
}
else if(Intent.ACTION_SEND.equals(action) && type.endsWith("pdf")){
Uri uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
filepath = uri.getPath();
}
Read opening file in kotlin:
private fun checkFileOpening(intent: Intent) {
if (intent.action == Intent.ACTION_VIEW && (intent.scheme == ContentResolver.SCHEME_FILE
|| intent.scheme == ContentResolver.SCHEME_CONTENT)) {
val text = intent.data?.let {
contentResolver.openInputStream(it)?.bufferedReader()?.use(BufferedReader::readText)
}
}
}
Put this intent filter inside the activity tag in manifest you'd like to open touching the file:
<intent-filter android:priority="999">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.OPENABLE" />
<data android:host="*" />
<data android:mimeType="application/octet-stream" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.yourextension" />
<data android:pathPattern=".*\\..*\\..*\\..*\\.yourextension" />
<data android:pathPattern=".*\\..*\\..*\\.yourextension" />
<data android:pathPattern=".*\\..*\\.yourextension" />
<data android:pathPattern=".*\\.yourextension" />
<data android:scheme="content" />
</intent-filter>
// I have tried this code. And it is working well. You can use this code to accept pdf file.
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/pdf" />
<data android:pathPattern=".*\\.pdf" />
<data android:pathPattern=".*\\..*\\.pdf" />
<data android:pathPattern=".*\\..*\\..*\\.pdf" />
<data android:pathPattern=".*\\..*\\..*\\..*\\.pdf" />
</intent-filter>
참고URL : https://stackoverflow.com/questions/3760276/android-intent-filter-associate-app-with-file-extension
'Programing' 카테고리의 다른 글
Android Studio 단위 테스트 : 데이터 (입력) 파일 읽기 (0) | 2020.09.04 |
---|---|
SQL Developer에 새 연결을 추가 할 때 Oracle TNS 이름이 표시되지 않음 (0) | 2020.09.04 |
표준 입력에서 한 줄씩 읽는 방법은 무엇입니까? (0) | 2020.09.04 |
자바에서 객체를 삭제 하시겠습니까? (0) | 2020.09.04 |
Graphite 이외의 통계 데이터 용 GUI? (0) | 2020.09.04 |