我有一个名为SongsManager的java类,它应该能够找到SD卡上的所有音频文件。不幸的是,我无法使用此代码找到任何音频文件。
在我的手机上,我在以下位置有多个.mp3和.wma文件供测试:
目前我在代码中使用以下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
答案 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>