1

我知道運行時權限,我已經考慮到了這一點,但它仍然不起作用。我已經添加了這些線條來體現:打開失敗:EACCES(Permission denied)api23?

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

這是我的onCreate方法:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_new); 
    if (shouldAskPermissions()) { 
     askPermissions(); 
    } 
    generateNoteOnSD(this,fileName,msg); 
    readFile(fileName); 
} 

這是要求和授予權限

protected static boolean shouldAskPermissions() { 
    return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1); 
} 

@TargetApi(23) 
protected void askPermissions() { 
    String[] permissions = { 
      "android.permission.READ_EXTERNAL_STORAGE", 
      "android.permission.WRITE_EXTERNAL_STORAGE" 
    }; 
    /* int requestCode = 200; 
    requestPermissions(permissions, requestCode);*/ 
    // Check if we have write permission 
    int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); 

    if (permission != PackageManager.PERMISSION_GRANTED) { 
     // We don't have permission so prompt the user 
     ActivityCompat.requestPermissions(
       this, permissions, 1); 
    } 
} 

而這些都是書寫和閱讀方法

public static void generateNoteOnSD(Context context, String sFileName, String sBody) { 
     try { 
      File root = new File(String.valueOf(Environment.getExternalStorageDirectory())); 
      Log.e("file path is ", String.valueOf(Environment.getExternalStorageDirectory())); 
      if (!root.exists()) { 
       root.mkdirs(); 
      } 
      File gpxfile = new File(root, sFileName); 
      String separator = System.getProperty("line.separator"); 

      FileWriter writer = new FileWriter(gpxfile.getAbsoluteFile(), true); 
      writer.append(separator); // this will add new line ; 

      //FileWriter writer = new FileWriter(gpxfile); 
      writer.append(sBody); 
      writer.flush(); 
      writer.close(); 
      Toast.makeText(context, "Saved", Toast.LENGTH_SHORT).show(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    public void readFile(String file1){ 
     //Find the directory for the SD Card using the API 
//*Don't* hardcode "/sdcard" 
     File sdcard = Environment.getExternalStorageDirectory(); 

//Get the text file 
     File file = new File(sdcard,file1); 

//Read text from file 
     StringBuilder text = new StringBuilder(); 

     try { 
      BufferedReader br = new BufferedReader(new FileReader(file)); 
      String line; 

      while ((line = br.readLine()) != null) { 
       text.append(line); 
       text.append('\n'); 
      } 
      br.close(); 
     } 
     catch (IOException e) { 
      //You'll need to add proper error handling here 
     } 

//Find the view by its id 
     Log.e("text",text.toString()); 
    } 

編輯 這是我的堆棧跟蹤:

W/System.err: java.io.FileNotFoundException: /storage/emulated/0/CrowdSensingData: open failed: EACCES (Permission denied) 
W/System.err:  at libcore.io.IoBridge.open(IoBridge.java:487) 
W/System.err:  at java.io.FileOutputStream.<init>(FileOutputStream.java:87) 
W/System.err:  at java.io.FileWriter.<init>(FileWriter.java:58) 
W/System.err:  at enis.example.com.alarmmanagertest.FileAndServerHandlingActivity.generateNoteOnSD(FileAndServerHandlingActivity.java:128) 
W/System.err:  at enis.example.com.alarmmanagertest.ActivityRecognitionService.handleDetectedActivities(ActivityRecognitionService.java:107) 
W/System.err:  at enis.example.com.alarmmanagertest.ActivityRecognitionService.onStart(ActivityRecognitionService.java:122) 
W/System.err:  at android.app.Service.onStartCommand(Service.java:459) 
W/System.err:  at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3209) 
W/System.err:  at android.app.ActivityThread.-wrap17(ActivityThread.java) 
W/System.err:  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1586) 
W/System.err:  at android.os.Handler.dispatchMessage(Handler.java:111) 
W/System.err:  at android.os.Looper.loop(Looper.java:207) 
W/System.err:  at android.app.ActivityThread.main(ActivityThread.java:5728) 
W/System.err:  at java.lang.reflect.Method.invoke(Native Method) 
W/System.err:  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 
W/System.err:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679) 
W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied) 
W/System.err:  at libcore.io.Posix.open(Native Method) 
W/System.err:  at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186) 
W/System.err:  at libcore.io.IoBridge.open(IoBridge.java:473) 
+1

'requestPermissions()'是異步的。當它返回時,用戶甚至沒有被要求獲得許可,更不用說授予它了。 – CommonsWare

+0

@CommonsWare我明白你的觀點,但我不明白如何更改代碼。我是一名初學者,使用android –

+0

這篇文章在任何有關Android應用程序開發的最新書籍或課程中都有介紹,在[文檔](https://developer.android.com/training/)權限/ requesting.html)。在[這個示例項目](https://github.com/commonsguy/cw-omnibus/tree/master/Files/FilesEditor)中,我使用[AbstractPermissionActivity'](https://github.com/commonsguy/cw -omnibus/blob/master/Files/FilesEditor/app/src/main/java/com/commonsware/android/fileseditor/AbstractPermissionActivity.java)隔離開啓活動時需要運行時權限的代碼。 – CommonsWare

回答

4

如果權限尚未授予你不應該叫這立即需要它們的方法。改爲在onRequestPermissionsResult中調用它們。這保證了只有在用戶授予權限後才能執行它們。

if (shouldAskPermissions()) { 
    askPermissions(); 
} else { 
    generateNoteOnSD(this,fileName,msg); 
    readFile(fileName); 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case 1: { 
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       generateNoteOnSD(this,fileName,msg); 
       readFile(fileName); 
      } 
     } 
    } 
} 

編輯: 此外,在您的shouldAskPermissions ContextCompat.checkSelfPermission()方法。

編輯2: 下面是shouldAskPermissions()的實現

protected boolean shouldAskPermissions() { 
    if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { 
     return false; 
    } 
    int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); 
    return (permission != PackageManager.PERMISSION_GRANTED); 
} 
+0

恐怕這並沒有解決問題,我仍然得到W/System.err:引起:android.system.ErrnoException:打開失敗:EACCES(權限被拒絕) –

+0

@futureengineer請發佈完整的stacktrace和你的新的shouldAskPermissions()方法 –

+0

只是爲了確保發佈堆棧跟蹤之前的東西,所以你不會浪費你的時間。我應該如何改變方法shouldAskPermissions()?它只是驗證版本,以檢查它是否需要運行時權限。如果你的意思是askPermissions()方法,我應該改變它嗎?它只是請求權限,這會觸發您在回覆中發佈的onRequestPermissionsResult方法,我是否誤解了某些內容? –

相關問題