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方法,我是否误解了某些内容? –

相关问题