samus
samus

Reputation: 6202

Opening an unknown file type in Android (6.0)

Instead of telling a user that they cannot open their file b/c "there are no supported apps" (ie Samsung) or something, I wan't to let them choose an app, like Asus (KitKat) does with their File Manager. Opening a file named test.noapp gives the following prompt

enter image description here

Choosing Text then gives a list of text-processing apps

enter image description here

Do I have to roll my own "Open as" category list, or is there something in the API (level 23) that I can leverage?


The following code is used to open files

Intent viewFileIntent = new Intent(Intent.ActionView);

Android.Net.Uri uriFile = Android.Net.Uri.FromFile(selectedAttachmentDetails.File);
string mimeType = GetAttachmentFileTypeMimeString(selectedAttachmentDetails.File.Name);

viewFileIntent.SetDataAndType(uriFile, mimeType);

THIS.StartActivityForResult(Intent.CreateChooser(viewFileIntent, "Complete action using"), 0);

private string GetAttachmentFileTypeMimeString(string attachmentFileName)
{
    string ext = Android.Webkit.MimeTypeMap.GetFileExtensionFromUrl(attachmentFileName);
    Android.Webkit.MimeTypeMap map = Android.Webkit.MimeTypeMap.Singleton;

    string mimeType = map.GetMimeTypeFromExtension(ext);    

    return mimeType == null ? "*/*" : mimeType;
}

Upvotes: 0

Views: 1781

Answers (2)

samus
samus

Reputation: 6202

styles.xml

<style name="OpenAsDialog" parent="android:Theme.Holo.Light.Dialog">  
    <item name="android:windowIsFloating">true</item>  
</style>

OpenAsDialog.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/open_as_dialog_root"
  android:orientation="vertical"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="#C0C0C0">
  <TextView
    android:id="@+id/open_as_dialog_tv_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom ="0.5dp"
    android:padding="10dp"
    android:background="#FFFFFF"
    android:text="Text"
    android:textSize="16sp"
    android:textColor ="#808080"/>
  <TextView
    android:id="@+id/open_as_dialog_tv_image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom ="0.5dp"
    android:paddingTop="0dp"
    android:padding="10dp"
    android:background="#FFFFFF"
    android:text="Image"
    android:textSize="16sp"
    android:textColor ="#808080"/>
  <TextView
    android:id="@+id/open_as_dialog_tv_audio"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom ="0.5dp"
    android:padding="10dp"
    android:background="#FFFFFF"
    android:text="Audio"
    android:textSize="16sp"
    android:textColor ="#808080"/>
  <TextView
    android:id="@+id/open_as_dialog_tv_video"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:background="#FFFFFF"
    android:text="Video"
    android:textSize="16sp"
    android:textColor ="#808080"/>      
</LinearLayout>

DialogFragment

public class OpenAsDialog : DialogFragment
{
    public static OpenAsDialog NewInstance()
    {
        OpenAsDialog dialogFragment = new OpenAsDialog();            

        return dialogFragment;
    }

    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        SetStyle(DialogFragmentStyle.Normal, Resource.Style.OpenAsDialog);            
    }        

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View messageView = inflater.Inflate(Resource.Layout.OpenAsDialog, container, false);            

        return messageView;
    }

    public override void OnViewCreated(View view, Bundle savedInstanceState)
    {
        base.OnViewCreated(view, savedInstanceState);

        Dialog.SetTitle("Open as");
    }        
}

Usage

private void ShowOpenAsDialog()
{
    OpenAsDialog openAsDialog = OpenAsDialog.NewInstance();
    openAsDialog.Show(THIS.FragmentManager, "open_as_dialog");
}

Upvotes: 0

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37594

The reason why they are asking if it's a text, audio, video etc. is to set the verbose mime and let the android OS handle it.

With that in mind you can guess the mime and set it. Other than that there is also guessContentTypeFromStream

It's from the class MimeTypeMap.

Upvotes: 1

Related Questions