Get list of mp3 files from assets folder and save in shared preference

278 views Asked by At

I have an app in which I have some mp3 sounds in the assets folder. At the start of the app, I am getting the list of files and copy all files from assets to getExternalFilesDir(). Invoke the media scanner for every file and only if the media scanner comes back with an URI then write something in shared preferences

 private void copyAssets() {
    AssetManager assetManager = getAssets();
    String[] files = null;
    try {
        files = assetManager.list("");
    } catch (IOException e) {
        Log.e("tag", "Failed to get asset file list.", e);
    }
    if (files != null) for (String filename : files) {
        InputStream in = null;
        OutputStream out = null;
        try {
            in = assetManager.open(filename);
            File outFile = new File(getExternalFilesDir(null), filename);
            out = new FileOutputStream(outFile);
            copyFile(in, out);

            MediaScannerConnection.scanFile(this,
                    new String[] { outFile.getAbsolutePath() }, null,
                    new MediaScannerConnection.OnScanCompletedListener() {
                        public void onScanCompleted(String contentPath, Uri uri) {
                            Log.i("onScanCompleted", uri.toString());
                            RingtoneSoundChooserFragment.path = uri.toString();
                            SharedPreferences sharedPreferences = getSharedPreferences("songs_uri",Context.MODE_PRIVATE);
                            SharedPreferences.Editor editor = sharedPreferences.edit();
                            editor.putString(filename,uri.toString());
                            editor.apply();
                        }
                    });


        } catch(IOException e) {
            Log.e("tag", "Failed to copy asset file: " + filename, e);
        }
        finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
        }
    }
}

In the fragment where I want to load these sounds and play, I have written the below code in my fragment class named 'RingtoneSoundChooserFragment'

  List<SoundData> sounds = new ArrayList<>();
    SharedPreferences sharedPreferences = getContext().getSharedPreferences("songs_uri",Context.MODE_PRIVATE);


    sounds.add(new SoundData("Shukran", SoundData.TYPE_RINGTONE,sharedPreferences.getString("shukran.mp3","null")));
    sounds.add(new SoundData("My Shortcomings", SoundData.TYPE_RINGTONE,sharedPreferences.getString("my_shortcomings.mp3","null")));
    sounds.add(new SoundData("Need the Love", SoundData.TYPE_RINGTONE,sharedPreferences.getString("need_the_love.mp3","null")));
    sounds.add(new SoundData("La", SoundData.TYPE_RINGTONE,sharedPreferences.getString("la_ilaha_illallah.mp3","null")));
    sounds.add(new SoundData("ma", SoundData.TYPE_RINGTONE,sharedPreferences.getString("subhanallah.mp3","null")));
    sounds.add(new SoundData("Qal", SoundData.TYPE_RINGTONE,sharedPreferences.getString("baydh.mp3","null")));
    sounds.add(new SoundData("Be Yourself", SoundData.TYPE_RINGTONE,sharedPreferences.getString("be_yourself.mp3","null")));
    sounds.add(new SoundData("Jamal Ul-Wujoodi", SoundData.TYPE_RINGTONE,sharedPreferences.getString("jamal_ul_wujoodi.mp3","null")));
    sounds.add(new SoundData("Yan", SoundData.TYPE_RINGTONE,sharedPreferences.getString("ya.mp3","null")));
    sounds.add(new SoundData("Kun", SoundData.TYPE_RINGTONE,sharedPreferences.getString("kun.mp3","null")));
    sounds.add(new SoundData("Day", SoundData.TYPE_RINGTONE,sharedPreferences.getString("eid.mp3","null")));
    sounds.add(new SoundData("Sharab", SoundData.TYPE_RINGTONE,sharedPreferences.getString("sharab.mp3","null")));
    sounds.add(new SoundData("Ao", SoundData.TYPE_RINGTONE,sharedPreferences.getString("thirteen.mp3","null")));
    sounds.add(new SoundData("Hoyoo", SoundData.TYPE_RINGTONE,sharedPreferences.getString("hoyoo.mp3","null")));
    sounds.add(new SoundData("Yapo", SoundData.TYPE_RINGTONE,sharedPreferences.getString("fifteen.mp3","null")));
    sounds.add(new SoundData("mi", SoundData.TYPE_RINGTONE,sharedPreferences.getString("sixteen.mp3","null")));
    sounds.add(new SoundData("io", SoundData.TYPE_RINGTONE,sharedPreferences.getString("seventeen.mp3","null")));

    SoundsAdapter adapter = new SoundsAdapter(getAlarmio(), sounds);
    adapter.setListener(this);
    recyclerView.setAdapter(adapter);

I have the adapter screen with a play button and when I want to play the sound I tap on the play button. But the issue is that in some android devices the sound shows beep beep beep and not the actual sound. however in some devices, it remains completely silent and in some devices, it plays the sound perfectly. The issue is also in android 10 but its happening on random devices. Some play the sound perfectly and some stay silent or beep. What I am missing or what is wrong with my code? Please help

1

There are 1 answers

6
blackapps On

The media scanner will not index files in your apps private directory. Not from getExternalFilesDir() anymore.

But you do not need the media scanner to get an uri or to save info in shared preferences.

Just take a FileProvider to serve your files.

An alternative is to directly copy the files to the media store. Then you will have nice media store uries and your files are scanned too.

A third possibility is to take your own ContentProvider and serve your files directly from assets. No need to copy first.