无法在SD卡上找到音频文件(Android Studio)

时间:2016-01-22 20:50:31

标签: java android android-studio

我有一个名为SongsManager的java类,它应该能够找到SD卡上的所有音频文件。不幸的是,我无法使用此代码找到任何音频文件。

在我的手机上,我在以下位置有多个.mp3和.wma文件供测试:

  • 卡\音乐
  • 卡\的Android \数据\ com.samsung.music

目前我在代码中使用以下SD卡路径:

 // SDCard Path
final String MEDIA_PATH = Environment.getExternalStorageDirectory().getPath() + "/";

我可能尝试过十几种不同的替代品,但显然还没有找到正确的路径。当我设置断点以查看MEDIA_PATH变量包含的内容时,我看到了:

MEDIA_PATH = "/storage/emulated/0/"

这似乎不是我的音乐所在,因为我的音乐在SD卡上。我想让应用程序在SD卡上找到音乐。

这是整个SongsManager.Java

package com.joshbgold.simplemusicplayer;

import android.os.Environment;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.HashMap;

public class SongsManager {

    // SDCard Path
    final String MEDIA_PATH = Environment.getExternalStorageDirectory().getPath() + "/";
    private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

    // Constructor
    public SongsManager(){
    }

    /**
     * Function to read all mp3 files from sdcard
     * and store the details in ArrayList
     * */
    public ArrayList<HashMap<String, String>> getPlayList(){
        File home = new File(MEDIA_PATH);

        if (home.listFiles(new FileExtensionFilter()).length > 0) {
            for (File file : home.listFiles(new FileExtensionFilter())) {
                HashMap<String, String> song = new HashMap<String, String>();
                song.put("songTitle", file.getName().substring(0, (file.getName().length() - 4)));
                song.put("songPath", file.getPath());

                // Adding each song to SongList
                songsList.add(song);
            }
        }
        // return songs playlist_item array
        return songsList;
    }

    /**
     * Class to filter files which are having .mp3 extension
     * */
    class FileExtensionFilter implements FilenameFilter {
        public boolean accept(File dir, String name) {
            return (name.endsWith(".mp3") || name.endsWith(".MP3") || name.endsWith(".wma"));
        }
    }
}

我有权读取和写入清单中列出的外部存储空间。我的目标是SDK 22,这样我就不必实现新的Marshmellow权限了。

完整项目也可以在github上下载:https://github.com/jogold9/Simple_Music_Player

1 个答案:

答案 0 :(得分:0)

首先,我发现我添加到手机的SD卡路径不是/ sdcard /而是/ storage / extSdCard /。只有/ storage / extSdCard /上有音乐文件。但是,这两条路径都是我手机上的有效路径。我怀疑/ sdcard /是手机的内部存储空间。

方法getExternalStorageDirectory实际上是在内部SD卡上返回一个位置,这不是我的目标。

其次,我找到了一些允许用户浏览文件夹结构并选择文件夹的代码。我根据自己的喜好定制了代码,经过一些试验和错误后,让它为我工作。

FileDialog.java:

public class FileDialog extends ListActivity {

    private static final String ITEM_KEY = "key";
    private static final String ITEM_IMAGE = "image";
    private static final String ROOT = "/";
    public static final String START_PATH = "START_PATH";
    public static final String FORMAT_FILTER = "FORMAT_FILTER";
    public static final String RESULT_PATH = "RESULT_PATH";
    public static final String SELECTION_MODE = "SELECTION_MODE";
    public static final String CAN_SELECT_DIR = "CAN_SELECT_DIR";

    private List<String> path = null;
    private TextView myPath;
    private EditText mFileName;
    private ArrayList<HashMap<String, Object>> mList;

    private Button selectButton;

    private LinearLayout layoutSelect;
    private LinearLayout layoutCreate;
    private InputMethodManager inputManager;
    private String parentPath;
    private String currentPath = ROOT;
    private String musicFolderPath = "";

    private int selectionMode = SelectionMode.MODE_CREATE;

    private String[] formatFilter = null;

    private boolean canSelectDir = false;

    private File selectedFile;
    private HashMap<String, Integer> lastPositions = new HashMap<String, Integer>();

    /**
     * Sets all inputs and views
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setResult(RESULT_CANCELED, getIntent());

        setContentView(R.layout.file_dialog_main);

        ActionBar bar = getActionBar();
        if (bar != null) {
            bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#3F51B5")));  //sets action bar to color primary dark
        }

        myPath = (TextView) findViewById(R.id.path);
        mFileName = (EditText) findViewById(R.id.fdEditTextFile);

        inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);

        selectButton = (Button) findViewById(R.id.fdButtonSelect);
        selectButton.setEnabled(false);
        selectButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (selectedFile != null) {
                    musicFolderPath = selectedFile.getPath();
                    getIntent().putExtra(RESULT_PATH, musicFolderPath);
                    setResult(RESULT_OK, getIntent());
                    savePrefs("folder", musicFolderPath);
                    Toast.makeText(getApplicationContext(), "You select " + selectedFile.getPath(), Toast.LENGTH_LONG).show();
                    finish();
                }
            }
        });


        selectionMode = getIntent().getIntExtra(SELECTION_MODE, SelectionMode.MODE_CREATE);

        formatFilter = getIntent().getStringArrayExtra(FORMAT_FILTER);

        canSelectDir = getIntent().getBooleanExtra(CAN_SELECT_DIR, false);

        if (selectionMode == SelectionMode.MODE_OPEN) {
            //newButton.setEnabled(false);
        }

        layoutSelect = (LinearLayout) findViewById(R.id.fdLinearLayoutSelect);
        layoutCreate = (LinearLayout) findViewById(R.id.fdLinearLayoutCreate);
        layoutCreate.setVisibility(View.GONE);

        final Button cancelButton = (Button) findViewById(R.id.fdButtonCancel);
        cancelButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View view) {
                setSelectVisible(view);
                finish();
            }

        });

        String startPath = getIntent().getStringExtra(START_PATH);
        startPath = startPath != null ? startPath : ROOT;
        if (canSelectDir) {
            File file = new File(startPath);
            selectedFile = file;
            selectButton.setEnabled(true);
        }
        getDir(startPath);
    }

    private void getDir(String dirPath) {

        boolean useAutoSelection = dirPath.length() < currentPath.length();

        Integer position = lastPositions.get(parentPath);

        getDirImpl(dirPath);

        if (position != null && useAutoSelection) {
            getListView().setSelection(position);
        }

    }

    /**
     * Assembles the structure of files and directories of children provided directory.
     */
    private void getDirImpl(final String dirPath) {

        currentPath = dirPath;

        final List<String> item = new ArrayList<String>();
        path = new ArrayList<String>();
        mList = new ArrayList<HashMap<String, Object>>();

        File myFile = new File(currentPath);
        File[] files = myFile.listFiles();
        if (files == null) {
            currentPath = ROOT;
            myFile = new File(currentPath);
            files = myFile.listFiles();
        }
        myPath.setText(getText(R.string.location) + ": " + currentPath);

        if (!currentPath.equals(ROOT)) {

            item.add(ROOT);
            addItem(ROOT, R.drawable.folder);
            path.add(ROOT);

            item.add("../");
            addItem("../", R.drawable.folder);
            path.add(myFile.getParent());
            parentPath = myFile.getParent();

        }

        TreeMap<String, String> dirsMap = new TreeMap<String, String>();
        TreeMap<String, String> dirsPathMap = new TreeMap<String, String>();
        TreeMap<String, String> filesMap = new TreeMap<String, String>();
        TreeMap<String, String> filesPathMap = new TreeMap<String, String>();
        for (File file : files) {
            if (file.isDirectory()) {
                String dirName = file.getName();
                dirsMap.put(dirName, dirName);
                dirsPathMap.put(dirName, file.getPath());
            } else {
                final String fileName = file.getName();
                final String fileNameLwr = fileName.toLowerCase();

                if (formatFilter != null) {
                    boolean contains = false;
                    for (int i = 0; i < formatFilter.length; i++) {
                        final String formatLower = formatFilter[i].toLowerCase();
                        if (fileNameLwr.endsWith(formatLower)) {
                            contains = true;
                            break;
                        }
                    }
                    if (contains) {
                        filesMap.put(fileName, fileName);
                        filesPathMap.put(fileName, file.getPath());
                    }
                } else {
                    filesMap.put(fileName, fileName);
                    filesPathMap.put(fileName, file.getPath());
                }
            }
        }
        item.addAll(dirsMap.tailMap("").values());
        item.addAll(filesMap.tailMap("").values());
        path.addAll(dirsPathMap.tailMap("").values());
        path.addAll(filesPathMap.tailMap("").values());

        SimpleAdapter fileList = new SimpleAdapter(this, mList, R.layout.file_dialog_row, new String[] {
                ITEM_KEY, ITEM_IMAGE }, new int[] { R.id.fdrowtext, R.id.fdrowimage });

        for (String dir : dirsMap.tailMap("").values()) {
            addItem(dir, R.drawable.folder);
        }

        for (String file : filesMap.tailMap("").values()) {
            addItem(file, R.drawable.file);
        }

        fileList.notifyDataSetChanged();

        setListAdapter(fileList);

    }

    private void addItem(String fileName, int imageId) {
        HashMap<String, Object> item = new HashMap<String, Object>();
        item.put(ITEM_KEY, fileName);
        item.put(ITEM_IMAGE, imageId);
        mList.add(item);
    }

    /**
     * When a list item is clicked 1) If it is a directory, open
     * children; 2) If you can choose directory, define it as the
     * path chosen. 3) If file, defined as the path chosen. 4) Active button for selection.
     */
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {

        File file = new File(path.get(position));

        setSelectVisible(v);

        if (file.isDirectory()) {
            selectButton.setEnabled(false);
            if (file.canRead()) {
                lastPositions.put(currentPath, position);
                getDir(path.get(position));
                if (canSelectDir) {
                    selectedFile = file;
                    v.setSelected(true);
                    selectButton.setEnabled(true);
                }
            } else {
                new AlertDialog.Builder(this).setIcon(R.drawable.icon)
                        .setTitle("[" + file.getName() + "] " + getText(R.string.cant_read_folder))
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        }).show();
            }
        } else {
            selectedFile = file;
            v.setSelected(true);
            selectButton.setEnabled(true);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            selectButton.setEnabled(false);

            if (layoutCreate.getVisibility() == View.VISIBLE) {
                layoutCreate.setVisibility(View.GONE);
                layoutSelect.setVisibility(View.VISIBLE);
            } else {
                if (!currentPath.equals(ROOT)) {
                    getDir(parentPath);
                } else {
                    return super.onKeyDown(keyCode, event);
                }
            }

            return true;
        } else {
            return super.onKeyDown(keyCode, event);
        }
    }

    /**
     * Sets the CREATE button and visibility
     */
    private void setCreateVisible(View v) {
        layoutCreate.setVisibility(View.VISIBLE);
        layoutSelect.setVisibility(View.GONE);

        inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
        selectButton.setEnabled(false);
    }

    /**
     * Sets the button SELECT and visibility
     */
    private void setSelectVisible(View v) {
        layoutCreate.setVisibility(View.GONE);
        layoutSelect.setVisibility(View.VISIBLE);

        inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
        selectButton.setEnabled(false);
    }

    //save prefs
    public void savePrefs(String key, String value){
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, value);
        editor.apply();
    }
}

file_dialog_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/relativeLayout01"
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical" android:layout_width="fill_parent"
                android:layout_height="fill_parent">

    <LinearLayout android:id="@+id/fdLinearLayoutList"
                  android:orientation="vertical" android:layout_width="fill_parent"
                  android:layout_height="wrap_content" android:layout_alignParentBottom="true">

        <LinearLayout android:id="@+id/fdLinearLayoutSelect"
                      android:orientation="vertical" android:layout_width="fill_parent"
                      android:layout_height="wrap_content"
                      android:layout_alignParentBottom="true"  android:paddingBottom="5dp">

            <LinearLayout android:orientation="horizontal"
                          android:layout_width="fill_parent" android:layout_height="fill_parent"
                          android:layout_marginTop="5dp">
                <Button android:id="@+id/fdButtonCancel" android:layout_height="wrap_content"
                        android:layout_width="0dip" android:layout_weight="1"
                        android:background="@color/colorPrimaryDark"
                        android:text="@string/cancel"
                        android:layout_marginRight="5dp"></Button>

                <Button android:id="@+id/fdButtonSelect" android:layout_height="wrap_content"
                        android:layout_width="0dip" android:layout_weight="1"
                        android:background="@color/colorPrimaryDark"
                        android:text="@string/select"></Button>
            </LinearLayout>


        </LinearLayout>



        <LinearLayout android:id="@+id/fdLinearLayoutCreate"
                      android:orientation="vertical" android:layout_width="fill_parent"
                      android:layout_height="wrap_content"
                      android:layout_alignParentBottom="true" android:paddingLeft="10dp"
                      android:paddingRight="10dp" android:paddingBottom="5dp">
            <TextView android:id="@+id/textViewFilename" android:text="@string/file_name"
                      android:layout_width="fill_parent" android:layout_height="wrap_content" />
            <EditText android:text="" android:id="@+id/fdEditTextFile"
                      android:layout_width="fill_parent" android:layout_height="wrap_content"></EditText>


        </LinearLayout>

    </LinearLayout>

    <LinearLayout android:orientation="vertical"
                  android:layout_width="fill_parent" android:layout_height="fill_parent"
                  android:layout_above="@+id/fdLinearLayoutList">
        <TextView android:id="@+id/path" android:layout_width="fill_parent"
                  android:layout_height="wrap_content" />
        <ListView android:id="@android:id/list" android:layout_width="fill_parent"
                  android:layout_height="fill_parent" />
        <TextView android:id="@android:id/empty"
                  android:layout_width="fill_parent" android:layout_height="fill_parent"
                  android:text="@string/no_data" />
    </LinearLayout>
</RelativeLayout>

file_dialog_row.xml:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/list_selector">

    <ImageView
        android:id="@+id/fdrowimage"
        android:layout_width="wrap_content"
        android:layout_height="35dp"
        android:layout_alignParentLeft="true"
        android:paddingLeft="3dp"
        android:paddingRight="5dp"/>

    <TextView
        android:id="@+id/fdrowtext"
        android:layout_width="wrap_content"
        android:layout_height="65dp"
        android:layout_alignBottom="@+id/fdrowimage"
        android:layout_alignTop="@+id/fdrowimage"
        android:layout_toRightOf="@+id/fdrowimage"
        android:gravity="center_vertical"
        android:text="@+id/fdrowtext"
        android:textSize="23sp"/>

</RelativeLayout>