4

Google ドライブで動作するアプリを作成しています。

フォルダー内のすべてのファイルのリストを取得する必要がありますが、それは不可能のようです: 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」というフォルダーを作成し、その中にファイルを作成しました。私は、Neewie フォルダーを指す DriveFolder を取得しましたが、listChildren を実行すると、カウント 0 の MetadataBuffer を受け取ります。

すべてのファイルをリストするために何かをする必要がありますか? gms ライブラリに何か問題がありますか?

4

2 に答える 2

1

あなたの例を再実行するには長い時間がかかりますが、先に進むためにいくつかのポイントがあるかもしれません.

まず、Google Drive Android API にはまだ DELETE 機能がないため、Web Drive インターフェースの「削除」アクションについて言及している可能性があります。ここで説明されているように、ステータス Metadata.isTrashed() はステータスを正しく反映していません。requestSync()を使用しても役に立ちませんでした。しかし、GDAA での DELETE の実装で修正されることを期待しているため、この問題は手放しました。DELETE の詳細については、こちらを参照してください。

次に、テスト環境 (AsyncTask にラップされている) で "await" バージョンの呼び出しを使用してテストを行います。ステップスルーする方がはるかに簡単です。私は時々「奇妙な」動作を経験しましたが、それを特定することはできませんでした. Google Play サービスのキャッシュをクリアすることで修正されました。

第 3 に、 このコード (一番下) にはGoogle Api Client ラッパー クラスGooApiClntがあり、安定した結果が得られるようです。試してみてください。「listAll」(ie listChildren) の代わりに「findAll」(ie DriveApi.query) バージョンをテストできます。これは、TRASHED 状態を前もってフィルタリングできるためです。ところで、あなたの例では Metadata.isTrashed() ステータスを記録していないことに気付きました。どのファイルが削除されたかをよりよく把握できます。ただし、これは同期遅延の問題を確認するだけです。

最後の小さな問題 - GDAA レベルでまだ修正されていないかどうかはわかりません - 「getMetadataBuffer」のリリース/クローズ。私のコードでリソースリークが発生していました。ここでも、上記の Github コード grep 'mdb.close()' を参照してください。

幸せなコーディングと幸運

于 2014-03-15T12:53:53.267 に答える
0

このアプローチを試してみましたが、すべてのファイルが返されるわけではないこともわかりました。残念ながら、この動作は意図的なものです =(

ドキュメントから引用します:

「Google Drive Android API は現在、drive.file と drive.appfolder のみをサポートしています」

drive.file (Drive.SCOPE_FILE) の意味: 「アプリによって作成または開かれたファイルへのファイルごとのアクセス」

「これは、ユーザーがアプリケーションで開いた、または作成したファイルのみがクエリで一致できることを意味します」

見る:

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

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

于 2016-12-29T03:58:41.883 に答える