Bộ lọc ý định của Android: liên kết ứng dụng với phần mở rộng tệp


92

Tôi có một loại tệp / phần mở rộng tùy chỉnh mà tôi muốn liên kết với ứng dụng của mình.

Theo như tôi biết, phần tử dữ liệu được tạo ra cho mục đích này, nhưng tôi không thể làm cho nó hoạt động. http://developer.android.com/guide/topics/manifest/data-element.html Theo tài liệu và rất nhiều bài đăng trên diễn đàn, nó sẽ hoạt động như thế này:

<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>

Vâng, nó không hoạt động. Tôi đã làm gì sai? Tôi chỉ muốn khai báo loại tệp của riêng tôi.


Thêm android: label = "@ string / app_name" vào bộ lọc ý định
Prashant

Câu trả lời:


116

Bạn cần nhiều bộ lọc ý định để giải quyết các tình huống khác nhau mà bạn muốn xử lý.

Ví dụ 1, xử lý các yêu cầu http không có 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>

Xử lý với các kiểu mimetype, trong đó hậu tố không liên quan:

  <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>

Xử lý ý định từ ứng dụng trình duyệt tệp:

  <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>

Tôi nghĩ rằng máy chủ = "*" có thể được bỏ qua, nhưng nó bắt đầu quá rộng.
Trà Phyrum vào

@Phyrum Tea: Có cách nào để liên kết phần mở rộng tệp với ứng dụng KHÁC bằng ứng dụng của tôi không? Ứng dụng của tôi tạo các tệp .list mà tôi muốn cho android biết rằng chúng là tệp văn bản và để mở chúng bằng trình chỉnh sửa văn bản (ứng dụng của tôi KHÔNG phải là trình soạn thảo văn bản).
Luis A. Florit

@ LuisA.Florit Bạn đã thử gọi các tệp của mình là * .txt chưa? Có thể đấy.
Gavriel

tiện ích mở rộng tùy chỉnh không hoạt động với MimeType. Nếu tôi cung cấp mimetype là / ứng dụng của tôi đang hiển thị khi tôi nhấp vào thông báo Gmail.
madan V

1
Không hoạt động .. Tôi đã chán ngấy khi tìm kiếm trong 2 ngày qua không hoạt động. im sử dụng android 9
Ahmad Arslan

48

Các giải pháp khác không hoạt động đáng tin cậy đối với tôi cho đến khi tôi thêm:

android:mimeType="*/*" 

Trước đó, nó hoạt động trong một số ứng dụng, trong một số thì không ...

giải pháp hoàn chỉnh cho tôi:

<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>

1
ồ! điều này đã giúp tôi. Có vẻ như tài liệu Android không chính xác. Tất cả (sơ đồ, máy chủ, đường dẫn [Pattern], MIMETYPE) phải được khai báo với công việc
Gavriel

Bạn nên có cả quy tắc có mimeTypevà không có nếu bạn muốn hoàn chỉnh. Xem developer.android.com/guide/components/…
Andrew Sun

1
Điều gì xảy ra nếu bạn muốn mở ứng dụng tệp của mình từ Gmail?
IgorGanapolsky

30

Những người trả lời được đưa ra bởi Phyrum Teayuku đã rất nhiều thông tin.

Tôi muốn thêm điều đó bắt đầu với Android 7.0 Nougat có một sự thay đổi đối với cách xử lý chia sẻ tệp giữa các ứng dụng:

Từ những thay đổi chính thức của Android 7.0 :

Đối với các ứng dụng nhắm mục tiêu đến Android 7.0, khung Android thực thi chính sách API nghiêm ngặt để cấm tiết lộ tệp: // URI bên ngoài ứng dụng của bạn. Nếu một ý định chứa URI tệp rời khỏi ứng dụng của bạn, ứng dụng sẽ không thành công với ngoại lệ FileUriExposedException.

Để chia sẻ tệp giữa các ứng dụng, bạn nên gửi nội dung: // URI và cấp quyền truy cập tạm thời trên URI. Cách dễ nhất để cấp quyền này là sử dụng lớp FileProvider. Để biết thêm thông tin về quyền và chia sẻ tệp, hãy xem Chia sẻ tệp.

Nếu bạn có tệp tùy chỉnh của riêng mình kết thúc mà không có đuôi cụ thể mime-type(hoặc tôi đoán là thậm chí có một), bạn có thể phải thêm schemegiá trị thứ hai vào intent-filterđể làm cho nó hoạt động vớiFileProviders .

Thí dụ:

<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>

Điều quan trọng ở đây là việc bổ sung

<data android:scheme="content" />

vào bộ lọc.

Tôi đã gặp khó khăn khi tìm hiểu về thay đổi nhỏ này khiến hoạt động của tôi không thể mở trên các thiết bị Android 7.0 trong khi mọi thứ đều tốt trên các phiên bản cũ hơn. Tôi hi vọng nó giúp ích cho ai đó.


Nếu không có mẹo này và thông tin bổ sung, tôi không thể đăng ký ứng dụng của mình với trình khám phá tệp. Đây là quan trọng và cần được bỏ phiếu tán
u2tall

Bạn đã tiết kiệm một ngày! Tnx lớn. Câu trả lời này nên được chấp nhận!
Andris

⚠️ Nếu bạn cố gắng lấy tệp được cung cấp qua lược đồ nội dung, chẳng hạn như File(uri.path), nó sẽ bị lỗi do No such file or directory- sẽ phải xử lý tình huống đó theo cách khác khi cập nhật để hỗ trợ Nougat +!
Jordan H

19

Phát hiện của tôi:

Bạn cần một số bộ lọc để giải quyết các cách khác nhau để truy xuất tệp. tức là, bằng tệp đính kèm gmail, bằng trình khám phá tệp, bằng HTTP, bằng FTP ... Tất cả đều gửi các nội dung rất khác nhau.

Và bạn cần lọc ra mục đích kích hoạt hoạt động của bạn trong mã hoạt động của bạn.

Đối với ví dụ bên dưới, tôi đã tạo một loại tệp giả mạo new.mrz. Và tôi đã truy xuất nó từ tệp đính kèm gmail và trình khám phá tệp.

Mã hoạt động được thêm vào 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!
            }
        }

Bộ lọc tệp đính kèm trong 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>
  • LOG: Đã phát hiện mục đích nội dung: android.intent.action.VIEW: content: //gmail-ls/l.foul@gmail.com/messages/2950/attachments/0.1/BEST/false: application / octet-stream: new. mrz

Bộ lọc trình khám phá tệp:

        <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>
  • ĐĂNG NHẬP: Đã phát hiện mục đích tệp: android.intent.action.VIEW: tệp: ///storage/sdcard0/My%20Documents/new.mrz: null: new.mrz

Bộ lọc 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>

Các chức năng riêng được sử dụng ở trên:

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());
    }
}

Hoạt động phải là trình khởi chạy hay loại chính? Bởi vì tôi đã thử bộ lọc tệp đính kèm trong Gmail và nó không hoạt động.
Amit

15

Các pathPattern

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

không hoạt động nếu đường dẫn tệp chứa một hoặc nhiều dấu chấm trước ".pdf".

Điều này sẽ hoạt động:

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

Thêm nhiều hơn nếu bạn muốn hỗ trợ thêm dấu chấm.


1
Hiện tại, đây là tùy chọn duy nhất để chuyển đến các thư mục con
LokiDroid

Tôi đang sử dụng cùng mã nhưng IDE cho tôi một lời cảnh báo, xem câu hỏi này stackoverflow.com/questions/35833776/...
AndreaF

5

Tôi đã cố gắng làm cho điều này hoạt động trong nhiều thời gian và về cơ bản đã thử tất cả các giải pháp được đề xuất nhưng vẫn không thể khiến Android nhận ra các phần mở rộng tệp cụ thể. Tôi có một bộ lọc ý định với một "*/*"mimetype, đây là thứ duy nhất có vẻ hoạt động và các trình duyệt tệp hiện liệt kê ứng dụng của tôi như một tùy chọn để mở tệp, tuy nhiên, ứng dụng của tôi hiện được hiển thị dưới dạng tùy chọn để mở BẤT KỲ LOẠI tệp nào mặc dù Tôi đã chỉ định các phần mở rộng tệp cụ thể bằng thẻ pathPattern. Điều này tiến xa đến mức ngay cả khi tôi cố gắng xem / chỉnh sửa một số liên lạc trong danh sách liên hệ của mình, Android vẫn hỏi tôi có muốn sử dụng ứng dụng của mình để xem số liên lạc đó không và đó chỉ là một trong nhiều tình huống xảy ra, RẤT RẤT khó chịu.

Cuối cùng, tôi thấy nhóm google này đăng bài với câu hỏi tương tự mà một kỹ sư khung Android thực tế đã trả lời. Cô ấy giải thích rằng Android đơn giản là không biết gì về phần mở rộng tệp, chỉ có kiểu MIME ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ).

Vì vậy, từ những gì tôi đã thấy, thử và đọc, Android chỉ đơn giản là không thể phân biệt giữa các phần mở rộng tệp và thẻ pathPattern về cơ bản là một sự lãng phí lớn về thời gian và năng lượng. Nếu bạn đủ may mắn để chỉ cần các tệp thuộc loại kịch câm nhất định (ví dụ như văn bản, video hoặc âm thanh), bạn có thể sử dụng bộ lọc ý định với loại kịch câm. Tuy nhiên, nếu bạn cần một phần mở rộng tệp cụ thể hoặc một loại kịch câm không được Android biết đến thì bạn không gặp may.

Nếu tôi sai về bất kỳ điều nào trong số này, vui lòng cho tôi biết, cho đến nay tôi đã đọc mọi bài đăng và thử mọi giải pháp được đề xuất mà tôi có thể tìm thấy nhưng không có giải pháp nào hiệu quả.

Tôi có thể viết một hoặc hai trang khác về mức độ phổ biến của những thứ này trong Android và trải nghiệm của nhà phát triển bị ảnh hưởng như thế nào, nhưng tôi sẽ lưu lại cho bạn những lời nói giận dữ của tôi;). Hy vọng tôi đã cứu ai đó một số rắc rối.


5

Markus Ressel đúng. Android 7.0 Nougat không còn cho phép chia sẻ tệp giữa các ứng dụng bằng URI tệp. Một URI nội dung phải được sử dụng. Tuy nhiên, URI nội dung không cho phép chia sẻ đường dẫn tệp, chỉ có kiểu kịch câm. Vì vậy, bạn không thể sử dụng URI nội dung để liên kết ứng dụng của mình với phần mở rộng tệp của riêng bạn.

Bệnh đậu mùa có một hành vi thú vị trên Android 7.0. Khi nó gặp một phần mở rộng tệp không xác định, nó dường như tạo thành ý định URI tệp nhưng thay vì khởi chạy ý định, nó gọi hệ điều hành để tìm ra ứng dụng nào có thể chấp nhận ý định đó. Nếu chỉ có một ứng dụng có thể chấp nhận URI tệp đó thì ứng dụng đó sẽ gửi trực tiếp URI nội dung khiêu dâm đến ứng dụng đó. Vì vậy, để làm việc với Dropbox, bạn không cần phải thay đổi các bộ lọc ý định trên ứng dụng của mình. Nó không yêu cầu bộ lọc ý định URI nội dung. Chỉ cần đảm bảo rằng ứng dụng có thể nhận được URI nội dung và ứng dụng có phần mở rộng tệp của riêng bạn sẽ hoạt động với Dropbox giống như trước Android 7.0.

Đây là một ví dụ về mã tải tệp của tôi đã được sửa đổi để chấp nhận URI nội dung:

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);
        ...
    }
}

1

Thử thêm

<action android:name="android.intent.action.VIEW"/>

Bây giờ hoạt động với các loại tệp thiết lập ban đầu như ứng dụng / pdf, tôi sẽ khai báo loại tệp của riêng mình như thế nào? Và khi tôi nói loại tệp, ý tôi là mimeType;)
Tamas 21/09/10

Bạn muốn loại tập tin mimetype này bắt được? Ngoài ra, tệp này được mở từ trình duyệt hoặc trình quản lý tệp hay được gửi từ một ứng dụng khác mà bạn đã tạo?
magaio

có thể là từ trình duyệt, ứng dụng thư, trình quản lý tệp hoặc bất kỳ đâu .. Hoặc phần mở rộng tệp ứng dụng ofc :) của riêng tôi là tùy chỉnh, do ứng dụng khách chỉ định.
Tamas

Chà, tôi vẫn bị mắc kẹt ... ai đó có thể giúp tôi không?
Tamas

@Tamas bạn đã sắp xếp cái này chưa. Tôi bị mắc kẹt về điều này!
StuStirling

1

Đối với tệp đính kèm trong Gmail, bạn có thể sử dụng:

<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++ / ... -->

Thêm nhiều loại kịch câm nếu cần. Tôi chỉ cần những thứ đó cho dự án của mình.


1
         <!--
            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>

Lưu ý rằng điều này sẽ giúp ứng dụng của bạn mở tất cả các tệp đính kèm trong gmail, không có cách nào để giải quyết vấn đề này


Điều này sẽ xử lý tất cả các tập tin đơn gửi qua email cho người dùng, không chỉ .teamz
IgorGanapolsky

1

Những người gặp sự cố với các ứng dụng File Manager \ Explorer khác, như @yuku và @ phyrum-tea đã trả lời

Điều này hoạt động với ứng dụng quản lý tệp mặc định của 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>

nhưng không thể hoạt động với ES File Explorer và các Trình quản lý tệp khác nên tôi đã thêm

 android:mimeType="*/*"

thì nó hoạt động với ES Explorer nhưng trình quản lý tệp của LG không thể phát hiện loại tệp nên giải pháp của tôi là

     <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>

1

URI nội dung và với bộ lọc ý định trong tệp kê khai ... nếu tệp của bạn có phần mở rộng tùy chỉnh .xyz, hãy thêm một loại mime phù hợp:

        <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>

Một số ứng dụng như email dường như chuyển đổi tiện ích mở rộng thành một loại kịch câm. Bây giờ tôi có thể nhấp vào tệp đính kèm trong email và mở nó trong ứng dụng của tôi.


1

Bạn thử nó sẽ giúp ích cho bạn. Thay vì pdf, bạn có thể sử dụng các phần mở rộng khác. Trước tiên, bạn phải thêm quyền đọc bộ nhớ ngoài trong tệp androidmanifest.xml .

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Sau đó, trong tệp androidmanifest trong thẻ Activity, bạn thêm một bộ lọc ý định như hình dưới đây.

            <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>

Cuối cùng trong mã của bạn, bạn nhận được đường dẫn của tệp pdf như hình dưới đây:

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();

        }

Đối với Intent.ACTION_VIEW này, không thể lấy đường dẫn tệp, nó gây ra lỗi: java.io.FileNotFoundException: Quyền bị từ chối. Nó chỉ từ một số ứng dụng cụ thể, không phải mọi lúc. bất kỳ giải pháp?
Hardik Joshi

@HardikJoshi Các ứng dụng có thể không đặt quyền GRANT_READ_URI_PERMISSION.
Mira_Cole

1

Đọc tệp mở trong 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) 
        }
    }
}

-1

Đặt bộ lọc ý định này bên trong thẻ hoạt động trong tệp kê khai mà bạn muốn mở khi chạm vào tệp:

<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>

-1

// Tôi đã thử mã này. Và nó đang hoạt động tốt. Bạn có thể sử dụng mã này để chấp nhận tệp pdf.

<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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.