1

Я знаю о разрешениях времени выполнения, и я принял это во внимание, но он все еще не работает. Я добавил эти строки манифестировать:open failed: EACCES (отказ от прав) 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()); 
    } 

EDIT Это мой StackTrace:

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) я использую [the 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); 
      } 
     } 
    } 
} 

Edit: Кроме того, включают ContextCompat.checkSelfPermission в ваших shouldAskPermissions() метод.

Edit 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: open failed: EACCES (Permission denied) –

+0

@futureengineer, пожалуйста, напишите полный стек и ваш новый метод shouldAskPermissions() –

+0

Просто, чтобы убедиться в чем-то перед публикацией stacktrace, чтобы вы не тратили свое время. Как я должен изменить метод shouldAskPermissions()? он просто проверяет версию, чтобы проверить, нужны ли ей разрешения времени выполнения. И если вы имеете в виду метод askPermissions(), я должен его изменить? он просто запрашивает разрешения, которые запускают метод onRequestPermissionsResult, который вы разместили в своем ответе, я что-то не понимаю? –