/* * MIT License * * Copyright (c) 2018 Fabio Falsini <[email protected]> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.falsinsoft.qtandroidtools; import android.content.Context; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.util.Log; import android.graphics.Bitmap; import android.provider.MediaStore; import android.content.pm.ActivityInfo; import android.content.pm.ResolveInfo; import android.content.ComponentName; import com.google.android.gms.auth.api.signin.GoogleSignIn; import com.google.android.gms.auth.api.signin.GoogleSignInClient; import com.google.android.gms.auth.api.signin.GoogleSignInOptions; import com.google.android.gms.auth.api.signin.GoogleSignInAccount; import com.google.android.gms.common.api.Scope; import com.google.api.client.extensions.android.http.AndroidHttp; import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException; import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential; import com.google.api.client.googleapis.media.MediaHttpDownloaderProgressListener; import com.google.api.client.googleapis.media.MediaHttpDownloader; import com.google.api.client.googleapis.media.MediaHttpUploaderProgressListener; import com.google.api.client.googleapis.media.MediaHttpUploader; import com.google.api.client.json.gson.GsonFactory; import com.google.api.client.http.FileContent; import com.google.api.services.drive.Drive; import com.google.api.services.drive.DriveScopes; import com.google.api.services.drive.model.File; import com.google.api.services.drive.model.FileList; import java.util.Collections; import java.util.List; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.io.FileOutputStream; public class AndroidGoogleDrive { private static final String TAG = "AndroidGoogleDrive"; private final Activity mActivityInstance; private Drive mDriveService = null; public AndroidGoogleDrive(Activity ActivityInstance) { mActivityInstance = ActivityInstance; } public boolean authenticate(String AppName, String ScopeName) { final GoogleSignInAccount SignInAccount = GoogleSignIn.getLastSignedInAccount(mActivityInstance); if(SignInAccount != null) { GoogleAccountCredential AccountCredential; Drive.Builder DriveBuilder; AccountCredential = GoogleAccountCredential.usingOAuth2(mActivityInstance, Collections.singleton(ScopeName)); AccountCredential.setSelectedAccount(SignInAccount.getAccount()); DriveBuilder = new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), AccountCredential); DriveBuilder.setApplicationName(AppName); mDriveService = DriveBuilder.build(); return true; } Log.d(TAG, "You have to signin by select account before use this call!"); return false; } public boolean isAuthenticated() { return (mDriveService != null) ? true : false; } public DriveFile[] listFiles(String Query) { if(mDriveService != null) { DriveFile[] DriveFileList; File[] FileList; try { FileList = mDriveService.files() .list() .setQ(Query) .setSpaces("drive") .setFields("files(id, name, mimeType, parents)") .execute() .getFiles() .toArray(new File[0]); } catch(UserRecoverableAuthIOException e) { Log.d(TAG, "Authorization scope not requested at signin!"); return null; } catch(IOException e) { Log.d(TAG, e.toString()); return null; } DriveFileList = new DriveFile[FileList.length]; for(int i = 0; i < FileList.length; i++) { DriveFile FileData = new DriveFile(); final File FileInfo = FileList[i]; FileData.id = FileInfo.getId(); FileData.name = FileInfo.getName(); FileData.mimeType = FileInfo.getMimeType(); FileData.parents = (FileInfo.getParents() != null) ? FileInfo.getParents().toArray(new String[0]) : null; DriveFileList[i] = FileData; } return DriveFileList; } return null; } public String getRootId() { if(mDriveService != null) { File FileInfo; try { FileInfo = mDriveService.files() .get("root") .execute(); } catch(IOException e) { Log.d(TAG, e.toString()); return null; } return FileInfo.getId(); } return null; } public String createFolder(String Name, String ParentFolderId) { if(mDriveService != null) { File FolderMetadata = new File(); File FolderData; FolderMetadata.setName(Name); FolderMetadata.setMimeType("application/vnd.google-apps.folder"); if(!ParentFolderId.isEmpty()) FolderMetadata.setParents(Collections.singletonList(ParentFolderId)); try { FolderData = mDriveService.files() .create(FolderMetadata) .setFields("id") .execute(); } catch(IOException e) { Log.d(TAG, e.toString()); return null; } return FolderData.getId(); } return null; } public File getFileMetadata(String FileId, String Fields) { if(mDriveService != null) { File FileInfo; try { FileInfo = mDriveService.files() .get(FileId) .setFields(Fields) .execute(); } catch(IOException e) { Log.d(TAG, e.toString()); return null; } return FileInfo; } return null; } public boolean moveFile(String FileId, String FolderId) { if(mDriveService != null) { StringBuilder PreviousParents = new StringBuilder(); File ParentData, FileData; try { ParentData = mDriveService.files() .get(FileId) .setFields("parents") .execute(); } catch(IOException e) { Log.d(TAG, e.toString()); return false; } for(String ParentId : ParentData.getParents()) { PreviousParents.append(ParentId); PreviousParents.append(','); } try { FileData = mDriveService.files() .update(FileId, null) .setAddParents(FolderId) .setRemoveParents(PreviousParents.toString()) .setFields("id, parents") .execute(); } catch(IOException e) { Log.d(TAG, e.toString()); return false; } return true; } return false; } public boolean deleteFile(String FileId) { if(mDriveService != null) { try { mDriveService.files() .delete(FileId) .execute(); } catch(IOException e) { Log.d(TAG, e.toString()); return false; } return true; } return false; } public boolean downloadFile(String FileId, String LocalFilePath) { if(mDriveService != null) { try { Drive.Files.Get FileDownloadRequest = mDriveService.files().get(FileId); FileDownloadRequest.getMediaHttpDownloader().setProgressListener(new FileDownloadProgressListener()); FileDownloadRequest.executeMediaAndDownloadTo(new FileOutputStream(LocalFilePath)); } catch(IOException e) { Log.d(TAG, e.toString()); return false; } return true; } return false; } public String uploadFile(String LocalFilePath, String Name, String MimeType, String ParentFolderId) { if(mDriveService != null) { java.io.File MediaFile = new java.io.File(LocalFilePath); File FileMetadata = new File(); File UploadedFileData; FileMetadata.setName(Name); if(!ParentFolderId.isEmpty()) FileMetadata.setParents(Collections.singletonList(ParentFolderId)); try { Drive.Files.Create FileUploadRequest = mDriveService.files().create(FileMetadata, new FileContent(MimeType, MediaFile)); FileUploadRequest.getMediaHttpUploader().setProgressListener(new FileUploadProgressListener()); UploadedFileData = FileUploadRequest.setFields("id").execute(); } catch(FileNotFoundException e) { Log.d(TAG, e.toString()); return null; } catch(IOException e) { Log.d(TAG, e.toString()); return null; } return UploadedFileData.getId(); } return null; } private class FileDownloadProgressListener implements MediaHttpDownloaderProgressListener { public void progressChanged(MediaHttpDownloader downloader) { switch(downloader.getDownloadState()) { case MEDIA_IN_PROGRESS: downloadProgressChanged(STATE_MEDIA_IN_PROGRESS, downloader.getProgress()); break; case MEDIA_COMPLETE: downloadProgressChanged(STATE_MEDIA_COMPLETE, 1.0); break; } } } private class FileUploadProgressListener implements MediaHttpUploaderProgressListener { public void progressChanged(MediaHttpUploader uploader) throws IOException { switch (uploader.getUploadState()) { case INITIATION_STARTED: uploadProgressChanged(STATE_INITIATION_STARTED, 0.0); break; case INITIATION_COMPLETE: uploadProgressChanged(STATE_INITIATION_COMPLETE, 0.0); break; case MEDIA_IN_PROGRESS: uploadProgressChanged(STATE_MEDIA_IN_PROGRESS, uploader.getProgress()); break; case MEDIA_COMPLETE: uploadProgressChanged(STATE_MEDIA_COMPLETE, 1.0); break; } } } public static class DriveFile { public String id; public String name; public String mimeType; public String[] parents; } private static final int STATE_INITIATION_STARTED = 0; private static final int STATE_INITIATION_COMPLETE = 1; private static final int STATE_MEDIA_IN_PROGRESS = 2; private static final int STATE_MEDIA_COMPLETE = 3; private static native void downloadProgressChanged(int state, double progress); private static native void uploadProgressChanged(int state, double progress); }