android Mediaplayer NPE 在存储中的文件上,但不在系统文件中

android Mediaplayer NPE on files in storage but not in system files

提问人:M. D. 提问时间:9/16/2022 最后编辑:M. D. 更新时间:9/16/2022 访问量:66

问:

我做了一个简单的媒体播放器安卓应用程序,但我有一个错误:

uri = Uri.parse(/data/hw_init/hw_product/media/Pre-loaded/Music/Beijing_Bass.mp3);

MediaPlayer.create(getApplicationContext(), uri).start();

工作正常

uri = Uri.parse(/storage/emulated/0/Download/Beijing_Bass.mp3);

MediaPlayer.create(getApplicationContext(), uri).start();

不起作用!(空指针异常)

在我的MainActivity上,这是我请求权限的方式:

//ask for permission for read and write external storage
private void permission(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        } else {
            Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
            musicFiles = getAllAudioFromDevice(this);
        }
    }
}

// on permission granted find all music files and add them to the list
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            permission();
        } else {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
    }
}

在我的清单中:

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

你能帮我理解我的错误吗?

多谢

编辑:这就是我得到我的uri的方式:

public static ArrayList<MusicFiles> getAllAudioFromDevice(final MainActivity mainActivity) {
    ArrayList<MusicFiles> tempAudioList = new ArrayList<>();
    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    String[] projection = {
            MediaStore.Audio.Media.ALBUM,
            MediaStore.Audio.Media.ARTIST,
            MediaStore.Audio.Media.DURATION,
            MediaStore.Audio.Media.DATA, // for path
            MediaStore.Audio.Media.DISPLAY_NAME,
            MediaStore.Audio.Media.TITLE,
            MediaStore.Audio.Media._ID
    };
    Cursor cursor = mainActivity.getContentResolver().query(uri, projection, null, null, null);
    if (cursor != null) {
        while (cursor.moveToNext()) {
            String album = cursor.getString(0);
            String artist = cursor.getString(1);
            String duration = cursor.getString(2);
            String path = cursor.getString(3);
            String displayName = cursor.getString(4);
            String title = cursor.getString(5);
            String id = cursor.getString(6);

            MusicFiles musicFilesTemp = new MusicFiles(path, title, artist, album, duration, displayName, id);
            Log.e("Music","Path : " + path +" Album : " + album );
            tempAudioList.add(musicFilesTemp);
        }
        cursor.close();
    }
    Log.e("Music","search complete");
    return tempAudioList;
}

然后这就是我真正启动我的媒体播放器的方式:

private void getIntentMethod() {
        position = getIntent().getIntExtra("position", -1);
        listSongs = musicFiles;
        if (listSongs != null) {
            playPauseBtn.setImageResource(R.drawable.ic_pause);
            uri = Uri.parse(listSongs.get(position).getPath());
        }
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            Log.e("Music","Media Player released");
        }

        mediaPlayer = MediaPlayer.create(getApplicationContext(), uri);
        Log.e("Music",uri.toString());

        if (mediaPlayer != null) {
            mediaPlayer.start();
            seekBar.setMax(mediaPlayer.getDuration() / 1000);
            duration_total.setText(formattedTime(mediaPlayer.getDuration() / 1000));
            song_name.setText(listSongs.get(position).getTitle());
            artist_name.setText(listSongs.get(position).getArtist());
            metaData(uri);
        } else {
            Log.e("Media Player", "Media Player is null");
        }

多亏了 logcat,我检测到只有当我的 uri 以“/storage/...”开头时才会发生 NPE 问题。当它以“/data/...”开头时,它可以正常工作。

java android-studio nullpointerexception android-mediaplayer

评论

0赞 blackapps 9/16/2022
你从哪里得到第一条路?您的设备是否扎根?
0赞 blackapps 9/16/2022
对于这两个路径,请在开始之前尝试 File.exists() 和 File.canRead()。
0赞 CommonsWare 9/16/2022
前两个代码片段都不会编译。除此之外,硬编码路径将不可靠。而且,即使您的第二个代码段的硬编码路径可能有效,您也无法在 Android 11+ 上读取该内容,除非您的应用自行下载并创建了该文件。
1赞 blackapps 9/16/2022
从提取路径的媒体存储中获取 URI。然后,为路径创建新的 URI。这没有道理。直接使用媒体存储中的 uri。mediastore uries 可在 geturiwithappendedid() (或类似的东西)下找到。
1赞 blackapps 9/16/2022
new MusicFiles(path, 删除路径字段,或者如果保留它,请添加 uri 字段。然后在回收视图中使用 uri,而不是为 path 创建 uri。

答:

0赞 M. D. 9/16/2022 #1

使用 https://developer.android.com/guide/topics/media/mediaplayer#java 中的这段代码进行调试

long id = /* retrieve it from somewhere */;
Uri contentUri = ContentUris.withAppendedId(
        android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);

mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
    new AudioAttributes.Builder()
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
        .setUsage(AudioAttributes.USAGE_MEDIA)
        .build()
);
mediaPlayer.setDataSource(getApplicationContext(), contentUri);

// ...prepare and start...

非常感谢 BlackApps