(Android)如何仅浏览包含音乐的文件夹

时间:2017-08-16 10:29:11

标签: java android browser directory filefilter

我尝试制作一个包含文件夹浏览器的Fragment,该浏览器仅显示至少有一首歌曲的文件夹。 我尝试过几个教程并使用Filefilter,但我仍然看到不包含任何有用信息的文件夹(例如Facebook文件夹),我该怎么办?它? 换句话说,我试图制作像this这样的文件夹浏览器;有人可以帮帮我吗?

代码: 的 FolderFragment.java

public class FolderFragment extends Fragment {
    private File file;
    private List<String> myList;
    private FolderAdapter mAdapter;
    private Context mContext;
    private LayoutInflater mInflater;
    private ViewGroup mContainer;
    private LinearLayoutManager mLayoutManager;
    View mRootView;
    private RecyclerView mRecyclerView;
    String root_files;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        mContext = container.getContext();
        mInflater = inflater;
        mContainer = container;

        mRootView = inflater.inflate(R.layout.fragment_folders, mContainer, false);
        mRecyclerView = (RecyclerView) mRootView.findViewById(R.id.recycler_view_folders);
        mLayoutManager = new LinearLayoutManager(mContext);
        mRecyclerView.setLayoutManager(mLayoutManager);
        if(getActivity() != null)
            new loadFolders().execute("");
        return mRootView;
    }

    private class loadFolders extends AsyncTask<String, Void, String>{

        @Override
        protected String doInBackground(String... params) {
            Activity activity = getActivity();
            if (activity != null) {

                mAdapter = new FolderAdapter(activity, new File("/storage"));
            }
            return "Executed";
        }

        @Override
        protected void onPostExecute(String result){
            mRecyclerView.setAdapter(mAdapter);
            mAdapter.notifyDataSetChanged();
        }
    }
}

FolderAdapter.java

public class FolderAdapter extends RecyclerView.Adapter<FolderAdapter.ItemHolder> implements BubbleTextGetter {
    private List<File> mFileSet;
    private List<Song> mSongs;
    private File mRoot;
    private Activity mContext;
    private boolean mBusy = false;

    public FolderAdapter(Activity context, File root){
        mContext = context;
        mSongs = new ArrayList<>();
        updateDataSet(root);
    }

    @Override
    public FolderAdapter.ItemHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_folder_list, viewGroup, false);
        return new ItemHolder(v);
    }

    @Override
    public void onBindViewHolder(final FolderAdapter.ItemHolder itemHolder, int i) {
        File localItem = mFileSet.get(i);
        Song song = mSongs.get(i);
        itemHolder.title.setText(localItem.getName());
        if (localItem.isDirectory()) {
            itemHolder.albumArt.setImageResource("..".equals(localItem.getName()) ? R.drawable.icon_4 : R.drawable.icon_5);
        } else {
            itemHolder.albumArt.setImageResource(R.drawable.icon_folder);
        }
    }

    @Override
    public int getItemCount(){
        Log.d("size fileset: ", ""+mFileSet.size());
        return mFileSet.size();
    }

    @Deprecated
    public void updateDataSet(File newRoot){
        if(mBusy) return;
        if("..".equals(newRoot.getName())){
            goUp();
            return;
        }
        mRoot = newRoot;
        mFileSet = FolderLoader.getMediaFiles(newRoot, true);
        getSongsForFiles(mFileSet);
    }

    @Deprecated
    public boolean goUp(){
        if(mRoot == null || mBusy){
            return false;
        }
        File parent = mRoot.getParentFile();
        if(parent != null && parent.canRead()){
            updateDataSet(parent);
            return true;
        } else {
            return false;
        }
    }

    public boolean goUpAsync(){
        if(mRoot == null || mBusy){
            return false;
        }
        File parent = mRoot.getParentFile();
        if(parent != null && parent.canRead()){
            return updateDataSetAsync(parent);
        } else {
            return false;
        }
    }

    public boolean updateDataSetAsync(File newRoot){
        if(mBusy){
            return false;
        }
        if("..".equals(newRoot.getName())){
            goUpAsync();
            return false;
        }
        mRoot = newRoot;
        new NavigateTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mRoot);
        return true;
    }

    @Override
    public String getTextToShowInBubble(int pos){
        if(mBusy || mFileSet.size() == 0) return "";
        try{
            File f = mFileSet.get(pos);
            if(f.isDirectory()){
                return String.valueOf(f.getName().charAt(0));
            } else {
                return Character.toString(f.getName().charAt(0));
            }
        } catch(Exception e){
            return "";
        }
    }

    private void getSongsForFiles(List<File> files){
        mSongs.clear();
        for(File file : files){
            mSongs.add(SongLoader.getSongFromPath(file.getAbsolutePath(), mContext));
        }
    }

    private class NavigateTask extends AsyncTask<File, Void, List<File>>{

        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            mBusy = true;
        }

        @Override
        protected List<File> doInBackground(File... params){
            List<File> files = FolderLoader.getMediaFiles(params[0], true);
            getSongsForFiles(files);
            return files;
        }

        @Override
        protected void onPostExecute(List<File> files){
            super.onPostExecute(files);
            mFileSet = files;
            notifyDataSetChanged();
            mBusy = false;
            //PreferencesUtility.getInstance(mContext).storeLastFolder(mRoot.getPath());

        }
    }

    public class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        protected TextView title;
        protected ImageView albumArt;

        public ItemHolder(View view) {
            super(view);
            this.title = (TextView) view.findViewById(R.id.folder_title);
            this.albumArt = (ImageView) view.findViewById(R.id.folder_album_art);
            view.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (mBusy) {
                return;
            }
            final File f = mFileSet.get(getAdapterPosition());

            if (f.isDirectory() && updateDataSetAsync(f)) {
                albumArt.setImageResource(R.drawable.ic_menu_send);
            } else if (f.isFile()) {

                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(mContext, "", Toast.LENGTH_LONG).show();
                    }
                }, 100);
            }
        }
    }
}

FolderLoader.java

public class FolderLoader {

    private static final String[] SUPPORTED_EXT = new String[] {
            "mp3",
            "m4a",
            "aac",
            "flac",
            "wav"
    };

    public static List<File> getMediaFiles(File dir, final boolean acceptDirs) {
        ArrayList<File> list = new ArrayList<>();
        list.add(new File(dir, "/storage"));
        if (dir.isDirectory()) {
            List<File> files = Arrays.asList(dir.listFiles(new FileFilter() {

                @Override
                public boolean accept(File file) {
                    if (file.isFile()) {
                        String name = file.getName();
                        return !".nomedia".equals(name) && checkFileExt(name);
                    } else if (file.isDirectory()) {
                        return acceptDirs && checkDir(file);
                    } else
                        return false;
                }
            }));
            Collections.sort(files, new FilenameComparator());
            Collections.sort(files, new DirFirstComparator());
            list.addAll(files);
        }

        return list;
    }

    public static boolean isMediaFile(File file) {
        return file.exists() && file.canRead() && checkFileExt(file.getName());
    }

    private static boolean checkDir(File dir) {
        return dir.exists() && dir.canRead() && !".".equals(dir.getName()) && dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                String name = pathname.getName();
                return !".".equals(name) && !"..".equals(name) && pathname.canRead() && (pathname.isDirectory()  || (pathname.isFile() && checkFileExt(name)));
            }

        }).length != 0;
    }

    private static boolean checkFileExt(String name) {
        if (TextUtils.isEmpty(name)) {
            return false;
        }
        int p = name.lastIndexOf(".") + 1;
        if (p < 1) {
            return false;
        }
        String ext = name.substring(p).toLowerCase();
        for (String o : SUPPORTED_EXT) {
            if (o.equals(ext)) {
                return true;
            }
        }
        return false;
    }

    private static class FilenameComparator implements Comparator<File> {
        @Override
        public int compare(File f1, File f2) {
            return f1.getName().compareTo(f2.getName());
        }
    }

    private static class DirFirstComparator implements Comparator<File> {
        @Override
        public int compare(File f1, File f2) {
            if (f1.isDirectory() == f2.isDirectory())
                return 0;
            else if (f1.isDirectory() && !f2.isDirectory())
                return -1;
            else
                return 1;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

如果您使用 ContentProviders

,则更简单的方法

您可以列出所有音乐文件或任何文件(您甚至可以提供排序或更多过滤器来缩小列表范围)。这就像使用数据库一样。

我现在无法发布完整代码。但是我可以告诉你如何解决这个问题,这种方法更具可读性和简洁性。

这是你需要做的。

  

1)创建一个Cursor实例   2)迭代光标以获取媒体   文件

创建实例

Cursor cursor = getContentResolver().query(URI uri ,String[] projection, null,null,null);

让我们关注前两个参数

a) URI - 可以是内部存储也可以是外部存储 外部使用 - MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
外部使用 - MediaStore.Audio.Media.INTERAL_CONTENT_URI;

b) Projection 是一个数组,用于获取文件的元数据,例如PATH,ARTIST NAME,NO OF SONGS等等

String[] proj = new String[]{MediaStore.Audio.Media.DISPLAY_NAME,MediaStore.Audio.Media.DATA};

现在你已经创建了Cursor。所以下一部分是迭代它。

while (cursor.moveToNext())
  {
     name = cursor.getString(cursor.getColumnIndex(modelConst.get_Proj()[0]));
     path =  cursor.getString(cursor.getColumnIndex(modelConst.get_Proj()[1]));
  }

答案 1 :(得分:0)

以下代码可能会对您有所帮助。更具体地说,如果以下内容不起作用或者不是您想要的,请显示您使用的一些代码。

Intent intent;
            intent = new Intent();
            intent.setAction(Intent.ACTION_GET_CONTENT);
            intent.setType("audio/*");
            startActivityForResult(Intent.createChooser(intent, "Title"), 89);

关于activty结果方法使用以下

 if (requestCode == 89 && resultCode == Activity.RESULT_OK){
        if ((data != null) && (data.getData() != null)){
            Uri audioFileUri = data.getData();
           // use uri to get path

            String path= audioFileUri.getPath();
        }
    }

确保在清单和运行时权限中给定外部存储读取权限,检查最新的sdk。