Список содержимого папки на SDCard

Я пытаюсь отобразить mp3 файлы в определенной папке на sdcard/myaudioЯ нашел этот пример:

Как вывести список всех файлов и папок, находящихся на SD-карте

Я пишу имя и папку SDCard в первом методе, но приложение падает

это то, что я сделал до сих пор

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    myList = new ArrayList<String>();

    String root_sd = Environment.getExternalStorageDirectory().toString();
    file = new File(root_sd + "/sdcard/myaudio");
    File list[] = file.listFiles();

    for (int i = 0; i < list.length; i++) {
        myList.add(list[i].getName());
    }

    setListAdapter(new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, myList));

}

Пожалуйста, помогите.

Обновить

public class MainActivity extends ListActivity {
private File file;
String root_sd = Environment.getExternalStorageDirectory().toString();
ArrayList<String> myList = new ArrayList<String>();

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    checkAndCreateDirectory();

    if (ActivityCompat.checkSelfPermission(this,
            android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
        fillList();
    } else {
        ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
    }
}

private void fillList() {
    String root_sd = Environment.getExternalStorageDirectory().toString();
    File file = new File(root_sd + "/sdcard/myaudio");
    File list[] = file.listFiles();

    for (int i = 0; i < list.length; i++) {
        myList.add(list[i].getName());
    }

    setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myList));
}

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

    if (requestCode == 100) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                fillList();
            }
        }
    }
}

private void checkAndCreateDirectory() {
}

public void checkAndCreateDirectory(String dirName){
    File new_dir = new File( root_sd + "/sdcard/myaudio/" );
    if( !new_dir.exists() ){
        new_dir.mkdirs();
    }
}

protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    File temp_file = new File(file, myList.get(position));

    if (!temp_file.isFile()) {
        file = new File(file, myList.get(position));
        File list[] = file.listFiles();

        myList.clear();

        for (int i = 0; i < list.length; i++) {
            myList.add(list[i].getName());
        }
        Toast.makeText(getApplicationContext(), file.toString(), Toast.LENGTH_LONG).show();
        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, myList));
    }
}

@Override
public void onBackPressed() {
    String parent = file.getParent().toString();
    file = new File(parent);
    File list[] = file.listFiles();

    myList.clear();

    for (int i = 0; i < list.length; i++) {
        myList.add(list[i].getName());
    }
    Toast.makeText(getApplicationContext(), parent, Toast.LENGTH_LONG).show();
    setListAdapter(new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, myList));
}

}

2 ответа

Похоже, что ваше приложение не имеет разрешения на чтение из внешнего хранилища.
Напишите это:

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

как раз перед <application тег в вашем manifest.xml
Поместите эту декларацию:

ArrayList<String> myList = new ArrayList<String>();

вместо внутри onCreate() на уровне класса (до onCreate()) сделать его видимым в любом месте вашего класса активности.
Создайте этот метод:

private void fillList() {
    String root_sd = Environment.getExternalStorageDirectory().toString();
    File file = new File(root_sd + "/datanfile");
    File list[] = file.listFiles();

    for (int i = 0; i < list.length; i++) {
        myList.add(list[i].getName());
    }

    setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myList));       
}

И в onCreate() иметь только этот код:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // setContentView(R.layout.activity_main);  ???????
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
        fillList();
    } else {
        ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
    }
}

Таким образом, ваше приложение будет запрашивать необходимое разрешение, если оно еще не предоставлено.
Теперь вы получите, предоставил ли пользователь это разрешение, переопределив onRequestPermissionsResult():

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

    if (requestCode == 100) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                fillList();
            }
        }
    }
}

Вышеуказанный метод вызывается после того, как пользователь принял или не разрешил вашему приложению разрешение.
Так fillList() будет выполнено, если ваше приложение уже имеет разрешение или после того, как пользователь предоставит разрешение. Он не будет выполнен, если пользователь не предоставит разрешение.
редактировать
в onCreate() метода вы разместили нет setContentView(), Зачем?
Edit2
В вашем коде у вас есть:

private void checkAndCreateDirectory() {
}

public void checkAndCreateDirectory(String dirName){
    File new_dir = new File( root_sd + "/sdcard/myaudio/" );
    if( !new_dir.exists() ){
        new_dir.mkdirs();
    }
}

Удалить 1-й и удалить String dirName со 2-го

Ваш file.listFiles(); может быть нулевым Это может произойти из-за пустой папки или конкретной папки там нет.

Вы можете использовать метод ниже, чтобы проверить, если папка уже там, в противном случае создайте ее.

 public void checkAndCreateDirectory(String dirName){
        File new_dir = new File( rootDir + dirName );
        if( !new_dir.exists() ){
             new_dir.mkdirs();
        }
    }

вы можете избежать сбоя, когда папка пуста, добавив следующую нулевую проверку

File list[] = file.listFiles(); 
if(list == null) return;
Другие вопросы по тегам