title: Unable to get Write permission on Android
body: <p>I'm developing an Android app that should  interact with Google Calendar. I followed the instructions on the Google API site and copied the code in this class: </p>
  
  <pre><code>public class GoogleCalendarManager {
  private static final String APPLICATION_NAME = "Locker";
  private static final JacksonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
  private static final String TOKENS_DIRECTORY_PATH = "tokens";
  
  /**
   * Global instance of the scopes required by this quickstart.
   * If modifying these scopes, delete your previously saved tokens/ folder.
   */
  private static final List&lt;String&gt; SCOPES = Collections.singletonList(CalendarScopes.CALENDAR_READONLY);
  private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
  
  private Calendar.Events events;
  private Context context;
  
  /**
   * Creates an authorized Credential object.
   * @param HTTP_TRANSPORT The network HTTP Transport.
   * @return An authorized Credential object.
   * @throws IOException If the credentials.json file cannot be found.
   */
  private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
      // Load client secrets.
      InputStream in = GoogleCalendarManager.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
      if (in == null) {
          Log.println(Log.DEBUG, "DEB", "------- FILE NOT FOUND ---------");
          throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
      } else {
          GoogleClientSecrets clientSecrets = GoogleClientSecrets
                  .load(JSON_FACTORY, new InputStreamReader(in));
  
          GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                  HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                  .setDataStoreFactory(new FileDataStoreFactory(
                          new File(TOKENS_DIRECTORY_PATH)))
                  .setAccessType("offline")
                  .build();
  
          LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
          return new AuthorizationCodeInstalledApp(flow, receiver)
                  .authorize("user");
      }
  }
  
  public GoogleCalendarManager(Context context) {
      this.context = context;
      // Build a new authorized API client service.
      NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();
      try {
          HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
      } catch (GeneralSecurityException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      }
      Calendar service = null;
      try {
          service = new Calendar
                  .Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                  .setApplicationName(APPLICATION_NAME)
                  .build();
  
          this.events = service.events();
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
  
  public void addReminder(String domain, String username, String lastUpdate, int updatePeriodDays){
      Resources resources = context.getResources();
  
      Event event = new Event()
              .setSummary(resources.getString(R.string.event_summary) + domain)
              .setDescription(resources.getString(R.string.event_description)
                      + domain + ": " + username
                      + resources.getString(R.string.event_description_plus)
                      + lastUpdate);
  
      // Getting the date
      Date lastUpdateDate = null;
      try {
          lastUpdateDate = new SimpleDateFormat("dd/MM/yyyy")
                  .parse(String.valueOf(lastUpdate));
      } catch (ParseException e) {
          e.printStackTrace();
      }
  
      long passPeriod = lastUpdateDate.getTime();
      long updatePeriod = TimeUnit.DAYS.toMillis(updatePeriodDays);
      long expirePeriod = passPeriod + updatePeriod;
  
  
      DateTime startDateTime = new DateTime(expirePeriod);
      EventDateTime start = new EventDateTime()
              .setDateTime(startDateTime);
      event.setStart(start);
  
      DateTime endDateTime = new DateTime(expirePeriod);
      EventDateTime end = new EventDateTime()
              .setDateTime(endDateTime);
      event.setEnd(end);
  
  }
  }
  </code></pre>
  
  <p>My problem is a <strong>java.io.IOException: unable to create directory: /tokens</strong> where I try to create a folder, in this line:</p>
  
  <pre><code>GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
              HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
              .setDataStoreFactory(new FileDataStoreFactory(
                      new File(TOKENS_DIRECTORY_PATH)))
              .setAccessType("offline")
              .build();
  </code></pre>
  
  <p>I've already tried to add permissions in the manifest file of my app:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      package="com.example.locker"&gt;
      &lt;uses-permission android:name="android.permission.INTERNET"&gt;&lt;/uses-permission&gt;
      &lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"&gt;&lt;/uses-permission&gt;
      &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"&gt;&lt;/uses-permission&gt;
      &lt;application
          ...
      &lt;/application&gt;
  
  &lt;/manifest&gt;
  </code></pre>
  
  <p>I really don't undestard how to write on the internal storage of the device. I've tried to write <strong>String.valueOf(Environment.getDataDirectory()))</strong> instead of the constant <strong>TOKENS_DIRECTORY_PATH</strong> in the File constructor, but I got another error, and the program crashes:</p>
  
  <pre><code> java.lang.NoClassDefFoundError: Failed resolution of: Ljava/nio/file/attribute/PosixFilePermission;
  </code></pre>
  
  <p>I tried both the situations with an emulator and a real device, but the errors don't change. I don't know how to have permissions to write.</p>
  
  <p>Thank you!!!</p>
  
  <p><strong>UPDATE</strong>
  I've added this methos in my Activity, executed before the creation of the GoogleCalendarManager:</p>
  
  <pre><code>public  boolean isStoragePermissionGranted() {
      if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M) {
          if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                  == PackageManager.PERMISSION_GRANTED) {
              Log.println(Log.DEBUG, "DEB","Permission is granted");
              return true;
          } else {
              Log.println(Log.DEBUG, "DEB","Permission is revoked");
              ActivityCompat.requestPermissions(this, new String[]{
                      Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
              return false;
          }
      }
      else { //permission is automatically granted on sdk&lt;23 upon installation
          Log.println(Log.DEBUG, "DEB","Permission is granted");
          return true;
      }
  }
  </code></pre>
  
  <p>It prints <strong>Permission is granted</strong> but I have the same error as before.</p>