权限授予我试图让一个应用程序从SD卡播放MP3。我在Windows 8上使用Android sdk版本23和Android studio。我在nexus 5模拟器上运行这个。获得FileNotFoundException异常否认后,比在运行时
我请求在运行时允许,我得到一个FileNotFoundException异常,如果我拒绝允许一次,但不是授予对第二个请求的权限。如果我重新启动应用程序,则可以播放音乐文件,如果我在第一次尝试时接受许可请求,它也可以成功播放音乐,而无需重新启动。
我做了一个简单的程序,复制问题并将其发布在github上。您需要/ Music目录中的mp3文件才能运行此应用程序。
这里就是我要求的存储许可代码:
private void CheckPermission() {
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
playSong();
} else {
// we don't have permission, request it
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_EXTERNAL_STORAGE_PERMISSION);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_EXTERNAL_STORAGE_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
Toast.makeText(getApplicationContext(), "Storage access granted, touch screen to start music", Toast.LENGTH_SHORT)
.show();
} else {
// Permission Denied
Toast.makeText(getApplicationContext(), "Storage access denied, can't load music", Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
这里是一个的失败相关的代码片段:
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String projection[] =
{android.provider.MediaStore.Audio.Media.DATA, android.provider.MediaStore.Audio.Media.TITLE};
Cursor cursor = this.getContentResolver().query(uri, projection, null, null, null);
String songURI = new String();
String title = new String();
while (cursor.moveToNext()) {
String data = cursor.getString(0);
title = cursor.getString(1);
// Note: Look for music folder in root drive.
if (data.matches("^/storage/emulated/0/Music/.*")) {
songURI = data;
break;
}
}
if (cursor != null) {
cursor.close();
}
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songURI));
try
{
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.start();
Toast toast = Toast.makeText(getApplicationContext(), title, Toast.LENGTH_SHORT);
toast.show();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return;
}
而这里的堆栈跟踪:
的MediaPlayer:创建失败: java.io.FileNotFoundException:/ storage/emulated/0/Music/108-radiohe card-pms.mp3:open failed:EACCES(Permission denied) at libcore.io.IoBridge.open(IoBridge.java:452) at java.io.FileInputStream。(FileInputStream.java:76) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1095) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1074) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1028) at android .media.MediaPlayer.setDataSource(MediaPlayer.java:973) at android.media.MediaPlayer.create(MediaPlayer.java:880) at android.media.MediaPlayer.create(MediaPlayer.java:857) 在gunboat.com.mediaplayer.create(MediaPlayer.java:836) at gunboat.com.mediaplayererror.FullscreenActivity.playSong(FullscreenActivity.java:190) at gunboat.com.mediaplayererror.FullscreenActivity.CheckPermission(FullscreenActivity.java:135 ) at gunboat.com.mediaplayererror.FullscreenActivity.access $ 300(FullscreenActivity.java:24) at gunboat.com.mediaplayererror.FullscreenActivity $ 5.onClick(FullscreenActivity.java:113) at android.view.View.performClick(View的.java:5198) 在android.view.View $ PerformClick.run(View.java:21147) 在android.os.Handler.handleCallback(Handler.java:739) 在ndroid.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java。 lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java :616) 产生的原因:android.system.ErrnoException:打开失败:EACCES(拒绝) 在libcore.io.Posix.open(本机方法) 在libcore.io。BlockGuardOs.open(BlockGuardOs.java:186) at libcore.io.IoBridge.open(IoBridge.java:438) at java.io.FileInputStream。(FileInputStream.java:76) at android.media.MediaPlayer.setDataSource (MediaPlayer.java:1095) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1074) at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1028) at android.media.MediaPlayer.setDataSource(MediaPlayer在Android.media.MediaPlayer.create(MediaPlayer.java:857) at andr在gunboat.com.mediaplayer.ror(FullscreenActivity.java:135)上的ooo.media.MediaPlayer.create at gunboat.com.mediaplayererror.FullscreenActivity.access $ 300(FullscreenActivity.java:24) at gunboat.com.mediaplayererror.FullscreenActivity $ 5.onClick(FullscreenActivity.java:113) at android.view.View.performClick(View。 java:5198) at android.view.View $ PerformClick.run(View.java:21147) at android.os.Handler.handleCallback(Handler.java:739) 在android.os.Handler.dispatchMessage(Handler.java:95) 在android.os.Looper.loop(Looper.java:148) 在android.app.ActivityThread.main(ActivityThread.java:5417)
感谢您的回复。我曾想过下一步是重新启动应用程序,但这通常是我会尽量避免的,除非没有其他选择。这是预期的行为还是错误?看看[文档](http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html)它说一些权限将需要重新启动应用程序,但是“系统将重新创建活动堆栈在将结果提交给您的onRequestPermission之前“ –
@FleaCircus它不是真的很清楚它是否是一个错误,但是您引用的部分暗示了Android应该自动处理重启。不幸的是,我唯一的棉花糖设备是仿真器,所以这可能在真实设备上有不同的工作方式(尽管我发现许多帖子都暗示它不会)。 –
我在同一条船上,我只能访问一个模拟器,我打算将问题标记为可行的解决方案,但我打算在Android项目上打开一个错误报告,如果有任何问题更多信息我会在这里发布。 –