[英]How can I find all .mp3 files stored on the internal storage of my phone?
我正在開發一個 android 應用程序,准確地說是一個 mp3 播放器,我想將它可以在手機上找到的所有 .mp3 文件添加到庫中。 問題是 android 應用程序似乎安裝在一個奇怪的文件夾中(我無法在手機上找到該文件夾)並且只搜索該文件夾中的文件。 在我的 AndroidManifest 文件中,我添加了這行代碼來請求權限,它工作正常:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
我還嘗試在 Android 工作室上模擬該應用程序,我注意到該應用程序位於/storage/emulated/0之類的文件夾中,它只搜索該目錄中的文件。 這是我搜索文件的方法:
public ArrayList<File> findSong (File file) {
ArrayList<File> arrayList = new ArrayList<>();
File[] files = file.listFiles();
if (files != null) {
for (File singlefile : files) {
if (singlefile.isDirectory() && !singlefile.isHidden()) {
arrayList.addAll(findSong(singlefile));
} else {
if (singlefile.getName().endsWith(".mp3") || singlefile.getName().endsWith(".wav")) {
arrayList.add(singlefile);
}
}
}
}
return arrayList;
}
這是 function 在列表中顯示歌曲:
void displaySongs() {
final ArrayList<File> mySongs = findSong(Environment.getExternalStorageDirectory());
items = new String[mySongs.size()];
for (int i = 0; i<mySongs.size(); i++) {
items[i] = mySongs.get(i).getName().toString().replace(".mp3", "")
.replace(".wav", "");
}
/*
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
listView.setAdapter(myAdapter);
*/
customAdapter customAdapter = new customAdapter();
listView.setAdapter(customAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String songName = (String) listView.getItemAtPosition(position);
startActivity(new Intent(getApplicationContext(), PlayerActivity.class)
.putExtra("songs", mySongs)
.putExtra("songname", songName)
.putExtra("pos", position));
}
});
}
歌曲會這樣列出,當您單擊它們時,播放器會打開並開始播放歌曲:
我是新手,但是該方法應該做的是搜索手機存儲中的所有文件,並將以.mp3 或.wav 結尾的文件添加到列表中。 非常感謝任何幫助、解釋和/或反饋。 如果您需要更多信息,我很樂意與您分享。
public List<AudioModel> getAllAudioFromDevice(final Context context) {
final List<AudioModel> tempAudioList = new ArrayList<>();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.AudioColumns.TITLE, MediaStore.Audio.AudioColumns.ALBUM,
MediaStore.Audio.ArtistColumns.ARTIST,};
// if want from specific folder
Cursor c = context.getContentResolver().query(uri, projection, MediaStore.Audio.Media.DATA + " like ? ", new String[]{"%utm%"}, null);
// if want fetch all files
Cursor c = context.getContentResolver().query(uri,
projection,
null,
null,
null);
if (c != null) {
while (c.moveToNext()) {
AudioModel audioModel = new AudioModel();
String path = c.getString(0);
String name = c.getString(1);
String album = c.getString(2);
String artist = c.getString(3);
audioModel.setaName(name);
audioModel.setaAlbum(album);
audioModel.setaArtist(artist);
audioModel.setaPath(path);
Log.e("Name :" + name, " Album :" + album);
Log.e("Path :" + path, " Artist :" + artist);
tempAudioList.add(audioModel);
}
c.close();
}
return tempAudioList;
}
如果您查看我在答案中的第二個代碼片段,您會看到我告訴應用程序使用已棄用的 Function 在目錄中搜索:
final ArrayList<File> mySongs = findSong(Environment.getExternalStorageDirectory());
Environment.getExternalStorageDirectory()在 API 級別 29 中已棄用。現在我沒有注意到它,因為我使用的 API 是 23 並且在模擬器中嘗試應用程序時沒有錯誤。 但是當我在我的三星 s9 上嘗試它時,顯然存在問題,因為 API 肯定更高。 幸運的是,我找到了一個非常簡單的解決方法。 它可能既不是最好的也不是最有效的,我只想說它對我有用:只需在應用程序標簽的清單文件中添加以下行:
android:requestLegacyExternalStorage="true"
它的作用是以某種方式在較新的設備上授予外部存儲權限。 我不知道它是如何工作的。 我會把它留在這里,因為也許將來它也可以幫助其他人。
使用 MediaStore.Audio
private void lodfrmdvic() {
linearlayout.removeAllViews();//clear albums or favs or ondevic
//LinearLayout linearlayout = (LinearLayout) findViewById(R.id.linearlayout);
dataaray = new ArrayList<>();
titlaray = new ArrayList<>();
albmaray = new ArrayList<>();
artstaray = new ArrayList<>();
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
final Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);
if (cursor != null && cursor.getCount() > 0) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.weight = 1.0f;//params.gravity = Gravity.END;
while (cursor.moveToNext()) {
final int curndx =cursor.getPosition();
/** when using cursor.getPosition() make failre becase it set in title.setOnClickListener the last valu(cursor Counts)
using int or string then insert it in title.setOnClickListener solve problem */
final String dsnam = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));//title+extion
final String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
//final String titl = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
final String titl = dsnam.replace( dsnam.substring(dsnam.lastIndexOf(".")) ,"");//to show titl=filename wthot exton
// Save to arrays
dataaray.add(data);
titlaray.add(titl);
albmaray.add(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)));
artstaray.add(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
LinearLayout mrow = new LinearLayout(this);
mrow.setPadding(0,20,0,20);
TextView title =new TextView(this);
//title.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f));
title.setLayoutParams(params);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {//17
title.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);//for start arabic if app lang is english and vice versa
}
ImageButton mor = new ImageButton(this);
//to short long title
String shrttitl = titl;
if(titl.length()>30){shrttitl=titl.substring(0,30)+"...";}//show till and ltr 30
title.setText(shrttitl);
mrow.addView(title);
//if(Build.VERSION.SDK_INT < 21){mor.setBackground(getResources().getDrawable(R.drawable.ic_baseline_cloud_upload_24));}
//else{mor.setBackground(getDrawable(R.drawable.ic_baseline_cloud_upload_24));}
mor.setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.ic_baseline_cloud_upload_24, getTheme()));
mrow.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {playaudio(curndx);} });
mor.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(Showsonds.this);
// builder.setTitle("del?");
// builder.setCancelable(false);
builder.setMessage(getString(R.string.ad)+" "+titl+" "+getString(R.string.tomyclod))
.setPositiveButton( getString(R.string.yes) , new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { adtomine(data,dsnam,titl); }
})
.setNegativeButton( getString(R.string.cncl) , new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { dialog.cancel(); }
});
AlertDialog dialog = builder.create();
dialog.show();
} });
mrow.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//toast("looooooooong clk");
//todo show >>
toast(titl);
return true;
} });
mrow.addView(mor);
linearlayout.addView(mrow);
}cursor.close();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.