使用 MediaPlayer 在 android 上播放默认铃声时出现非法状态异常和权限问题

Illegal State Exception and Permissions issue when playing default ringtone on android using MediaPlayer

我已经查看了有关此主题的所有其他帖子,但我已经尝试了所有这些帖子,但都无济于事。我真的只是想循环播放当前的铃声,如果有更简单的方法,请告诉我。

这是我当前的代码:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    try {
        player.setDataSource(this, Settings.System.DEFAULT_RINGTONE_URI);
    } catch (IOException e) {
        e.printStackTrace();
    }
    player.setOnPreparedListener(this);
    player.prepareAsync();                                // this is Line 34
    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
    return START_STICKY;
}

@Override
public void onPrepared(MediaPlayer mediaPlayer) {
    player.setLooping(true);
    player.start();
}

我尝试的一切都给我错误:

Caused by: java.lang.IllegalStateException
                  at android.media.MediaPlayer.prepareAsync(Native Method)
                  at com.package.MainService.onStartCommand(MainService.java:34)
                  at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3688)

如果我在我的 /res/raw 文件夹中给它一个 mp3,媒体播放器工作正常。

我刚刚进一步阅读了控制台,它说:

Couldn't open content://media/external/audio/media/738: 
java.lang.SecurityException: Permission Denial: reading 
com.android.providers.media.MediaProvider uri 
content://media/external/audio/media/738 from pid=24931, uid=10295 requires 
android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
D/MediaPlayer: setDataSource IOException | SecurityException happend : 
           java.lang.SecurityException: Permission Denial: reading 
com.android.providers.media.MediaProvider uri 
content://media/external/audio/media/738 from pid=24931, uid=10295 requires 
android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()

更新

我刚刚向清单添加了权限,但问题仍然存在:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.package">

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

感谢任何帮助!

您需要添加运行时权限才能从 URI 读取媒体文件。

来自Documnetation

在您的 Activity 中添加此代码以获得运行时权限:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_EXTERNAL_STORAGE)) {

        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                1);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}