принудительно закрыть на Android Lollipop

код получить музыкальные файлы с SD-карты/музыки и просмотреть список тем

в android 5 происходит принудительное закрытие

думаю проблема в этой функции

ФильтрРасширенияФайла()

package com.ghs.musicsatsametime;

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

public class SongsManager {
    // SDCard Path
    final String MEDIA_PATH = new String("/sdcard/Music");
    private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

    // Constructor
    public SongsManager(){

    }

    /**
     * Function to read all mp3 files from sdcard
     * and store the details in ArrayList
     * */
    public ArrayList<HashMap<String, String>> getPlayList(){
        File home = new File(MEDIA_PATH);

        if (home.listFiles(new FileExtensionFilter()).length > 0) {
            for (File file : home.listFiles(new FileExtensionFilter())) {
                HashMap<String, String> song = new HashMap<String, String>();
                song.put("songTitle", file.getName().substring(0, (file.getName().length() - 4)));
                song.put("songPath", file.getPath());

                // Adding each song to SongList
                songsList.add(song);
            }
        }
        // return songs list array
        return songsList;
    }

    /**
     * Class to filter files which are having .mp3 extension
     * */
    class FileExtensionFilter implements FilenameFilter {
        public boolean accept(File dir, String name) {
            return (name.endsWith(".mp3") || name.endsWith(".MP3"));
        }
    }
}

и мой логкэт

10-30 10:45:30.176: E/AndroidRuntime(15788): FATAL EXCEPTION: main
10-30 10:45:30.176: E/AndroidRuntime(15788): Process: com.ghs.musicsatsametime, PID: 15788
10-30 10:45:30.176: E/AndroidRuntime(15788): java.lang.NullPointerException: Attempt to get length of null array
10-30 10:45:30.176: E/AndroidRuntime(15788):    at com.ghs.musicsatsametime.SongsManager.getPlayList(SongsManager.java:25)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at com.ghs.musicsatsametime.dj.DJMusicFragment.getMusicList(DJMusicFragment.java:421)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at com.ghs.musicsatsametime.dj.DJMusicFragment.access$22(DJMusicFragment.java:415)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at com.ghs.musicsatsametime.dj.DJMusicFragment$7.onClick(DJMusicFragment.java:359)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at android.view.View.performClick(View.java:4856)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at android.view.View$PerformClick.run(View.java:19956)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at android.os.Handler.handleCallback(Handler.java:739)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at android.os.Handler.dispatchMessage(Handler.java:95)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at android.os.Looper.loop(Looper.java:211)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at android.app.ActivityThread.main(ActivityThread.java:5371)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at java.lang.reflect.Method.invoke(Native Method)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at java.lang.reflect.Method.invoke(Method.java:372)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945)
10-30 10:45:30.176: E/AndroidRuntime(15788):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740)

person ghasem sadeghi    schedule 30.10.2015    source источник
comment
Опубликуйте свой логкэт, пожалуйста.   -  person yennsarah    schedule 30.10.2015
comment
Исключение StackTrace было бы полезно   -  person the-ginger-geek    schedule 30.10.2015
comment
Попытка получить длину нулевого массива является ошибкой.   -  person RvdK    schedule 30.10.2015
comment
Просто некоторое улучшение кода, вам не нужно проверять, больше ли длина вашего массива 0, поскольку вы перебираете каждый элемент в своем цикле. Чтобы предотвратить ваш NPE, вы должны проверить, является ли он нулевым.   -  person yennsarah    schedule 30.10.2015
comment
Кроме того, поскольку любой программист должен уметь анализировать стек вызовов, а не просто обращаться за помощью по поводу этой конкретной ошибки и способов ее решения, вам следует на самом деле посмотреть в свой журнал и попытаться понять что происходит и почему. Как видите, стеки вызовов очень информативны, указывая номер строки, в которой произошла ошибка, и в чем заключалась проблема (в данном случае попытка вызвать length() для нулевого экземпляра массива).   -  person JHH    schedule 30.10.2015
comment
О, и, пожалуйста, постарайтесь быть более информативным в описаниях проблем. Заголовок, близкий к леденцу, может применяться практически к миллионам различных ошибок программирования, он ничего не говорит о вашей конкретной проблеме.   -  person JHH    schedule 30.10.2015


Ответы (5)


Вы добавили следующее разрешение в свой AndroidManifest.xml?

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

Для просмотра списка файлов в каталоге требуется доступ для чтения к внешнему хранилищу.

person the-ginger-geek    schedule 30.10.2015

Ваша переменная home равна нулю.

Получает список файлов в каталоге, представленном этим файлом. Затем этот список фильтруется с помощью FileFilter, и соответствующие файлы возвращаются в виде массива файлов. Возвращает значение null, если этот файл не является каталогом. Если фильтр равен нулю, то все файлы совпадают.

См. здесь: Вызов исключения нулевого указателя в Android

Мое первое предположение: у вас нет никаких разрешений.

person RvdK    schedule 30.10.2015

ИМО, вы должны попробовать это: поместите папку «Музыка» в память телефона («Хранилище устройства»). Журнал показал, что ваш путь к файлу неверен, поэтому listFiles() возвращает null

final String MEDIA_PATH = Environment.getExternalStorageDirectory() + "/Music/");
person linhtruong    schedule 30.10.2015

На основании вашего журнала, в котором говорится:

 java.lang.NullPointerException: Attempt to get length of null array

Я нашел эту строку в вашем коде:

 if (home.listFiles(new FileExtensionFilter()).length > 0) {

Методы listFiles() возвращают нулевой массив. Он не был инициализирован или выделен. Таким образом, я предполагаю, что небольшая защита в этой строке поможет этому сбою:

 List<File> files = home.listFiles(new FileExtensionFilter());
 if (null != files && files.length > 0) {
    for(File file:files){
       ...
     }
 }

эта строка предотвратит сбой кода, но я не знаю, возвращает ли эта строка правильный массив, который вам нужен. Этот сбой произошел, когда по этому пути нет файла?

обновление: спасибо за предложение @JHH

person John Feng    schedule 30.10.2015
comment
И ответ @Neil также является очень важной частью, которую необходимо проверить. - person John Feng; 30.10.2015
comment
Не очень эффективно запускать код дважды и создавать два объекта фильтра. В этом случае лучше было бы объявить и присвоить локальной переменной значение listFiles(), затем проверить значение null и длину. - person JHH; 30.10.2015

Спасибо всем

проблема решена

я изменил

home.listFiles(new FileExtensionFilter()).length > 0

to

home.listFiles(new FileExtensionFilter()).length != 0
person ghasem sadeghi    schedule 30.10.2015