7

I've been working on an application which is set to open a file with a specific extension. It works some times with Gmail (some files open, while some don't), and I can open a file from the file explorer.

I can't open the files from the Email application on the phone however and as I say, some files do not open from the Gmail application with my application and some do!

Here is my code.

             <intent-filter > <!-- Solution from @richardlegget on this question http://stackoverflow.com/questions/8148629/intent-filter-to-download-attachment-from-gmail-apps-on-android -->
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="application/octet-stream" android:pathPattern=".*\\.myextension" />
             </intent-filter>
             <intent-filter >
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="*/*" android:scheme="file" android:host="*" android:pathPattern=".*\\.myextension" />
             </intent-filter>

My Question

Is there a blanket set of intent-filters that register a specific activity with any file containing the desired file extension from anywhere on the Android device?

StuStirling
  • 14,067
  • 20
  • 82
  • 138

4 Answers4

3

Not sure why are you using separate intent-filters when you can do it using a single tag.

        <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=".*\\.myextension" />
            <data android:scheme="https" android:host="*"
                android:pathPattern=".*\\.myextension" />
            <data android:scheme="content" android:host="*"
                android:pathPattern=".*\\.myextension" />
            <data android:scheme="file" android:host="*"
                android:pathPattern=".*\\.myextension" />
        </intent-filter>

There might be a permissions problem. I.E If your activity is set to open in separate task, then cannot access files created/owned by other applications. You'l have to set intent flags such that it opens in the same application.

Syed Aqeel Ashiq
  • 1,347
  • 3
  • 17
  • 50
  • No doesn't work. The reason I am creating separate tags for each intent-filter is because they don't work when just inside one. – StuStirling Feb 06 '14 at 14:09
  • I have made an edit, please see if it helps. I.E. you have to remove NEW_TASK intent flag from your activity, if it is there. – Syed Aqeel Ashiq Feb 13 '14 at 08:02
2

Try multiple <data android:pathPattern/> like this answer suggests

Community
  • 1
  • 1
catlan
  • 23,677
  • 8
  • 64
  • 74
1

You need to resolve your path yourself when the scheme is content, i.e. when you receive a URI to a ContentProvider. The system will look at the mime type for your by call to ContentResolver.getType(Uri uri) before your intent filter is checked, hence you need the code below.

Resolve the file path to your file by fetching a Cursor from the URI containing content scheme and query the _data column:

Cursor cursor = getContentResolver().query(URI, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) { 
    int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
    return cursor.getString(idx);
} 

And add this intent-filter:

<intent-filter >
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="content" />
    <data android:mimeType="ourapp/ourfileextension" />
    <data android:mimeType="application/zip" />
    <data android:mimeType="application/octet-stream" />
</intent-filter>
Magnus
  • 1,453
  • 11
  • 14
  • This will just open all files with the scheme `content` – StuStirling Feb 10 '14 at 07:49
  • @DiscoS2 yes, have you verified my statement about that you're trying to open URI pointing to content URI from gmail/email ? – Magnus Feb 10 '14 at 09:45
  • I have used this approach before. I know how some of the content is provided as a URI however I am still no closer to understanding how to just open my file type – StuStirling Feb 10 '14 at 10:03
  • Then how do you know that the file that the Content provider is pointing to is actually the file with correct file ending without doing the code above? – Magnus Feb 10 '14 at 10:12
  • 2
    I don't hence the question. I don't want to provide my application to be allowed to open every file type and then check in the app – StuStirling Feb 10 '14 at 10:41
  • @DiscoS2 Ok, test and see if my revised answer can help you – Magnus Feb 13 '14 at 20:49
1
  • Can open any type of file. But here i handled repeatedly used file types, without disturbing default behaviour.
  • And the snippet is as below...

    public void openAllFiles(File url) throws IOException { // Create URI File file=url; Uri uri = Uri.fromFile(file);

    Intent intent = new Intent(Intent.ACTION_VIEW);
    // Check what kind of file you are trying to open, by comparing the url with extensions.
    // When the if condition is matched, plugin sets the correct intent (mime) type,
    // so Android knew what application to use to open the file
    if (url.toString().contains(".doc") || url.toString().contains(".docx")) {
        // Word document
        intent.setDataAndType(uri, "application/msword");
    } else if(url.toString().contains(".pdf")) {
        // PDF file
        intent.setDataAndType(uri, "application/pdf");
    } else if(url.toString().contains(".ppt") || url.toString().contains(".pptx")) {
        // Powerpoint file
        intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
    } else if(url.toString().contains(".xls") || url.toString().contains(".xlsx")) {
        // Excel file
        intent.setDataAndType(uri, "application/vnd.ms-excel");
    } else if(url.toString().contains(".zip") || url.toString().contains(".rar")) {
        // WAV audio file
        intent.setDataAndType(uri, "application/x-wav");
    } else if(url.toString().contains(".rtf")) {
        // RTF file
        intent.setDataAndType(uri, "application/rtf");
    } else if(url.toString().contains(".wav") || url.toString().contains(".mp3")) {
        // WAV audio file
        intent.setDataAndType(uri, "audio/x-wav");
    } else if(url.toString().contains(".gif")) {
        // GIF file
        intent.setDataAndType(uri, "image/gif");
    } else if(url.toString().contains(".jpg") || url.toString().contains(".jpeg") || url.toString().contains(".png")) {
        // JPG file
        intent.setDataAndType(uri, "image/jpeg");
    } else if(url.toString().contains(".txt")) {
        // Text file
        intent.setDataAndType(uri, "text/plain");
    } else if(url.toString().contains(".3gp") || url.toString().contains(".mpg") || url.toString().contains(".mpeg") || url.toString().contains(".mpe") || url.toString().contains(".mp4") || url.toString().contains(".avi")) {
        // Video files
        intent.setDataAndType(uri, "video/*");
    } else {
        //if you want you can also define the intent type for any other file
    
        //additionally use else clause below, to manage other unknown extensions
        //in this case, Android will show all applications installed on the device
        //so you can choose which application to use
        intent.setDataAndType(uri, "*/*");
    }
    
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent); 
    

    }

karthik
  • 139
  • 10