Получить список файлов из каталога Музыка

Дорабатываю приложение и хочу добавить воспроизведение сохраненных аудио. Сохранение происходит следующим образом: Если Android версии 9 или ниже, то сохранение аудио происходит в папку mymusic в корневом каталоге устройства, если версия 10 и новее, то сохранение происходит в папку с музыкой по умолчанию.

Как получить список файлов в зависимости от версии? А именно хотелось бы получить название файлов и полный путь к ним.

Класс Recorder.java

public class Recorder extends AsyncTask {

    private Context context;
    private String urlPath;
    private String recordedFileName;
    private boolean isRecording = false;

    public Recorder() {}

    public Recorder(Context context, String url, String recordedFilePath) {
        this.context = context;
        this.urlPath = url;
        this.recordedFileName = recordedFilePath;
    }

    @Override
    protected Object doInBackground(Object[] objects) {

        isRecording = true;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            try {
                ContentValues values = new ContentValues();
                values.put(MediaStore.Audio.Media.DISPLAY_NAME, recordedFileName);
                values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/*");
                values.put(MediaStore.Audio.Media.IS_PENDING, 1);

                ContentResolver contentResolver = context.getContentResolver();
                Uri collection = MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);

                Uri item = contentResolver.insert(collection, values);

                ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(item, "w", null);

                OutputStream outputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());

                audioWrite(urlPath, outputStream);

                contentResolver.update(item, values, null, null);
                values.clear();
                values.put(MediaStore.Audio.Media.IS_PENDING, 0);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } else {
            try {
                File direct = new File(Environment.getExternalStorageDirectory() + File.separator + AppConstants.dirName);

                if (!direct.exists()) {
                    File musicFolder = new File(Environment.getExternalStorageDirectory() + File.separator + AppConstants.dirName);
                    musicFolder.mkdirs();
                }

                File file = new File(Environment.getExternalStorageDirectory() + File.separator + AppConstants.dirName, recordedFileName);
                System.out.println(file.getAbsoluteFile());
                OutputStream outputStream = new FileOutputStream(file);

                audioWrite(urlPath, outputStream);
            }catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    private void audioWrite(String urlPath, OutputStream outputStream) {
        try {
            URL url = new URL(urlPath);
            InputStream inputStream = url.openStream();

            byte[] buffer = new byte[4*1024];
            int read;
            while ((read = inputStream.read(buffer)) != -1) {
                if(isCancelled())
                    break;
                outputStream.write(buffer,0,read);
            }
            outputStream.flush();
            outputStream.close();
            inputStream.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void record()
    {
        File file = new File(Environment.getExternalStorageDirectory() + File.separator + AppConstants.dirName,recordedFileName);
        if (file.exists()) {
            file.delete();
        }

        this.execute();

    }

    public void stopRecording() {
        isRecording=false;
        this.cancel(true);
    }

    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    public String getUrlPath() {
        return urlPath;
    }

    public void setUrlPath(String urlPath) {
        this.urlPath = urlPath;
    }

    public String getRecordedFileName() {
        return recordedFileName;
    }

    public void setRecordedFileName(String recordedFileName) {
        this.recordedFileName = recordedFileName;
    }

    public boolean isRecording() {
        return isRecording;
    }

    public void setRecording(boolean recording) {
        this.isRecording = recording;
    }

}

Класс PlayerActivity.java

public class PlayerActivity extends AppCompatActivity {

    private String audioUrl;
    private String audioImg;
    private String audioTitle;
    private int audioID = 0;
    private int audioFav = 0;

    public static boolean isPlay = false;
    ImageButton btnPLayPause;
    private TextView txtaudio;
    private RoundedImageView imgaudio;
    private ImageButton btnStartRecord;
    private ImageButton btnStopRecord;

    private Recorder recorder;
    private String recordedFileName = null;
    private boolean isRecording = false;

    private Chronometer mChronometer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_player);
       
    }

    public void onClickPlay() {
        if (!isPlay) {
            Toast.makeText(this, "Сначала запустите аудио", Toast.LENGTH_SHORT).show();
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                reCreateRecorder();
                Toast.makeText(this, "Запись аудио: " + audioTitle, Toast.LENGTH_SHORT).show();
                recorder.record();
                isRecording = true;
                btnStartRecord.setVisibility(View.GONE);
                layoutTime.setVisibility(View.VISIBLE);
                btnStopRecord.setVisibility(View.VISIBLE);

                mChronometer.setBase(SystemClock.elapsedRealtime());
                mChronometer.start();
            } else {
                int permissionStatus = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

                if (permissionStatus == PackageManager.PERMISSION_GRANTED) {
                    reCreateRecorder();
                    Toast.makeText(this, "Запись аудио: " + audioTitle, Toast.LENGTH_SHORT).show();
                    recorder.record();
                    isRecording = true;
                    btnStartRecord.setVisibility(View.GONE);
                    layoutTime.setVisibility(View.VISIBLE);
                    btnStopRecord.setVisibility(View.VISIBLE);

                    mChronometer.setBase(SystemClock.elapsedRealtime());
                    mChronometer.start();
                } else {
                    ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                            AppConstants.REQUEST_CODE_PERMISSION_WRITE_EXTERNAL_STORAGE);
                    layoutTime.setVisibility(View.GONE);
                }
            }
        }
    }

    public void onClickPause() {
        btnStartRecord.setVisibility(View.VISIBLE);
        layoutTime.setVisibility(View.GONE);
        btnStopRecord.setVisibility(View.GONE);
        recorder.stopRecording();
        isRecording = false;
        mChronometer.stop();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            Toast.makeText(this, "Файл сохранен в папке с аудио", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Файл сохранен в: " + Environment.getExternalStorageDirectory() +
                    File.separator + AppConstants.dirName, Toast.LENGTH_SHORT).show();
        }
        reCreateRecorder();
    }

    public void reCreateRecorder() {
        if (recorder != null) {
            if (recorder.isRecording()) recorder.stopRecording();
            recorder = null;
        }
        recordedFileName = "myaudios-" + Calendar.getInstance().getTimeInMillis()/1000L + ".mp3";
        recorder = new Recorder(this, audioUrl, recordedFileName);
    }


    @Override
    protected void onResume() {
        super.onResume();

        btnStartRecord.setOnClickListener(v -> {
            onClickPlay();
        });

        btnStopRecord.setOnClickListener(v -> {
            onClickPause();
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case AppConstants.REQUEST_CODE_PERMISSION_WRITE_EXTERNAL_STORAGE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    onClickPlay();
                } else {
                    Toast.makeText(this, "Нет доступа к хранилищу!", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    @Override
    public void onBackPressed() {
        if (isRecording) {
            Toast.makeText(this, "Сначала остановите запись!", Toast.LENGTH_SHORT).show();
        } else {
            super.onBackPressed();
        }
    }
}

Класс MyFilesActivity.java

public class MyFilesActivity extends AppCompatActivity {

    private Cursor cursor;
    private List<String> mediaList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_files);

        parseAllAudio();
    }

    private void parseAllAudio() {
        try {
            String TAG = "myaudios";
            Cursor cur = getContentResolver().query(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Audio.Media.DATA+ " like ? ", new String[]{"%" + "myaudios" + "%"}, null,
                    null);

            if (cur == null) {
                Log.e(TAG, "Failed to retrieve music: cursor is null :-(");

            }
            else if (!cur.moveToFirst()) {
                Log.e(TAG, "Failed to move cursor to first row (no query results).");

            }else {
                Log.i(TAG, "Listing...");
                do {
                    mediaList.add(cur.getString(cur.getColumnIndex(MediaStore.Audio.Media.DATA)));

                } while (cur.moveToNext());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        for (String s : mediaList) {
                System.out.println(s + " --------------------------");
        }
    }

}

Ответы (2 шт):

Автор решения: Wlad

Можете попробовать обращаться ко всем аудио-файлам на устройстве, делать из них выборку по "названию" и получать их URI.
в данном примере это music_folder.
т.е. у вас файлы должны иметь что-то общее. например "Wlad_song1.mp3" "Wlad_ringtone.mp3" "recordbyWlad.mp3"
поэтому music_folder = "Wlad" Проблема этого решения, что если у вас есть папка которая содержит "Wlad" - все аудио из нее тоже найдутся.

public void getMp3Songs(Context ctx) {
    ArrayList<String> songsList = new ArrayList<>(); // массив который будет хранить URI на нужные аудио-файлы
    Uri allSongsUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";

        // базовый курсор для ВСЕЙ музыки на телефоне
    // Cursor cursor = ctx.getContentResolver().query(allSongsUri, null, null, null, selection);

        // курсор для выбора музыки из определнной папки    
    Cursor  cursor = ctx.getContentResolver().query(allSongsUri, null, MediaStore.Audio.Media.DATA + " like ? ", new String[]{"%" + music_folder + "%"}, selection);
    // music_folder - часть, которая обязательная должна присутствовать в URI


    if (cursor != null) {
        if (cursor.moveToFirst()) {
            do {
                    // просто добавляем путь к файлу в дин.массив
                songsList.add(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));
//                    Log.e("Koshel Music files", "" + cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));
            } while (cursor.moveToNext());
        }
        cursor.close();
    }
}
→ Ссылка
Автор решения: Наталья Сергеевна

Получилось следующим образом:

private void parseAllAudio() {

    songList = new ArrayList<>();

    ContentResolver resolver = getContentResolver();
    if(resolver!=null) {
        Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null, null, null, null);

        if(cursor!=null) {
            Log.d("TAG", "find "+cursor.getCount()+" hidden folders");
        }

        if (cursor != null && cursor.moveToFirst()) {
            File file;
            do {
                file = new File(cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA)));

                if (file.exists()) {
                    if (file.getAbsolutePath().contains(AppConstants.dirName)) {
                        songList.add(new Song(
                                cursor.getInt(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID))
                                ,cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.TITLE))
                                ,getFileSize(file)
                                ,cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA))
                        ));
                    }
                }
            } while (cursor.moveToNext());
            cursor.close();
        }
    }
}
→ Ссылка