public void loadForm(
     final GoogleApiClient googleClient, final Activity activity, final String formName) {
   if (loadFormFromLocalStorage(activity, formName)) {
     return;
   }
   Query.Builder queryBuilder = new Query.Builder();
   Log.i(
       MainActivity.PT_APP_INFO,
       "Load form from cloud.  Google client state " + googleClient.isConnected());
   queryBuilder.addFilter(Filters.eq(SearchableField.TITLE, formName));
   Query query = queryBuilder.build();
   final DriveFolder driveFolder = Drive.DriveApi.getFolder(googleClient, storageDriveId);
   Toast.makeText(activity, "Loading " + formName + " from google drive... ", Toast.LENGTH_LONG)
       .show();
   driveFolder
       .queryChildren(googleClient, query)
       .setResultCallback(
           new ResultCallback<DriveApi.MetadataBufferResult>() {
             @Override
             public void onResult(DriveApi.MetadataBufferResult resultBufferResult) {
               if (resultBufferResult.getMetadataBuffer().getCount() > 0) {
                 DriveFile driveFile =
                     Drive.DriveApi.getFile(
                         googleClient, resultBufferResult.getMetadataBuffer().get(0).getDriveId());
                 driveFile
                     .open(googleClient, DriveFile.MODE_READ_ONLY, null)
                     .setResultCallback(
                         new ResultCallback<DriveApi.DriveContentsResult>() {
                           @Override
                           public void onResult(DriveApi.DriveContentsResult driveContentsResult) {
                             try {
                               InputStream is =
                                   driveContentsResult.getDriveContents().getInputStream();
                               FormTemplateManager.loadForm(is);
                               LocalDriver.save(
                                   FormTemplateManager.getFormTemplate(),
                                   GoogleFileType.FORM,
                                   formName);
                               goBackToMain(activity);
                             } catch (Throwable th) {
                               String errorStr =
                                   "Unable to retrieve form "
                                       + formName
                                       + " because "
                                       + th
                                       + " Retrieving from local drive";
                               Toast.makeText(activity, errorStr, Toast.LENGTH_LONG).show();
                               Log.e(MainActivity.PT_APP_INFO, errorStr);
                             }
                           }
                         });
               }
             }
           });
 }
Пример #2
0
    /**
     * Helper just to avoid copy&paste'ing code.
     *
     * <p>Note: since this contains blocking Drive API calls, this will crash if you try to call it
     * from the main thread, it can only be called from other threads.
     *
     * @return null if the folder can not be found.
     */
    private DriveFolder checkOrCreateRemoteFolder(
        GoogleApiClient googleApiClient, DriveFolder rootFolder, String folderName) {
      // check for STORAGE permission
      if (!canWriteToStorage()) return null;

      Query query =
          new Query.Builder()
              .addFilter(
                  Filters.and(
                      Filters.eq(SearchableField.TITLE, folderName),
                      Filters.contains(SearchableField.MIME_TYPE, "folder")))
              .build();

      DriveApi.MetadataBufferResult result =
          rootFolder.queryChildren(mGoogleApiClient, query).await();

      if (!result.getStatus().isSuccess()) {
        Log.e(
            mActivity.getResources().getString(R.string.app_name),
            "Cannot query folders in the root of Google Drive.");
        return null;
      } else {
        for (Metadata m : result.getMetadataBuffer()) {
          if (m.getTitle().equals(folderName)) {
            // Folder exists - we found it!
            DriveFolder folder = m.getDriveId().asDriveFolder();
            result.getMetadataBuffer().release();
            return folder;
          }
        }
      }

      result.getMetadataBuffer().release();

      // Folder not found; let's create it.
      MetadataChangeSet changeSet = new MetadataChangeSet.Builder().setTitle(folderName).build();

      DriveFolder.DriveFolderResult result1 =
          rootFolder.createFolder(googleApiClient, changeSet).await();

      if (!result1.getStatus().isSuccess()) {
        Log.e(
            mActivity.getResources().getString(R.string.app_name),
            "Error while trying to create the folder \"" + folderName + "\"");
        return null;
      }

      return result1.getDriveFolder();
    }
 public void saveOrUpdate(
     final FormTemplate formToSave,
     final GoogleApiClient googleClient,
     final GoogleFileType googleFileType)
     throws GoogleDriverException {
   LocalDriver.save(formToSave, googleFileType, null);
   if (storageDriveId == null) {
     throw new GoogleDriverException("Cannot found form directory on google drive");
   }
   final DriveId dirDriveId;
   if (googleFileType == GoogleFileType.REPORT) {
     dirDriveId = reportDriveId;
   } else {
     dirDriveId = storageDriveId;
   }
   final String fileName = PhysicalTherapyUtils.getFileName(formToSave);
   Query.Builder queryBuilder = new Query.Builder();
   queryBuilder.addFilter(Filters.eq(SearchableField.TITLE, fileName));
   Query query = queryBuilder.build();
   try {
     final DriveFolder driveFolder = Drive.DriveApi.getFolder(googleClient, dirDriveId);
     driveFolder
         .queryChildren(googleClient, query)
         .setResultCallback(
             new ResultCallback<DriveApi.MetadataBufferResult>() {
               @Override
               public void onResult(DriveApi.MetadataBufferResult resultBufferResult) {
                 DriveId fileDriveId = null;
                 for (Metadata result : resultBufferResult.getMetadataBuffer()) {
                   fileDriveId = result.getDriveId();
                 }
                 if (fileDriveId == null) {
                   save(formToSave, googleClient, dirDriveId, fileName);
                 } else {
                   update(formToSave, googleClient, fileDriveId, fileName);
                 }
               }
             });
   } catch (Throwable th) {
     throw new GoogleDriverException("Unable to find or save file to drive because " + th, th);
   }
 }
 private void setStorageDirectory(final GoogleApiClient googleClient)
     throws GoogleDriverException {
   Query.Builder queryBuilder = new Query.Builder();
   queryBuilder.addFilter(Filters.eq(SearchableField.TITLE, STORAGE_DIR));
   Query query = queryBuilder.build();
   try {
     final DriveFolder driveFolder = Drive.DriveApi.getRootFolder(googleClient);
     driveFolder
         .queryChildren(googleClient, query)
         .setResultCallback(
             new ResultCallback<DriveApi.MetadataBufferResult>() {
               @Override
               public void onResult(DriveApi.MetadataBufferResult resultBufferResult) {
                 for (Metadata result : resultBufferResult.getMetadataBuffer()) {
                   if (result.getTitle().equals(STORAGE_DIR)) {
                     storageDriveId = result.getDriveId();
                     getAllForms(googleClient);
                   }
                 }
                 if (storageDriveId == null) {
                   MetadataChangeSet.Builder builder = new MetadataChangeSet.Builder();
                   builder.setTitle(STORAGE_DIR);
                   driveFolder
                       .createFolder(googleClient, builder.build())
                       .setResultCallback(
                           new ResultCallback<DriveFolder.DriveFolderResult>() {
                             @Override
                             public void onResult(
                                 DriveFolder.DriveFolderResult driveFolderResult) {
                               storageDriveId = driveFolderResult.getDriveFolder().getDriveId();
                             }
                           });
                 }
               }
             });
   } catch (Throwable th) {
     throw new GoogleDriverException(
         "Unable to find or create google drive storage directory because " + th, th);
   }
 }
Пример #5
0
    private void syncPhotosForTeam(GoogleApiClient googleApiClient, int teamNumber) {
      if (mTeamNumber >= 0) {

        Log.i(
            mActivity.getResources().getString(R.string.app_name),
            "Beginning photo sync for team " + teamNumber);

        // get the list of local files

        File photosDir = new File(mLocalTeamPhotosFilePath + "/" + teamNumber);

        /** **** get the list of local files ***** */

        // check if that folder exists
        if (!photosDir.isDirectory()) {
          // we have no photos for this team
          if (mRequester != null) mRequester.updatePhotos(new Bitmap[0]);
          googleApiClient.disconnect();
          return;
        }

        File[] listOfFiles = photosDir.listFiles();
        ArrayList<String> arrLocalFiles = new ArrayList<String>();
        for (File file : listOfFiles) {
          // make sure it's an image file
          Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
          if (bitmap != null) {
            arrLocalFiles.add(file.getPath());
          }
          // else: if it's not a file, then what is it???? .... skip I guess
        }

        // Navigate to the correct folder - there has to be a more efficient way to do this

        DriveFolder rootFolder =
            Drive.DriveApi.getFolder(googleApiClient, mDriveIdTeamPhotosFolder);
        Log.i(
            mActivity.getResources().getString(R.string.app_name), "Local Files: " + arrLocalFiles);

        Query query =
            new Query.Builder()
                .addFilter(Filters.eq(SearchableField.TITLE, "" + teamNumber))
                .build();

        DriveApi.MetadataBufferResult result =
            rootFolder.queryChildren(googleApiClient, query).await();

        DriveFolder teamPhotosFolder = null;
        for (Metadata m : result.getMetadataBuffer()) {
          teamPhotosFolder = m.getDriveId().asDriveFolder();
        }
        result.getMetadataBuffer().close();

        ArrayList<PathAndDriveId> arrRemoteFiles = new ArrayList<PathAndDriveId>();
        if (teamPhotosFolder != null) {
          query =
              new Query.Builder()
                  .addFilter(
                      Filters.eq(SearchableField.MIME_TYPE, "application/vnd.google-apps.photo"))
                  .build();
          result = teamPhotosFolder.queryChildren(googleApiClient, query).await();

          for (Metadata m : result.getMetadataBuffer()) {
            arrRemoteFiles.add(
                new PathAndDriveId(
                    mRemoteToplevelFolderName
                        + "/"
                        + mRemoteTeamFolderName
                        + "/"
                        + mRemoteTeamPhotosFolderName
                        + "/"
                        + mTeamNumber
                        + "/"
                        + m.getTitle(),
                    m.getDriveId(),
                    m.getTitle()));
          }
          result.getMetadataBuffer().close();
        }
        Log.i(
            mActivity.getResources().getString(R.string.app_name),
            "Remote Files: " + arrRemoteFiles);

        // Remove files that are in both lists - these don't need to be synced.
        for (PathAndDriveId remoteFile : arrRemoteFiles) {
          String remotePath = remoteFile.path;
          if (arrLocalFiles.contains(remotePath)) {
            arrRemoteFiles.remove(remoteFile);
            arrLocalFiles.remove(remotePath);
          }
        }

        /** **** Download any Files we're missing locally ***** */
        for (PathAndDriveId remoteFile : arrRemoteFiles) {
          // the Drive API actually makes a local cache of the file, so let's copy the contents into
          // our app's file structure
          DriveApi.DriveContentsResult fileResult =
              remoteFile
                  .driveId
                  .asDriveFile()
                  .open(googleApiClient, DriveFile.MODE_READ_ONLY, null)
                  .await();

          if (!fileResult.getStatus().isSuccess()) {
            // file can't be opened
            continue;
          }

          String localFileToCreate =
              mLocalTeamPhotosFilePath + "/" + teamNumber + "/" + remoteFile.title;
          DriveContents contents = null;
          InputStream in = null;
          FileOutputStream fout = null;
          try {
            // DriveContents object contains pointers to the actual byte stream, which we will
            // manually copy
            contents = fileResult.getDriveContents();
            in = contents.getInputStream();
            fout = new FileOutputStream(localFileToCreate);

            // read bytes from source file and write to destination file
            byte[] b = new byte[1024];
            int noOfBytes = 0;
            while ((noOfBytes = in.read(b)) != -1) fout.write(b, 0, noOfBytes);
            in.close();
            fout.close();
            contents.discard(googleApiClient);
          } catch (FileNotFoundException e) {
            // something went wrong, delete the file we were trying to create
            (new File(localFileToCreate)).delete();
          } catch (IOException e) {
            // something went wrong, delete the file we were trying to create
            (new File(localFileToCreate)).delete();
          }
        }

        /** **** Upload any files that are missing remotely ***** */
        for (String localFile : arrLocalFiles) {

          // if the remote folder does not exist, create it. This should only need to be called
          // once.
          if (teamPhotosFolder == null) {
            MetadataChangeSet changeSet =
                new MetadataChangeSet.Builder().setTitle("" + teamNumber).build();
            DriveFolder.DriveFolderResult folderResult =
                rootFolder.createFolder(googleApiClient, changeSet).await();
            teamPhotosFolder = folderResult.getDriveFolder();
          }

          DriveContents contents = null;
          try {
            FileInputStream in = new FileInputStream(localFile);

            // create a new file in Drive. This works a little different than normal file IO it that
            // you create the file first,
            // then tell it at the end which folder it's part of. Think of "folders" in drive more
            // like "tags" or "labels".
            DriveApi.DriveContentsResult contentResult =
                Drive.DriveApi.newDriveContents(googleApiClient).await();
            contents = contentResult.getDriveContents();
            OutputStream out = contents.getOutputStream();
            // read bytes from source file and write to destination file
            byte[] b = new byte[1024];
            int noOfBytes = 0;
            while ((noOfBytes = in.read(b)) != -1) out.write(b, 0, noOfBytes);
            in.close();
            out.close();
          } catch (FileNotFoundException e) {
            // something went wrong, discard the changes to the Drive file
            if (contents != null) contents.discard(googleApiClient);
          } catch (IOException e) {
            // something went wrong, discard the changes to the Drive file
            if (contents != null) contents.discard(googleApiClient);
          }

          if (contents != null) {
            String[] splitFilename = localFile.split("/");
            String filename = splitFilename[splitFilename.length - 1];
            MetadataChangeSet changeSet =
                new MetadataChangeSet.Builder()
                    .setTitle(filename)
                    .setMimeType(URLConnection.guessContentTypeFromName(filename))
                    .build();

            teamPhotosFolder.createFile(googleApiClient, changeSet, contents).await();
          }
        }

        Log.i(
            mActivity.getResources().getString(R.string.app_name),
            "Finished photo sync for team " + teamNumber);
        googleApiClient.disconnect();

        // hand the photos back to the PhotoRequester
        if (mRequester != null) {
          // first, get the list of image files
          listOfFiles = photosDir.listFiles();
          ArrayList<Bitmap> arrLocalBitmaps = new ArrayList<Bitmap>();
          for (File file : listOfFiles) {
            // make sure it's an image file
            Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
            if (bitmap != null) {
              arrLocalBitmaps.add(bitmap);
            }
            // else: if it's not a file, then what is it???? .... skip I guess
          }
          Bitmap[] bitmaps = new Bitmap[arrLocalBitmaps.size()];
          // TODO: commented out because it crashes the app with the error:
          // "Only the original thread that created a view hierarchy can touch its views."
          // This will need a re-jigging - maybe a loop in the PhotoRequester that checks for
          // updates every
          // few seconds and re-draws if there has been one.

          //                    mRequester.updatePhotos(arrLocalBitmaps.toArray(bitmaps));
        }
      }
    }