Google Drive Android API - Проверьте, существует ли папка
Я пытаюсь выяснить, как проверить, существует ли папка на Google Диске с помощью нового Google Drive Android API
Я попробовал следующее, думая, что он либо вылетит, либо вернет ноль, если папка не найдена, но он этого не делает (если только это действительный идентификатор DriveId, даже если папка была удалена).
DriveFolder folder = Drive.DriveApi.getFolder(getGoogleApiClient(), driveId));
Если я пытаюсь создать файл в папке, полученной из приведенного выше кода, он тоже не вылетает? Я, очевидно, испытываю определенные трудности с пониманием того, как этот новый API работает вместе, особенно с очень ограниченными учебниками и SO вопросами, и я действительно застрял на этом, так что любой вклад будет высоко оценен.
Просто чтобы прояснить мою проблему: я создаю файл в указанной папке на Google Диске, но если папка не существует (была удалена пользователем), я хочу сначала создать ее.
3 ответа
После долгих исследований это код, которым я закончил. Он работает правильно, но имеет проблему: когда папка удаляется в Google Диске, требуется некоторое время (часы), чтобы обновить метаданные, которые я могу извлечь из моего приложения, что означает, что этот код может сначала определить, была ли папка удалена Через пару часов действительно произошло событие, связанное с разгромом - дополнительную информацию и обсуждения можно найти здесь.
public class checkFolderActivity extends BaseDemoActivity {
@Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
DriveId folderId = DriveId.decodeFromString(folderId);
DriveFolder folder = Drive.DriveApi.getFolder(mGoogleApiClient, folderId);
folder.getMetadata(mGoogleApiClient).setResultCallback(metadataRetrievedCallback);
}
final private ResultCallback<DriveResource.MetadataResult> metadataRetrievedCallback = new
ResultCallback<DriveResource.MetadataResult>() {
@Override
public void onResult(DriveResource.MetadataResult result) {
if (!result.getStatus().isSuccess()) {
Log.v(TAG, "Problem while trying to fetch metadata.");
return;
}
Metadata metadata = result.getMetadata();
if(metadata.isTrashed()){
Log.v(TAG, "Folder is trashed");
}else{
Log.v(TAG, "Folder is not trashed");
}
}
};
}
Если вы создаете папку, основываясь на ее состоянии существования, метод 'createTree()' здесь делает именно это.
Следующие 2 фрагмента кода содержат список файлов / папок на основе переданных аргументов (внутри папки, глобально, на основе типа MIME...). Строка с md.getTitle() - это та, которую вы можете использовать для опроса файлов / папок.
GoogleApiClient _gac;
void findAll(String title, String mime, DriveFolder fldr) {
ArrayList<Filter> fltrs = new ArrayList<Filter>();
fltrs.add(Filters.eq(SearchableField.TRASHED, false));
if (title != null) fltrs.add(Filters.eq(SearchableField.TITLE, title));
if (mime != null) fltrs.add(Filters.eq(SearchableField.MIME_TYPE, mime));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
MetadataBufferResult rslt = (fldr == null) ? Drive.DriveApi.query(_gac, qry).await() :
fldr.queryChildren(_gac, qry).await();
if (rslt.getStatus().isSuccess()) {
MetadataBuffer mdb = null;
try {
mdb = rslt.getMetadataBuffer();
if (mdb == null) return null;
for (Metadata md : mdb) {
if ((md == null) || md.isTrashed()) continue;
--->>>> md.getTitle()
}
} finally { if (mdb != null) mdb.close(); }
}
}
void listAll(DriveFolder fldr) {
MetadataBufferResult rslt = fldr.listChildren(_gac).await();
if (rslt.getStatus().isSuccess()) {
MetadataBuffer mdb = null;
try {
mdb = rslt.getMetadataBuffer();
if (mdb == null) return null;
for (Metadata md : mdb) {
if ((md == null) || md.isTrashed()) continue;
--->>>> md.getTitle()
}
} finally { if (mdb != null) mdb.close(); }
}
}
Ключ, вероятно, проверяет статус "isTrashed()". Поскольку "удалить" файл в Интернете только перемещает его в корзину. Кроме того, удаление в целом (на веб-сайте, так как в API нет "УДАЛИТЬ") немного ненадежно. Я тестировал его некоторое время, и может пройти несколько часов, прежде чем обновится статус "isTrashed()". И ручная очистка корзины в Google Диске также ненадежна. Смотрите эту проблему на Github.
Здесь немного больше разговоров, но, вероятно, не связанных с вашей проблемой.
Так что сегодня ответ - устаревший API. Итак, я опубликовал пример того, как проверить, существует ли папка с новым обновлением документации:
fun checkFolder(name: String):Boolean {
check(googleDriveService != null) { "You have to init Google Drive Service first!" }
return search(name, FOLDER_MIME_TYPE)
}
private fun search(name: String, mimeType:String): Boolean {
var pageToken: String? = null
do {
val result: FileList =
googleDriveService!!
.files()
.list()
.setQ("mimeType='$FOLDER_MIME_TYPE'")
.setSpaces("drive")
.setFields("nextPageToken, files(id, name)")
.setPageToken(pageToken)
.execute()
for (file in result.files) {
Log.d(TAG_UPLOAD_FILE , "Found file: %s (%s)\n ${file.name}, ${file.id} ")
if (name == file.name) return true
}
pageToken = result.nextPageToken
} while (pageToken != null)
return false
}
private const val FOLDER_MIME_TYPE= "application/vnd.google-apps.folder"
Вы можете попытаться получить метаданные для папки. Если папка не существует, это не удастся.