简体   繁体   中英

How can I find all .mp3 files stored on the internal storage of my phone?

I'm working on an android app, an mp3 player to be precise, and I would like to add all the.mp3 files it can find on the phone to the library. The problem is that it seems like the android app gets installed in a strange folder (I am unable to find the folder on my phone) and only searches files in that folder. In my AndroidManifest file, I added this line of code to ask for permissions and it works fine:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

I also tried to emulate the app on Android studio and I noticed that the app got located in a folder like /storage/emulated/0 and it only searched for files in that directory. This is my method to search for files:

    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;
    }

And this is the function to display the songs in a list:

    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));
            }
        });
    }

The songs get listed like this and when you click on them the player opens and starts playing the song:

歌曲如何在应用程序上列出的屏幕截图

I'm new at all this, but what the method should do is search through all files in the phone's storage and add to the list those who end with either.mp3 or.wav. Any help, explanation, and/or feedback is highly appreciated. If you need some more information I will be happy to share it with you.

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;
}

If you look at the second code snippet I have in the answer, you can see that I tell the app to search in a Directory by using a deprecated Function:

 final ArrayList<File> mySongs = findSong(Environment.getExternalStorageDirectory());

Environment.getExternalStorageDirectory() is deprecated in API level 29. Now I didn't notice it because the API I am using is 23 and there was no error while trying the app in the emulator. But when I tried it on my Samsung s9 there was obviously a problem because the API there is definitely higher. Luckily I found a very easy fix. It's probably neither the best nor the most efficient, all I'm saying is that it worked for me: Just add the following line in your Manifest file in the application-tag:

android:requestLegacyExternalStorage="true"

What it does is somehow give external storage permissions on newer devices too. I don't know exactly how it works. I'm gonna leave this here because maybe in the future it might help someone else too.

using 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();
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM