2

權限授予我試圖讓一個應用程序從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)

回答

1

今天剛剛處理了這個。您需要在授予權限後重新啓動您的應用程序。我用這樣的事情來完成重新啓動:我常來這個結論

private static final int REQUEST_CODE_READ_EXTERNAL_STORAGE = 1; 

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    switch (requestCode) { 
     case REQUEST_CODE_READ_EXTERNAL_STORAGE: 
      if (grantResults.length >= 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       // Schedule start after 1 second 
       PendingIntent pi = PendingIntent.getActivity(this, 0, getIntent(), PendingIntent.FLAG_CANCEL_CURRENT); 
       AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
       am.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, pi); 

       // Stop now 
       System.exit(0); 
      } else { 
       Toast.makeText(this, R.string.error_external_storage_unavailable, Toast.LENGTH_LONG).show(); 
       finish(); 
      } 

      break; 
    } 

    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
} 

這裏一個來源:Application not able to access SD card when WRITE_EXTERNAL_STORAGE permission is granted at run time

的原因重啓,當READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE權限授予用戶將您的應用程序的帳戶添加到新的安全組中。此更改在應用程序進程仍在運行時不起作用。

+0

感謝您的回覆。我曾想過下一步是重新啓動應用程序,但這通常是我會盡量避免的,除非沒有其他選擇。這是預期的行爲還是錯誤?看看[文檔](http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html)它說一些權限將需要重新啓動應用程序,但是「系統將重新創建活動堆棧在將結果提交給您的onRequestPermission之前「 –

+0

@FleaCircus它不是真的很清楚它是否是一個錯誤,但是您引用的部分暗示了Android應該自動處理重啓。不幸的是,我唯一的棉花糖設備是仿真器,所以這可能在真實設備上有不同的工作方式(儘管我發現許多帖子都暗示它不會)。 –

+0

我在同一條船上,我只能訪問一個模擬器,我打算將問題標記爲可行的解決方案,但我打算在Android項目上打開一個錯誤報告,如果有任何問題更多信息我會在這裏發佈。 –

相關問題