diff --git a/aFileChooser/src/com/ipaulpro/afilechooser/FileChooserActivity.java b/aFileChooser/src/com/ipaulpro/afilechooser/FileChooserActivity.java index 724cf1d..551a019 100644 --- a/aFileChooser/src/com/ipaulpro/afilechooser/FileChooserActivity.java +++ b/aFileChooser/src/com/ipaulpro/afilechooser/FileChooserActivity.java @@ -32,6 +32,7 @@ import android.support.v4.app.FragmentTransaction; import android.view.Menu; import android.view.MenuItem; +import android.webkit.MimeTypeMap; import android.widget.Toast; import java.io.File; @@ -46,8 +47,10 @@ public class FileChooserActivity extends FragmentActivity implements OnBackStackChangedListener, FileListFragment.Callbacks { public static final String PATH = "path"; + public static final String MIME_TYPE = "mime_type"; public static final String EXTERNAL_BASE_PATH = Environment .getExternalStorageDirectory().getAbsolutePath(); + public static final String MIME_TYPE_DEFAULT = "*/*"; private static final boolean HAS_ACTIONBAR = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; @@ -61,11 +64,14 @@ public void onReceive(Context context, Intent intent) { }; private String mPath; + private String mMimeType; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mMimeType = (getIntent() != null) ? getIntent().getType() : MIME_TYPE_DEFAULT; + mFragmentManager = getSupportFragmentManager(); mFragmentManager.addOnBackStackChangedListener(this); @@ -144,7 +150,7 @@ public boolean onOptionsItemSelected(MenuItem item) { * Add the initial Fragment with given path. */ private void addFragment() { - FileListFragment fragment = FileListFragment.newInstance(mPath); + FileListFragment fragment = FileListFragment.newInstance(mPath, mMimeType); mFragmentManager.beginTransaction() .add(android.R.id.content, fragment).commit(); } @@ -158,7 +164,7 @@ private void addFragment() { private void replaceFragment(File file) { mPath = file.getAbsolutePath(); - FileListFragment fragment = FileListFragment.newInstance(mPath); + FileListFragment fragment = FileListFragment.newInstance(mPath, mMimeType); mFragmentManager.beginTransaction() .replace(android.R.id.content, fragment) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) diff --git a/aFileChooser/src/com/ipaulpro/afilechooser/FileListAdapter.java b/aFileChooser/src/com/ipaulpro/afilechooser/FileListAdapter.java index 3480122..405bc81 100644 --- a/aFileChooser/src/com/ipaulpro/afilechooser/FileListAdapter.java +++ b/aFileChooser/src/com/ipaulpro/afilechooser/FileListAdapter.java @@ -17,9 +17,11 @@ package com.ipaulpro.afilechooser; import android.content.Context; +import android.provider.DocumentsContract.Document; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.webkit.MimeTypeMap; import android.widget.BaseAdapter; import android.widget.TextView; @@ -27,6 +29,8 @@ import java.util.ArrayList; import java.util.List; +import com.ipaulpro.afilechooser.utils.FileUtils; + /** * List adapter for Files. * @@ -41,9 +45,11 @@ public class FileListAdapter extends BaseAdapter { private final LayoutInflater mInflater; private List mData = new ArrayList(); + private String mMimeType; - public FileListAdapter(Context context) { + public FileListAdapter(Context context, String mimeType) { mInflater = LayoutInflater.from(context); + mMimeType = mimeType; } public void add(File file) { @@ -115,7 +121,25 @@ public View getView(int position, View convertView, ViewGroup parent) { int icon = file.isDirectory() ? ICON_FOLDER : ICON_FILE; view.setCompoundDrawablesWithIntrinsicBounds(icon, 0, 0, 0); + // Disable visually + row.setEnabled(isEnabled(position)); + return row; } + @Override + public boolean isEnabled(int position) { + boolean enable = true; + + File file = getItem(position); + + // Always enabled if a folder + if (!file.isDirectory()) { + // Set enabled if the MIME types match + String concreteType = FileUtils.getMimeType(file); + enable = FileUtils.compareMimeTypes(concreteType, mMimeType); + } + + return enable; + } } \ No newline at end of file diff --git a/aFileChooser/src/com/ipaulpro/afilechooser/FileListFragment.java b/aFileChooser/src/com/ipaulpro/afilechooser/FileListFragment.java index 5da363a..e76ab9c 100644 --- a/aFileChooser/src/com/ipaulpro/afilechooser/FileListFragment.java +++ b/aFileChooser/src/com/ipaulpro/afilechooser/FileListFragment.java @@ -60,12 +60,14 @@ public interface Callbacks { * Create a new instance with the given file path. * * @param path The absolute path of the file (directory) to display. + * @param mimeType The MIME type for the file. * @return A new Fragment with the given file path. */ - public static FileListFragment newInstance(String path) { + public static FileListFragment newInstance(String path, String mimeType) { FileListFragment fragment = new FileListFragment(); Bundle args = new Bundle(); args.putString(FileChooserActivity.PATH, path); + args.putString(FileChooserActivity.MIME_TYPE, mimeType); fragment.setArguments(args); return fragment; @@ -86,11 +88,15 @@ public void onAttach(Activity activity) { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + String mimeType = getArguments() != null ? getArguments().getString( + FileChooserActivity.MIME_TYPE) + : FileChooserActivity.MIME_TYPE_DEFAULT; - mAdapter = new FileListAdapter(getActivity()); + mAdapter = new FileListAdapter(getActivity(), mimeType); mPath = getArguments() != null ? getArguments().getString( FileChooserActivity.PATH) : Environment .getExternalStorageDirectory().getAbsolutePath(); + } @Override diff --git a/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java b/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java index 25c8008..2a09109 100644 --- a/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java +++ b/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java @@ -159,6 +159,33 @@ public static String getMimeType(Context context, Uri uri) { return getMimeType(file); } + /** + * Helper to compare two MIME types, where one may be a pattern. + * + * @param concreteType A fully-specified MIME type. + * @param desiredType A desired MIME type that may be a pattern such as *\/*. + * @return Returns true if the two MIME types match. + */ + public static boolean compareMimeTypes(String concreteType, String desiredType) { + final int typeLength = desiredType.length(); + if (typeLength == 3 && desiredType.equals("*/*")) { + return true; + } + + final int slashpos = desiredType.indexOf('/'); + if (slashpos > 0) { + if (typeLength == slashpos+2 && desiredType.charAt(slashpos+1) == '*') { + if (desiredType.regionMatches(0, concreteType, 0, slashpos+1)) { + return true; + } + } else if (desiredType.equals(concreteType)) { + return true; + } + } + + return false; + } + /** * @param uri The Uri to check. * @return Whether the Uri authority is {@link LocalStorageProvider}.