问题描述
我正在制作一个适用于谷歌驱动器的应用程序。
我需要获取文件夹中所有文件的列表,但似乎不可能:当我调用listFiles方法()时,我无法获取DriveFolder中的所有文件。 但不仅如此,在我获得的文件列表中,还有一些我之前删除的文件。
我已经读过它可能是由于谷歌播放服务造成的同步延迟造成的,但我在我的帐户设置中选择了“立即同步”选项,所以我认为问题不是由延迟造成的。
这是我正在讨论的方法
这是我写的代码:
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库有问题吗?
1楼
我需要很长时间来重新运行你的例子,但我可能会有一些积分让你领先。
首先,由于Google Drive Android API中还没有DELETE功能,您可能是指Web Drive界面中的“删除”操作。 状态Metadata.isTrashed()未正确反映所述的状态。 使用requestSync()没有帮助。 但是我想让这个问题继续下去,因为我希望他们通过在GDAA中实现DELETE来修复它。 有关DELETE的更多信息,请 。
其次,我在我的测试环境中使用“await”版本的调用(包含在AsyncTask中)来测试。 单步执行要容易得多。 我偶尔经历过一些“怪异”的行为,但无法确定它。 通过修复此问题。
第三,在此代码(底部)中有一个 ,它似乎可以产生稳定的结果 - 您可以尝试一下。 您可以测试'findAll'(即DriveApi.query)版本而不是'listAll'(即listChildren),因为它允许您预先过滤TRASHED状态。 顺便说一句,我注意到你没有在你的例子中记录Metadata.isTrashed()状态。 它可以更好地查看删除的文件。 但同样,它只会确认同步延迟问题。
最后一个小问题 - 我不知道它是否已经在GDAA级别上修复 - 发布/关闭'getMetadataBuffer'。 它导致我的代码中的资源泄漏。 再次,请参阅上面引用的Github代码,grep'mdb.close()'。
快乐的编码和祝你好运
2楼
我尝试过这种方法,并且我发现并非所有文件都被返回。 不幸的是,这种行为是有意的=(
我引用文档:
“Google Drive Android API目前仅支持drive.file和drive.appfolder”
drive.file(Drive.SCOPE_FILE)表示:“对应用程序创建或打开的文件的每个文件访问权限”
“这意味着只有用户使用您的应用程序打开或创建的文件才能与查询匹配”
看到: