DriveFolder.listChildren() не показва всички свои деца

Създавам приложение, което работи с Google Drive.

Трябва да получа списък с ВСИЧКИ файлове в папка, но изглежда, че не е възможно: когато извикам listFiles method(), не мога да получа всички файлове в DriveFolder. Но не само това, в списъка с файлове, които получавам, има някои файлове, които съм изтрил преди това.

Прочетох, че може да е причинено от забавяне на синхронизирането поради услугите на Google Play, но бях избрал опцията „Синхронизиране сега“ в настройките на моя акаунт, така че мисля, че проблемът не е причинен от това забавяне.

Това е методът, за който говоря http://developer.android.com/reference/com/google/android/gms/drive/DriveFolder.html#listChildren(com.google.android.gms.common).api.GoogleApiClient)

И това е кодът, който съм написал:

public class ServicePull extends IntentService implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener{

private GoogleApiClient mApiClient;

public static void startPull(Context context) {
    Intent intent = new Intent(context, ServicePull.class);
    context.startService(intent);
}

public ServicePull() {
    super("ServicePull");
}

@Override
protected void onHandleIntent(Intent intent) {
    mApiClient = new GoogleApiClient.Builder(this)
            .addApi(Drive.API)
            .addScope(Drive.SCOPE_FILE)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

    mApiClient.connect();
}



@Override
public void onConnected(Bundle bundle) {
    NotificationStatus.notify(this, "On Connected", "mApiClient Connected");
    DriveFolder driveFolder = Drive.DriveApi.getRootFolder(mApiClient);
    driveFolder.listChildren(mApiClient).setResultCallback(rootFolderCallback);
}

@Override
public void onConnectionSuspended(int i) {
    NotificationStatus.notify(this, "On Suspended", "mApiClient Suspended");
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    NotificationStatus.notify(this, "On failed", "mApiClient failed");
}

final private ResultCallback<DriveApi.MetadataBufferResult> rootFolderCallback =
        new ResultCallback<DriveApi.MetadataBufferResult>() {
            @Override
            public void onResult(DriveApi.MetadataBufferResult metadataBufferResult) {
                log("got root folder");
                MetadataBuffer buffer = metadataBufferResult.getMetadataBuffer();
                log("Buffer count  " + buffer.getCount());
                for(Metadata m : buffer){
                    log("Metadata name  " + m.getTitle() + "(" + (m.isFolder() ? "folder" : "file") + ")");
                    if (m.isFolder() && m.getTitle().equals("Neewie"))
                        Drive.DriveApi.getFolder(mApiClient, m.getDriveId())
                                .listChildren(mApiClient)
                                .setResultCallback(fileCallback);
                }
            }
};

final private ResultCallback<DriveApi.MetadataBufferResult> fileCallback =
        new ResultCallback<DriveApi.MetadataBufferResult>() {
            @Override
            public void onResult(DriveApi.MetadataBufferResult metadataBufferResult) {
                log("got file children");
                MetadataBuffer buffer = metadataBufferResult.getMetadataBuffer();
                //for(Metadata m : buffer){
                log("Buffer count  " + buffer.getCount());
                for(int i =0;i<buffer.getCount();i++){
                    Metadata m = buffer.get(i);
                    log(m.toString());
                    Drive.DriveApi.getFile(mApiClient, m.getDriveId())
                            .openContents(mApiClient, DriveFile.MODE_READ_ONLY,
                                    new DriveFile.DownloadProgressListener() {
                                        @Override
                                        public void onProgress(long bytesDownloaded, long bytesExpected) {
                                            // Update progress dialog with the latest progress.
                                            int progress = (int) (bytesDownloaded * 100 / bytesExpected);
                                            Log.wtf("TAG", String.format("Loading progress: %d percent", progress));
                                        }
                                    }
                            )
                            .setResultCallback(contentsCallback);
                }
            }
};


final private ResultCallback<DriveApi.ContentsResult> contentsCallback =
        new ResultCallback<DriveApi.ContentsResult>() {
            @Override
            public void onResult(DriveApi.ContentsResult contentsResult) {
                log("got file contents");
                File file = new File("storage/emulated/0/Downtests/tessing.txt");
                file.mkdirs();
                try {
                    InputStream input = contentsResult.getContents().getInputStream();
                    OutputStream output = new FileOutputStream(file);
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = input.read(buf)) > 0) {
                        output.write(buf, 0, len);
                    }
                    input.close();
                    output.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }


            }
        };

private void log(String s){
    Log.wtf("ServicePull", s);
}



}

Очевидно създадох папка, наречена „Neewie“ и вътре в нея файл. Имам DriveFolder, сочещ към папка Neewie, но когато го изписвамChildren, получавам MetadataBuffer с брой 0.

Трябва ли да направя нещо, за да изброя ВСИЧКИ файлове? Нещо не е наред с gms библиотеката?


person BamsBamx    schedule 14.03.2014    source източник


Отговори (2)


Ще ми отнеме много време да повторя вашия пример, но може да имам няколко точки, за да ви изпреваря.

Първо, тъй като все още няма функционалност DELETE в Google Drive Android API, вероятно имате предвид действието „премахване“ в интерфейса на уеб Drive. Състоянието Metadata.isTrashed() не отразява правилно състоянието, както обсъдено тук . И използването на requestSync() не помогна. Но оставих този проблем, тъй като очаквам да го поправят с внедряването на DELETE в GDAA. Повече за DELETE можете да намерите тук.

Второ, използвам версията „изчакване“ на извикванията в моята тестова среда (обвита в AsyncTask), за да тествам нещата. Много по-лесно се прекрачва. От време на време съм изпитвал някакво "странно" поведение, но не можах да го определя. Поправи го чрез изчистване на Google Кеш на услугите на Play.

Трето, има клас обвивка на клиент на Google Api GooApiClnt в този код (в долната част), който изглежда дава стабилни резултати - можете да опитате. Можете да тествате версиите 'findAll' (т.е. DriveApi.query) вместо 'listAll' (т.е. listChildren), тъй като ви позволява да филтрирате състоянието TRASHED предварително. Между другото, забелязах, че не регистрирате състоянието Metadata.isTrashed() във вашия пример. Това би дало по-добра представа какви файлове са били изтрити. Но отново, това само ще потвърди проблемите със забавянето на синхронизирането.

Последният, незначителен проблем - и не знам дали вече не е бил коригиран на ниво GDAA - освобождаването/затварянето на "getMetadataBuffer". Това причиняваше изтичане на ресурси в моя код. Отново вижте кода на Github, посочен по-горе, grep 'mdb.close()'.

Приятно кодиране и успех

person seanpj    schedule 15.03.2014
comment
Ами пробвах клас GooApiClnt... findAll() и listAll() ще дадат едни и същи идентификатори на файлове. Все още обаче има някои файлове в GDrive, които не са в дадения ArrayList :( Мисля, че единствените файлове, които са в списъка, са тези, които са качени от моето приложение... Толкова е странно - person BamsBamx; 16.03.2014
comment
Като цяло GDAA не е съвсем готов за праймтайм, получавам всякакви необичайни проблеми (като днес createFolder() създаде 3 папки с едно и също име), които обикновено не мога да репликирам. Има проблеми с времето, като SO 22381649, проблем с времето за „изтриване“, ... Но ще се подобри, предполагам. Внимавайте, променям GooApiClnt доста често, току-що добавих изтриване/кошче, вижте SO 22295903. - person seanpj; 16.03.2014
comment
За съжаление, SO 22295903 = stackoverflow.com/questions/22295903/ - person seanpj; 16.03.2014
comment
Е, най-накрая ще използвам стария API.... Изглежда, че Google Drive Android API все още не е трябвало да бъде пуснат... - person BamsBamx; 16.03.2014
comment
Това е дилема, няма съмнение, че накрая ще бъде по-добър от стария. Не бързам с развитието си, просто може да ми отнеме достатъчно време, за да се слея с окончателния GDAA накрая. - person seanpj; 16.03.2014

Опитах този подход и също така открих, че не всички файлове се връщат. За съжаление това поведение е умишлено =(

Цитирам от документацията:

„Понастоящем API на Google Drive за Android поддържа само drive.file и drive.appfolder“

drive.file (Drive.SCOPE_FILE) означава: „Достъп до файлове, създадени или отворени от приложението“

„Това означава, че само файлове, които потребителят е отворил или създал с вашето приложение, могат да бъдат съпоставени със заявка“

Вижте:

https://developers.google.com/drive/android/auth

https://developers.google.com/drive/android/queries

person Bleifuss    schedule 29.12.2016