我在我的应用程序中播放闹钟声音。在大多数设备上,这个工作完美无瑕。有些用户描述说没有声音在播放。这似乎主要影响三星和华为设备。这是那里的东西不能小例子:READ_EXTERNAL_STORAGE权限需要在MediaPlayer中打开content:// media/external/[...]?
alarmUri = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
try {
if(!mediaPlayer.isPlaying()) {
mediaPlayer.setDataSource(this, alarmUri);
AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
mediaPlayer.setAudioStreamType(audioManager.STREAM_ALARM);
mediaPlayer.setLooping(true);
mediaPlayer.prepare();
mediaPlayer.start();
}
} catch(Exception e) {
Log.d(logtag,"Exception: " + e);
}
对于受影响的用户,下面的异常被抛出:
异常java.io.IOException的:失败的setDataSource: 状态= 0x80000000的
这似乎只发生在alarmURI如下所示:content://media/external/audio/media/11
,即它驻留在外部存储上。当alarmURI看起来这是content://media/internal/audio/media/40
时,我从未见过它发生。
为了播放声音,我需要READ_EXTERNAL_STORAGE
权限吗?如果我使用的Uri包含/external/
部分?还是我错过了别的?通常,如果权限是问题,我会期望抛出SecurityException。
/电子邮件:我可以重现我的设备上的错误。这里有一个更详细的错误报告:
异常java.lang.SecurityException异常:权限拒绝:从PID //媒体/外部/音频/媒体:阅读 com.android.providers.media.MediaProvider URI 内容= 27158,UID = 10177 需要android.permission.READ_EXTERNAL_STORAGE,或 grantUriPermission()
谢谢您的回答什么。这真的很有见地。我已经开始阅读你提到的所有主题。此外,我成功地重现了错误,并且还能够解决它。请求READ_EXTERNAL_STORAGE权限解决它。但是,我想尽可能少地使用权限。因此,我试图查找如何实现动态的uri权限,但我无法弄清楚。有两种方法可以接收URI: – mc51
1. RingtoneManager.getActualDefaultRingtoneUri()和2. Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); RingtoneManager的文档没有提及动态权限。因此,我现在真的不会如何开始...... – mc51
@ mc51没有文档明确提到动态权限(除了相关方法本身的文档),因为在创建ContentProvider系统时不存在动态权限。它们在Android的更高版本中引入。当你使用选择器Intent时,在收到Uri后调用'takePersistableUriPermission'。不知道,如何处理'getActualDefaultRingtoneUri',你可能想看看,各种开源应用程序如何使用它。 – user1643723