为什么Google Drive SDK仅允许六个部分文件下载请求?

时间:2014-11-22 14:21:53

标签: java google-oauth google-drive-api google-oauth-java-client

我想部分阅读Google云端硬盘上的文件(Range requestPartial download)。此外,我想要串行执行 - 仅在读取前一个间隔(使用CountDownLatch)并在单独的线程(Android禁止主线程中的HTTP请求)之后读取下一个间隔。为此,我想实现ByteChannel方法:

@Override
public int read(final ByteBuffer dst) {
    final com.google.api.services.drive.model.File googleFile = mFile.getImpliedFile();
    final int bufferLength = dst.capacity();
    final int[] bytesReceived = {-1};
    final CountDownLatch latch = new CountDownLatch(1);
    new Thread(new Runnable(){
        public void run() {
            byte[] receivedByteArray = getByteArrayGoogle(mService, googleFile, position, bufferLength);
//            byte[] receivedByteArray = getByteArrayApache(googleFile, position, bufferLength);                

            dst.put(receivedByteArray, 0, receivedByteArray.length);
            bytesReceived[0] = receivedByteArray.length;
            position += receivedByteArray.length;
            latch.countDown();
        }
    }).start();
    try {
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return bytesReceived[0];
}

如果我使用谷歌推荐的谷歌google-api-services-drive-v2-rev151-1.18.0-rc.jar和google-api-client-assembly-1.18.0-rc-1.18.0-rc.zip

private byte[] getByteArrayGoogle(Drive drive, File file, long position, int byteCount) {
    String downloadUrl = file.getDownloadUrl();
    byte[] receivedByteArray = null;
    if (downloadUrl != null && downloadUrl.length() > 0) {
        try {
            com.google.api.client.http.HttpRequest httpRequestGet = drive.getRequestFactory().buildGetRequest(new GenericUrl(downloadUrl));
            httpRequestGet.getHeaders().setRange("bytes=" + position + "-" + (position + byteCount - 1));
            com.google.api.client.http.HttpResponse response = httpRequestGet.execute();
            InputStream is = response.getContent();
            receivedByteArray = IOUtils.toByteArray(is);
            response.disconnect();
            System.out.println("google-http-client-1.18.0-rc response: [" + position + ", " + (position + receivedByteArray.length - 1) + "]");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return receivedByteArray;
}

我永远不会读超过六个间隔!但是,如果我使用Apache HTTP客户端:

private byte[] getByteArrayApache(File file, long position, int byteCount) {
    String downloadUrl = file.getDownloadUrl();
    byte[] receivedByteArray = null;
    if (downloadUrl != null && downloadUrl.length() > 0) {
        try {
            org.apache.http.client.methods.HttpGet httpRequestGet = new HttpGet(downloadUrl);
            httpRequestGet.addHeader("Authorization", "Bearer " + GoogleDriveActivity.getAccessToken(mContext));
            httpRequestGet.addHeader("Range", "bytes=" + position + "-" + (position + byteCount - 1));
            org.apache.http.HttpResponse response = new DefaultHttpClient().execute(httpRequestGet);
            InputStream is = response.getEntity().getContent();
            receivedByteArray = IOUtils.toByteArray(is);
            System.out.println("apache-http-client response: [" + position + ", " + (position + receivedByteArray.length - 1) + "]");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return receivedByteArray;
}

我可以阅读所有需要的时间间隔。

问题似乎出现在com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential。RequestHandler

public void intercept(HttpRequest request) throws IOException {
  try {
    token = getToken();
    request.getHeaders().setAuthorization("Bearer " + token);
  } catch (GooglePlayServicesAvailabilityException e) {
    throw new GooglePlayServicesAvailabilityIOException(e);
  } catch (UserRecoverableAuthException e) {
    throw new UserRecoverableAuthIOException(e);
  } catch (GoogleAuthException e) {
    throw new GoogleAuthIOException(e);
  }
}

因为我无法获得token第七个请求,并且应用程序在调试时总是冻结。

token = getToken();     

1。这种奇怪的行为是什么原因以及如何使用Google API发出六个以上的请求?

2。是否有其他方法可以使用Google API进行部分下载?

P.S。顺便说一句,类RequestHandler有注释@Beta ...

COMMENT: 似乎问题出在Google Play服务专有类com.google.android.gms.auth.GoogleAccountCredential used for getting a token中:

GoogleAuthUtil.getToken(context, accountName, scope)

由于我怀疑GoogleAuthUtil.getToken必须使用主线程验证身份验证,但主要线程在等待请求结果时被CountDownLatch阻止。因此,我此时已陷入僵局。前六个请求是从AsyncTask执行的,它们不会阻塞主线程。

0 个答案:

没有答案