11package com .orgzly .android .repos ;
22
3- import android .app .Activity ;
4- import android .content .Intent ;
53import android .content .Context ;
64import android .net .Uri ;
5+ import android .os .Build ;
6+
7+ import androidx .annotation .RequiresApi ;
78
89import com .google .android .gms .auth .api .signin .GoogleSignIn ;
910
11+ import com .google .android .gms .auth .api .signin .GoogleSignInAccount ;
1012import com .google .api .client .extensions .android .http .AndroidHttp ;
1113import com .google .api .client .googleapis .extensions .android .gms .auth .GoogleAccountCredential ;
1214import com .google .api .client .http .FileContent ;
2022
2123import java .io .BufferedOutputStream ;
2224// import java.io.File;
23- import java .io .FileInputStream ;
2425import java .io .FileOutputStream ;
2526import java .io .IOException ;
26- import java .io .InputStream ;
2727import java .io .OutputStream ;
2828import java .util .ArrayList ;
29+ import java .util .Arrays ;
2930import java .util .Collections ;
3031import java .util .HashMap ;
3132import java .util .List ;
32- import java .util .Locale ;
3333import java .util .Map ;
3434
35- import android .util .Log ;
36-
3735public class GoogleDriveClient {
3836 private static final String TAG = GoogleDriveClient .class .getName ();
3937
@@ -48,10 +46,10 @@ public class GoogleDriveClient {
4846
4947 private final Context mContext ;
5048 private final long repoId ;
51- private Drive mDriveService ;
49+ private static Drive mDriveService ;
5250
53- private Map <String , String > pathIds ;
54- {
51+ private static Map <String , String > pathIds ;
52+ static {
5553 pathIds = new HashMap <>();
5654 pathIds .put ("My Drive" , "root" );
5755 pathIds .put ("" , "root" );
@@ -61,30 +59,61 @@ public GoogleDriveClient(Context context, long id) {
6159 mContext = context ;
6260
6361 repoId = id ;
64- }
6562
66- public void setService (Drive driveService ) {
67- mDriveService = driveService ;
63+ if (isLinked ()) setDriveService ();
6864 }
6965
7066 public boolean isLinked () {
7167 // Check for existing Google Sign In account, if the user is already signed in
7268 // the GoogleSignInAccount will be non-null.
73- return GoogleSignIn .getLastSignedInAccount (mContext ) != null ;
69+ return getGoogleAccount () != null ;
70+ }
71+
72+ private GoogleSignInAccount getGoogleAccount () {
73+ return GoogleSignIn .getLastSignedInAccount (mContext );
74+ }
75+
76+ public Drive getDriveService (GoogleSignInAccount googleAccount ) {
77+ GoogleAccountCredential credential = GoogleAccountCredential .usingOAuth2 (
78+ mContext , Collections .singleton (DriveScopes .DRIVE ));
79+ credential .setSelectedAccount (googleAccount .getAccount ());
80+ return new Drive .Builder (
81+ AndroidHttp .newCompatibleTransport (),
82+ new GsonFactory (),
83+ credential )
84+ .setApplicationName ("Orgzly" )
85+ .build ();
86+ }
87+
88+ public Drive getDriveService () {
89+ if (mDriveService != null ) return mDriveService ;
90+ return getDriveService (getGoogleAccount ());
91+ }
92+
93+ public void setDriveService () {
94+ if (mDriveService == null ) mDriveService = getDriveService ();
95+ }
96+
97+ public void setDriveService (GoogleSignInAccount googleAccount ) {
98+ mDriveService = getDriveService (googleAccount );
7499 }
75100
76101 private void linkedOrThrow () throws IOException {
77102 if (! isLinked ()) {
78103 throw new IOException (NOT_LINKED );
104+ } else {
105+ setDriveService ();
79106 }
80107 }
81108
109+ @ RequiresApi (api = Build .VERSION_CODES .N )
82110 private String findId (String path ) throws IOException {
83111 if (pathIds .containsKey (path )) {
84112 return pathIds .get (path );
85113 }
86114
87115 String [] parts = path .split ("/" );
116+ parts = Arrays .stream (parts ).filter (s -> !s .isEmpty ()).toArray (String []::new );
88117 String [] ids = new String [parts .length +1 ];
89118
90119 ids [0 ] = "root" ;
@@ -95,23 +124,21 @@ private String findId(String path) throws IOException {
95124 .setSpaces ("drive" )
96125 .setFields ("files(id, name, mimeType)" )
97126 .execute ();
98- List files = result .getFiles ();
127+ List < File > files = result .getFiles ();
99128 if (!files .isEmpty ()) {
100129 File file = (File ) files .get (0 );
101130 ids [i +1 ] = file .getId ();
102131 }
103132 }
104133
105- for (int i = 0 ; i < ids .length ; ++i ) {
106- if (ids [i ] == null ) {
107- break ;
108- }
109- pathIds .put (path , ids [i ]);
134+ if (ids [ids .length -1 ] != null ) {
135+ pathIds .put (path , ids [ids .length -1 ]);
110136 }
111137
112138 return ids [ids .length -1 ]; // Returns null if no file is found
113139 }
114140
141+ @ RequiresApi (api = Build .VERSION_CODES .N )
115142 public List <VersionedRook > getBooks (Uri repoUri ) throws IOException {
116143 linkedOrThrow ();
117144
@@ -129,24 +156,23 @@ public List<VersionedRook> getBooks(Uri repoUri) throws IOException {
129156
130157 try {
131158
132- String folderId = findId (path );
133-
159+ String pathId = findId (path );
134160
135- if (folderId != null ) {
161+ if (pathId != null ) {
136162
137- File folder = mDriveService .files ().get (folderId )
138- .setFields ("id, mimeType" )
163+ File folder = mDriveService .files ().get (pathId )
164+ .setFields ("id, name, mimeType, version, modifiedTime " )
139165 .execute ();
140166
141- if (folder .getMimeType () == "application/vnd.google-apps.folder" ) {
167+ if (folder .getMimeType (). equals ( "application/vnd.google-apps.folder" ) ) {
142168
143169 String pageToken = null ;
144170 do {
145171 FileList result = mDriveService .files ().list ()
146172 .setQ (String .format ("mimeType != 'application/vnd.google-apps.folder' " +
147- "and '%s' in parents and trashed = false" , folderId ))
173+ "and '%s' in parents and trashed = false" , pathId ))
148174 .setSpaces ("drive" )
149- .setFields ("nextPageToken, files(id, name, mimeType)" )
175+ .setFields ("nextPageToken, files(id, name, mimeType, version, modifiedTime )" )
150176 .setPageToken (pageToken )
151177 .execute ();
152178 for (File file : result .getFiles ()) {
@@ -170,7 +196,7 @@ public List<VersionedRook> getBooks(Uri repoUri) throws IOException {
170196 throw new IOException ("Not a directory: " + repoUri );
171197 }
172198 } else {
173- throw new IOException ("Not a directory : " + repoUri );
199+ throw new IOException ("Path not found : " + repoUri );
174200 }
175201
176202 } catch (Exception e ) {
@@ -187,6 +213,7 @@ public List<VersionedRook> getBooks(Uri repoUri) throws IOException {
187213 /**
188214 * Download file from Google Drive and store it to a local file.
189215 */
216+ @ RequiresApi (api = Build .VERSION_CODES .N )
190217 public VersionedRook download (Uri repoUri , String fileName , java .io .File localFile ) throws IOException {
191218 linkedOrThrow ();
192219
@@ -200,10 +227,10 @@ public VersionedRook download(Uri repoUri, String fileName, java.io.File localFi
200227
201228 if (fileId != null ) {
202229 File file = mDriveService .files ().get (fileId )
203- .setFields ("id, mimeType, version, modifiedDate " )
230+ .setFields ("id, mimeType, version, modifiedTime " )
204231 .execute ();
205232
206- if (file .getMimeType () != "application/vnd.google-apps.folder" ) {
233+ if (! file .getMimeType (). equals ( "application/vnd.google-apps.folder" ) ) {
207234
208235 String rev = Long .toString (file .getVersion ());
209236 long mtime = file .getModifiedTime ().getValue ();
@@ -231,6 +258,7 @@ public VersionedRook download(Uri repoUri, String fileName, java.io.File localFi
231258
232259
233260 /** Upload file to Google Drive. */
261+ @ RequiresApi (api = Build .VERSION_CODES .N )
234262 public VersionedRook upload (java .io .File file , Uri repoUri , String fileName ) throws IOException {
235263 linkedOrThrow ();
236264
@@ -267,7 +295,7 @@ public VersionedRook upload(java.io.File file, Uri repoUri, String fileName) thr
267295 pathIds .put (filePath , fileId );
268296 } else {
269297 fileMetadata = mDriveService .files ().update (fileId , fileMetadata , mediaContent )
270- .setFields ("id" )
298+ .setFields ("id, version, modifiedTime " )
271299 .execute ();
272300 }
273301
@@ -285,6 +313,7 @@ public VersionedRook upload(java.io.File file, Uri repoUri, String fileName) thr
285313 return new VersionedRook (repoId , RepoType .GOOGLE_DRIVE , repoUri , bookUri , rev , mtime );
286314 }
287315
316+ @ RequiresApi (api = Build .VERSION_CODES .N )
288317 public void delete (String path ) throws IOException {
289318 linkedOrThrow ();
290319
@@ -293,7 +322,7 @@ public void delete(String path) throws IOException {
293322
294323 if (fileId != null ) {
295324 File file = mDriveService .files ().get (fileId ).setFields ("id, mimeType" ).execute ();
296- if (file .getMimeType () != "application/vnd.google-apps.folder" ) {
325+ if (! file .getMimeType (). equals ( "application/vnd.google-apps.folder" ) ) {
297326 File fileMetadata = new File ();
298327 fileMetadata .setTrashed (true );
299328 mDriveService .files ().update (fileId , fileMetadata ).execute ();
@@ -313,6 +342,7 @@ public void delete(String path) throws IOException {
313342 }
314343 }
315344
345+ @ RequiresApi (api = Build .VERSION_CODES .N )
316346 public VersionedRook move (Uri repoUri , Uri from , Uri to ) throws IOException {
317347 linkedOrThrow ();
318348
@@ -324,10 +354,10 @@ public VersionedRook move(Uri repoUri, Uri from, Uri to) throws IOException {
324354
325355 if (fileId != null ) {
326356 fileMetadata = mDriveService .files ().update (fileId , fileMetadata )
327- .setFields ("id, mimeType, version, modifiedDate " )
357+ .setFields ("id, mimeType, version, modifiedTime " )
328358 .execute ();
329359
330- if (fileMetadata .getMimeType () == "application/vnd.google-apps.folder" ) {
360+ if (fileMetadata .getMimeType (). equals ( "application/vnd.google-apps.folder" ) ) {
331361 throw new IOException ("Relocated object not a file?" );
332362 }
333363
@@ -336,7 +366,7 @@ public VersionedRook move(Uri repoUri, Uri from, Uri to) throws IOException {
336366 String rev = Long .toString (fileMetadata .getVersion ());
337367 long mtime = fileMetadata .getModifiedTime ().getValue ();
338368
339- return new VersionedRook (repoId , RepoType .DROPBOX , repoUri , to , rev , mtime );
369+ return new VersionedRook (repoId , RepoType .GOOGLE_DRIVE , repoUri , to , rev , mtime );
340370
341371 } catch (Exception e ) {
342372 e .printStackTrace ();
0 commit comments