2017-08-16 102 views
0

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

代码: 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; 
     } 
    } 
} 
+1

向我们展示您到目前为止的代码。 –

+0

你想看所有的音乐文件吗?我可以帮助你。现在 –

+0

@billynomates检查编辑 – Sabatino

回答

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时间权限检查。

+0

我已经发布了我的代码,请检查编辑 – Sabatino

1

一个更简单的方法是,如果你使用ContentProviders

可以列出了所有的音乐文件或文件本身(您甚至可以提供分拣或多个过滤器来缩小您的列表)。这就像使用数据库一样。

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

这里你需要做什么。

1) Create an instance of Cursor.
2) Iterate Cursor to get your media files

创建实例

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

允许在所述第一两个参数

焦点)URI - 它可以是内部或外部存储。
供外部使用 - MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
供外部使用 - MediaStore.Audio.Media.INTERAL_CONTENT_URI;

B)投影是您可以使用它让你的文件的元数据,如PATH,歌手名,NO歌曲和多

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

现在你已经创建了光标的数组。接下来的部分是遍历它。

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

我试图按照你所说的去做,但是我得到这个错误:java.lang.NullPointerException:'试图写入到空对象引用字段'int android.support.v7.widget.RecyclerView $ ViewHolder.mItemViewType'(没有指定这个错误在哪里,但是如果我把光标放在注释之间,代码工作正常)。以下是我的新代码:https://pastebin.com/6trkmaQu – Sabatino

+0

@Sabatino我在本地机器上检查了您的代码(pastebin),没有使用RecyclerView适配器。我工作正常。您似乎遇到了RecyclerView适配器的问题。 –

+0

好吧,坚持下去,我会尽量使用好旧的ListView – Sabatino