Google Drive REST API Notifications not working fo

2019-06-27 12:40发布

According to the documentation it should be possible to register a notification channel for changes to the app folder of my app, using setSpaces("appDataFolder").

However, I only get an initial sync notification when setting up the channel, but no change notifications when I change something in the app folder.

If I use setSpaces("drive") or omit the setSpaces() altogether and change something in regular drive space, I receive change notifications alright.

I didn't find anything about watching for changes in the app folder, so I hope someone here can help me.

This is how I set up the channel, where mDrive is a fully initialized and authorized instance of com.google.api.services.drive.Drive

channelId = UUID.randomUUID().toString();
channelExpiration = System.currentTimeMillis() + CHANNEL_LIVETIME_MILLIS;
Channel channel = new Channel();
channel.setType("web_hook");
channel.setId(channelId);
channel.setAddress(DRIVE_API_CALLBACK_RECEIVER_URL);
channel.setToken("...");
channel.setExpiration(channelExpiration);
Channel result = mDrive.changes().watch(channel).setSpaces("appDataFolder").execute();

1条回答
放我归山
2楼-- · 2019-06-27 13:37

Is there a scope where you set this up? Make sure you have a broad enough scope to include 'appDataFolder'. By this I mean you should be able to get some results from this (from here):

/**
 * Print metadata for the Application Data folder.
 *
 * @param service Drive API service instance.
 */
private static void printApplicationDataFolderMetadata(Drive service) {
  try {
    File file = service.files().get("appfolder").execute();

    System.out.println("Id: " + file.getId());
    System.out.println("Title: " + file.getTitle());
  } catch (IOException e) {
    System.out.println("An error occured: " + e);
  }
}

I think the above might be your problem. Whereever you are setting scope make sure to include the drive.appfolder or more formally

https://www.googleapis.com/auth/drive.appfolder

Furthermore, are you checking if result is null? You really should put the Channel result =... line in a try {} catch(IOExeption e) {} and print the error if there is one like in this example (from here).

  /**
   * Watch for all changes to a user's Drive.
   *
   * @param service Drive API service instance.
   * @param channelId Unique string that identifies this channel.
   * @param channelType Type of delivery mechanism used for this channel.
   * @param channelAddress Address where notifications are delivered.
   * @return The created channel if successful, {@code null} otherwise.
   */
  private static Channel watchChange(Drive service, String channelId,
      String channelType, String channelAddress) {
    Channel channel = new Channel();
    channel.setId(channelId);
    channel.setType(channelType);
    channel.setAddress(channelAddress);
    try {
      return service.changes().watch(channel).execute();
    } catch (IOException e) {
      e.printStackTrace();
      // ADD A LOG OR PRINT STATEMENT HERE 
      Log.e("DRIVEAPI", "Error: " + e.toString())
    }
    return null;
  }

Which for you code should look like this:

channelId = UUID.randomUUID().toString();
channelExpiration = System.currentTimeMillis() + CHANNEL_LIVETIME_MILLIS;
Channel channel = new Channel();
channel.setType("web_hook");
channel.setId(channelId);
channel.setAddress(DRIVE_API_CALLBACK_RECEIVER_URL);
channel.setToken("...");
channel.setExpiration(channelExpiration);
try {
    Channel result = mDrive.changes().watch(channel).setSpaces("appDataFolder").execute();
    if(result != null) {
        // do whatever you want with result Channel
    } else {
        Log.e("DRIVEAPI", "Error: result is null for some reason!");
    }
} catch (IOException e) {
    e.printStackTrace()
    Log.e("DRIVEAPI", "Error: " + e.toString());
}
查看更多
登录 后发表回答