Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Register a new file type in Android

I want to write a simple STL (geometrical data file) viewer application on Android, but I'm not able to make recognize a format to the system. I wrote this in my app manifest file:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.PICK" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http" />
    <data android:pathPattern=".*\\.stl" />
    <data android:mimeType="application/sla" />
    <data android:host="*" />
</intent-filter>

But the moment I launch the browser and go to download some sample STL file, the download is interrupted and I'm reported that the data file type is unknown for the system.

I have no real Android device, so I use only an emulator, and for development I use C# on MonoDroid (but I honestly don't think that is the problem).

How could I fix this problem?

like image 885
Tigran Avatar asked Jan 25 '11 22:01

Tigran


People also ask

How do I assign a file type in Android?

Open File Manager and browse the the folder containing the files that you want to associate with a particular app. This will set the target file types to be opened with the selected app and open that file in that app as well.


3 Answers

I'm using this manifest to register (for example) a .stl file type with my application:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="org.test.core" android:versionCode="1" android:versionName="1.0">     <application android:icon="@drawable/icon" android:label="@string/app_name">         <activity android:name=".Testy" android:label="@string/app_name">             <intent-filter>                 <action android:name="android.intent.action.MAIN" />                 <category android:name="android.intent.category.LAUNCHER" />             </intent-filter>         </activity>          <activity android:name="ThorActivity" android:label="@string/app_name">         </activity>          <activity android:name="LokiActivity" android:label="@string/app_name">         </activity>          <activity android:name="OdinActivity" android:label="@string/app_name">             <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=".*\\.stl" />                 <data android:scheme="https" android:host="*"                     android:pathPattern=".*\\.stl" />                 <data android:scheme="content" android:host="*"                     android:pathPattern=".*\\.stl" />                 <data android:scheme="file" android:host="*"                     android:pathPattern=".*\\.stl" />             </intent-filter>         </activity>     </application>      <uses-permission android:name="android.permission.INTERNET" />     <uses-permission android:name="android.permission.BLUETOOTH" />     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />     <uses-permission android:name="android.permission.READ_PHONE_STATE" />     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  </manifest> 

As you can see, I'm linking the .stl file extension to the activity OdinActivity. Inside the OdinActivity, I use the following line to get the file path so I can open it:

filePath = getIntent().getData().getEncodedPath(); 

Then I just open it to read from it:

FileOutputStream out = new FileOutputStream(new File(filePath)); 
like image 104
gnclmorais Avatar answered Oct 01 '22 09:10

gnclmorais


I am surprised that gnclmorais' solution should work. Because it, having multiple data entries in one intent-filter, did not work for me. What did work in the end was multiple intent-filter in one activity:

<activity
  android:description='@string/Activity_Description'
  android:icon='@drawable/ic_launcher'
  android:label='@string/Activity_Name'
  android:name='net.sourceforge.uiq3.fx603p.Calculator_Activity'
>
  <intent-filter>
    <action
      android:name='android.intent.action.MAIN'
    ></action>
    <category
      android:name='android.intent.category.LAUNCHER'
    ></category>
  </intent-filter>
  <intent-filter
    android:icon='@drawable/ic_fx_603p_pf'
    android:label='FX-603P Simulator Program'
    android:priority='1'
  >
    <category
      android:name='android.intent.category.DEFAULT'
    ></category>
    <action
      android:name='android.intent.action.VIEW'
    ></action>
    <data
      android:host='*'
      android:pathPattern='.*\\.pf'
      android:scheme='file'
    ></data>
  </intent-filter>
  <intent-filter
    android:icon='@drawable/ic_fx_603p_df'
    android:label='FX-603P Simulator Datafile'
    android:priority='1'
  >
    <category
      android:name='android.intent.category.DEFAULT'
    ></category>
    <action
      android:name='android.intent.action.VIEW'
    ></action>
    <data
      android:host='*'
      android:pathPattern='.*\\.df'
      android:scheme='file'
    ></data>
  </intent-filter>
  <intent-filter
    android:icon='@drawable/ic_fx_603p_af'
    android:label='FX-603P Simulator Allfile (Data and Program)'
    android:priority='1'
  >
    <category
      android:name='android.intent.category.DEFAULT'
    ></category>
    <action
      android:name='android.intent.action.VIEW'
    ></action>
    <data
      android:host='*'
      android:pathPattern='.*\\.af'
      android:scheme='file'
    ></data>
  </intent-filter>
  <intent-filter
    android:icon='@drawable/ic_fx_603p_pf'
    android:label='FX-603P Simulator Program'
    android:priority='1'
  >
    <category
      android:name='android.intent.category.DEFAULT'
    ></category>
    <action
      android:name='android.intent.action.VIEW'
    ></action>
    <data
      android:host='*'
      android:mimeType='application/x-fx-602p.program'
    ></data>
  </intent-filter>
  <intent-filter
    android:icon='@drawable/ic_fx_603p_df'
    android:label='FX-603P Simulator Datafile'
    android:priority='1'
  >
    <category
      android:name='android.intent.category.DEFAULT'
    ></category>
    <action
      android:name='android.intent.action.VIEW'
    ></action>
    <data
      android:host='*'
      android:mimeType='application/x-fx-602p.data'
    ></data>
  </intent-filter>
  <intent-filter
    android:icon='@drawable/ic_fx_603p_af'
    android:label='FX-603P Simulator Allfile (Data and Program)'
    android:priority='1'
  >
    <category
      android:name='android.intent.category.DEFAULT'
    ></category>
    <action
      android:name='android.intent.action.VIEW'
    ></action>
    <data
      android:host='*'
      android:mimeType='application/x-fx-602p.all'
    ></data>
  </intent-filter>
</activity>

Note that having both pathPattern and mimeType in one data entry did not work either. Last, but not least, I would suggest a few null checks when getting the file name:

   /**
    * <p>Open calculator and load file (if one was passed).</p>
    * @see android.app.Activity#onStart()
    */
   @Override
   public void onStart ()
   {
      android.util.Log.d (Calculator_Activity.TAG, "+ onStart");
      super.onStart ();

      final android.content.Intent intent = getIntent ();

      if (intent != null)
      {
         android.util.Log.d (Calculator_Activity.TAG, "> Got intent : " + intent);

         final android.net.Uri data = intent.getData ();

         if (data != null)
         {
            android.util.Log.d (Calculator_Activity.TAG, "> Got data   : " + data);

            final String filePath = data.getEncodedPath ();

            android.util.Log.d (Calculator_Activity.TAG, "> Open file  : " + filePath);

            // File loading comes here.
         } // if
      } // if
      android.util.Log.d (Calculator_Activity.TAG, "- onStart");
      return;
   } // onStart

The actual loading of the file is missing from the sample. It should be inserted after the “Open file” log command.

like image 37
Martin Avatar answered Oct 01 '22 08:10

Martin


I tried the other solutions and this is the only one which works for me:

<intent-filter
    android:icon="@drawable/icon"
    android:label="Armro File"
    android:priority="1" >
    <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" />
    <data android:scheme="https" />
    <data android:scheme="ftp" />
    <data android:scheme="file" />
    <data android:host="*" />
    <data android:mimeType="*/*" />
    <data android:pathPattern=".*\\.myowntype" />
</intent-filter>

Why do the other ones not work?

like image 28
Simon Avatar answered Oct 01 '22 09:10

Simon