Je joue un son d'alarme dans mon application. Sur la plupart des appareils, cela fonctionne parfaitement. Certains utilisateurs ont décrit qu'aucun son ne joue. Cela semble affecter principalement les appareils Samsung et Huawei. Ceci est un exemple minimal de l'endroit où les choses échouent:READ_EXTERNAL_STORAGE autorisation nécessaire pour ouvrir le contenu: // media/external/[...] dans MediaPlayer?
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);
}
Pour les utilisateurs concernés, l'exception suivante est levée:
Exception java.io.IOException: setDataSource échoué .: status = 0x80000000
Cela semble se produire uniquement lorsque alarmURI ressemble à ceci: content://media/external/audio/media/11
, c'est-à-dire qu'il réside sur un magasin externe. Je ne l'ai jamais vu se produire quand alarmURI regarde ceci ceci content://media/internal/audio/media/40
.
Ai-je besoin de l'autorisation READ_EXTERNAL_STORAGE
pour jouer le son, si l'Uri I contient la partie /external/
? Ou est-ce que je manque quelque chose d'autre? Normalement, je m'attendrais à une exception SecurityException, si l'autorisation était le problème.
/e: Je pourrais reproduire le bug sur mon appareil. Voici un rapport d'erreur plus détaillé:
Exception java.lang.SecurityException: Permission refusée: lecture com.android.providers.media.MediaProvider uri contenu: // media/externe/audio/médias de pid = 27158, uid = 10177 nécessite android.permission.READ_EXTERNAL_STORAGE ou grantUriPermission()
Merci pour votre réponse. C'était vraiment perspicace. J'ai commencé à lire sur tous les sujets que vous avez mentionnés. En outre, j'ai réussi à reproduire l'erreur et a également été en mesure de le résoudre. Demander l'autorisation READ_EXTERNAL_STORAGE le résout. Cependant, j'aimerais utiliser le moins d'autorisations possible. Par conséquent, j'ai essayé de chercher comment implémenter les permissions dynamiques de l'uri, mais je n'ai pas été capable de le comprendre. Il y a deux façons de recevoir l'uri: – mc51
1. RingtoneManager.getActualDefaultRingtoneUri() et 2. Intention intention = new Intent (RingtoneManager.ACTION_RINGTONE_PICKER); Les documents de RingtoneManager ne mentionnent pas les autorisations dynamiques. Donc, je ne sais pas vraiment comment commencer ... – mc51
@ mc51 Aucun document ne mentionne explicitement les permissions dynamiques (à part les docs des méthodes pertinentes elles-mêmes), car les autorisations dynamiques n'existaient pas lorsque le système ContentProvider a été créé. Ils ont été introduits dans les versions ultérieures d'Android. Lorsque vous utilisez le sélecteur Intent, appelez 'takePersistableUriPermission' après avoir reçu un Uri. Pas sûr, comment faire face à 'getActualDefaultRingtoneUri', vous voudrez peut-être regarder, comment diverses applications open source l'utilisent. – user1643723