2017-08-16 103 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