简体   繁体   中英

Can't read mp3 files Android using Java

This is the MainActivity.java:

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

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

        Dexter.withContext(this)
                .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
                .withListener(new PermissionListener() {
                    @Override
                    public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
                        ArrayList<File> songs = fetchSongs(Environment.getExternalStorageDirectory());
                        String[] items = new String [songs.size()];

                        for (int i = 0; i < songs.size(); i++) {
                            items[i] = songs.get(i).getName().replace(".mp3", "");
                        }

                        ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, items);
                        ListView listView = findViewById(R.id.listView);
                        listView.setAdapter(adapter);
                    }

                    @Override
                    public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {}

                    @Override
                    public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
                        permissionToken.continuePermissionRequest();
                    }
                })
                .check();
    }

    public ArrayList<File> fetchSongs (File file) {
        ArrayList arrayList = new ArrayList();
        File [] songs = file.listFiles();

        if (songs != null) {
            for (File song : songs) {
                if (song.isDirectory() && !song.isHidden()) {
                    arrayList.addAll(fetchSongs(song));
                } else {
                    if (song.getName().endsWith(".mp3") && !song.getName().startsWith(".")) {
                        arrayList.add(song);
                    }
                }
            }
        }

        return arrayList;
    }
}

FYI I am running this on a Physical Device which has Android 10.

The 'file' parameter in public ArrayList<File> fetchSongs (File file) function is not null and is a Directory but in the same Function if I run file.listFiles() that returns null.

I do have two mp3 files downloaded.

My AndroidManifest.xml File has declared the permission to Read External Storage: <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

I don't know if this only works if you have if (if (songs.= null)songs != null)an external SD card on your Device but I am running this on my Device's own Storage.

Edit: When I ran this on another Physical Device which had Android 9 It ran perfectly.

Any Help is much Appreciated. Thank You

Try adding this inside the <application> tag in AndroidManifest.xml:

android:requestLegacyExternalStorage="true"

In Android 10 and higher, they changed how external storage works (scoped storage), and this code snippet allows you to revert back to the legacy storage APIs in order to have full access to external storage

UPDATE: for Android 11 and later, either use the MediaStore API or use the getExternalFilesDirs() for your app-specific directory (please note that you will need to move songs from the external storage directory to the app-specific directory), the app specific directory is like below:

Android/data/com.companyname.appname

But for Android 10 (API level 29) compatibility, you could surround the file fetching code with an API level check, if the level is 30 and higher (Android 11 and higher) then use getExternalFilesDirs() , else use the legacy storage APIs

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