我尝试制作一个包含文件夹浏览器的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;
}
}
}
答案 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。