1

Using the new GDAA, as I understand it, in order to access a folder and its contents you have to have the folder's DriveId - because this insures that an app can only access the content it has created itself.

Now, my app uploads files to the user's Google Drive account (pictures) in a custom folder. When this folder is first created I save the DriveId of the folder to Shared Preferences so I can access the folder later for more uploads. My problem is that I would like the user to be able to access the pictures from multiple devices (so he/she e.g. can look at pictures uploaded from his/her phone while being on a tablet and vice versa), but this I cannot do without having the folder's DriveId on both devices. The only solution I can think of is sharing the DriveId between user's devices via some cloud service, but this seems awfully inconvenient for the purpose.

Any thoughts?

Jakob Harteg
  • 9,587
  • 15
  • 56
  • 78

2 Answers2

3

Shamelessly promoting myself to Cheryl's sidekick, I can give you some specific points, since I've run through this gauntlet before. This is what I did:

  1. Create a unique 'root' for my app in the system root - "MyStupidAppRoot'. Here you'll hit the main challenge since you are creating it by name and if you base the creation on it's non-existence, you may not reliably be able to check it. But it is getting better, see SO 22382099 and SO 22515028.
  2. Once you have a reliable anchor 'MyStupidAppRoot', you can create AppFolder mentioned by Cheryl (not available yet) or create you own visible file (again, the unique creation challenge) that can keep anything you want. Like for instance all your PREFERENCE strings. I even got so brave as to store full SQLite DB file there. It is possible since you write a byte[] buffer to a file.
  3. Than, any other device with you app can find 'MyStupidAppRoot', get the resource file from there and read it.

It should be noted that the main difference between you own folder/file and the AppFolder is, that user's can't read the contents of an AppFolder, but can still delete it.

Here's how you can write byte[] buffer to a file. It is the 'await' version to make it simple, but there is an async version 'createFileAsync()' here.

 public DriveFile createFileWait(DriveFolder fldr, String name, String mime, byte[] buff) {
  DriveFile drvFile = null;
  if (isConnected()) try { 
    ContentsResult rslt = Drive.DriveApi.newContents(_gac).await();
    if (rslt.getStatus().isSuccess()) {
      Contents cont = rslt.getContents();    
      cont.getOutputStream().write(buff);
      MetadataChangeSet meta = (mime == null) ?
          new MetadataChangeSet.Builder().setTitle(name).build() :
          new MetadataChangeSet.Builder().setTitle(name).setMimeType(mime).build();
      drvFile = fldr.createFile(_gac, meta, cont).await().getDriveFile();
    }
  } catch (Exception e) {}
  return drvFile;
}

About the IDs:

The DriveId you mention above is an object, that can be turned into 2 different strings as discussed in SO 21800257. It is up to you which one you choose. The long one from 'encodeToString()' is easier to turn back into DriveId by 'decodeFromString()', the shorter one can be easily recognized in the http address, but takes async / await method to get back the DriveId - fetchDriveId().

Community
  • 1
  • 1
seanpj
  • 6,735
  • 2
  • 33
  • 54
  • If it sounds like a shameless self-promotion, believe me, it is: Since you're probably going through the same maze as I did, I would recommend you pull the code from github here https://github.com/seanpjanson/140201-GDAA to test all your theories and find snags before they hit you in your app. It is one single file with no UI and covers all major functions. 'await' versions in AsyncTask' should be easy to step through. – seanpj Mar 20 '14 at 12:00
  • at Jakob: One more thing just popped up in my mind: If you your app handles more than one account, saving your config in the known position of the Drive allows you to download correct app state for each user. – seanpj Mar 21 '14 at 12:28
  • In a really unrelated to the question manner, your answer helped me, so here is my upvote ^_^ – Redwarp May 15 '14 at 17:53
1

You don't necessarily have to have the DriveId, its just the most sure-fire way to do it since it uniquely identifies the folder. You can also query based on the title to try to find the same folder. Assuming that the web and Android app share an app id, both should be able to access the same files.

One easy option for sharing state between apps is to make use of the newly launched App Folders (called App Data Folders on the web.) This is a hidden folder where you can store files specific to your app. Its not yet in the Android docs, but it should show up there as soon as the rollout of Google Play Services 4.3 is released. See http://android-developers.blogspot.com/2014/03/google-play-services-43.html

Cheryl Simon
  • 46,552
  • 15
  • 93
  • 82
  • huh, okay. Thank you very much. Was almost certain that there was some restriction saying that the app could only access "self-created" files, but great. And I'm just loving how the Play Services keeps getting better. I think I will go for that list-all-files-and-look-for-my-folder solution, hah. Thanks again. – Jakob Harteg Mar 19 '14 at 21:50