2014-04-04 13 views
7

Vấn đề là các 'RESOURCEID' từ 'DriveId.getResourceId()' là không có sẵn (trả về NULL) trên các tập tin mới được tạo ra (sản phẩm của 'DriveFolder.createFile (GAC, meta, cont) '). Nếu tệp được truy lục bằng danh sách hoặc thủ tục truy vấn thông thường, thì 'resourceID' là chính xác.không thể đoán trước kết quả của DriveId.getResourceId() trong Google Drive Android API

Tôi nghi ngờ đây là vấn đề về thời gian/độ trễ, nhưng không rõ liệu có một hành động ứng dụng có thể buộc làm mới hay không. 'Drive.DriveApi.requestSync (GAC)' dường như không có hiệu lực.

Trả lời

15

CẬP NHẬT (07/22/2015)
Nhờ có sự trả lời nhanh chóng từ Steven Bazyl (xem bình luận dưới đây), tôi cuối cùng đã có một giải pháp thỏa đáng bằng Completion Events. Dưới đây là hai đoạn mã được rút gọn mà cung cấp những RESOURCEID để ứng dụng ngay sau khi tập tin mới được tạo ra là tuyên truyền để các Drive: tạo

File, thêm đăng ký thay đổi:

public class CreateEmptyFileActivity extends BaseDemoActivity { 
    private static final String TAG = "_X_"; 

    @Override 
    public void onConnected(Bundle connectionHint) { super.onConnected(connectionHint); 

    MetadataChangeSet meta = new MetadataChangeSet.Builder() 
     .setTitle("EmptyFile.txt").setMimeType("text/plain") 
     .build(); 

    Drive.DriveApi.getRootFolder(getGoogleApiClient()) 
     .createFile(getGoogleApiClient(), meta, null, 
     new ExecutionOptions.Builder() 
      .setNotifyOnCompletion(true) 
      .build() 
    ) 
     .setResultCallback(new ResultCallback<DriveFileResult>() { 
     @Override 
     public void onResult(DriveFileResult result) { 
      if (result.getStatus().isSuccess()) { 
      DriveId driveId = result.getDriveFile().getDriveId(); 
      Log.d(TAG, "Created a empty file: " + driveId); 
      DriveFile file = Drive.DriveApi.getFile(getGoogleApiClient(), driveId); 
      file.addChangeSubscription(getGoogleApiClient()); 
      } 
     } 
     }); 
    } 
} 

Dịch vụ tổ chức sự kiện, sản lượng đánh bắt hoàn thành:

public class ChngeSvc extends DriveEventService { 
    private static final String TAG = "_X_"; 

    @Override 
    public void onCompletion(CompletionEvent event) { super.onCompletion(event); 
    DriveId driveId = event.getDriveId(); 
    Log.d(TAG, "onComplete: " + driveId.getResourceId()); 
    switch (event.getStatus()) { 
     case CompletionEvent.STATUS_CONFLICT: Log.d(TAG, "STATUS_CONFLICT"); event.dismiss(); break; 
     case CompletionEvent.STATUS_FAILURE: Log.d(TAG, "STATUS_FAILURE"); event.dismiss(); break; 
     case CompletionEvent.STATUS_SUCCESS: Log.d(TAG, "STATUS_SUCCESS "); event.dismiss(); break; 
    } 
    } 
} 

trong những trường hợp bình thường (wifi), tôi nhận được RESOURCEID gần như ngay lập tức.

20:40:53.247﹕Created a empty file: DriveId:CAESABiiAiDGsfO61VMoAA== 
20:40:54.305: onComplete, ResourceId: 0BxOS7mTBMR_bMHZRUjJ5NU1ZOWs 

... thực hiện ngay bây giờ.

BÀI ĐĂNG ORIGINAL, không được chấp thuận, để lại ở đây để tham khảo.

Tôi để câu trả lời này được đặt trong một năm với hy vọng rằng GDAA sẽ phát triển một giải pháp hoạt động. Lý do cho việc nagging của tôi rất đơn giản. Nếu ứng dụng của tôi tạo ra một tệp, nó cần phát sóng sự kiện này cho bạn bè của nó (ví dụ các thiết bị khác) với một ID có ý nghĩa (đó là ResourceId). Đây là một nhiệm vụ tầm thường dưới REST Api, nơi ResourceId quay lại ngay sau khi tệp được tạo thành công.

Kim để nói rằng tôi hiểu triết lý GDAA che chắn ứng dụng từ mạng nguyên thủy, bộ nhớ đệm, theo đợt, ... Nhưng rõ ràng, trong tình huống này, ResourceID có sẵn lâu trước khi nó được gửi đến ứng dụng.

Ban đầu, tôi thực hiện đề nghị Cheryl Simon và thêm một ChangeListener trên một tập tin mới được tạo ra, hy vọng để có được những RESOURCEID khi tập tin được phổ biến.Sử dụng cổ điển CreateEmptyFileActivity từ android-demo, tui đã đánh cùng các mã kiểm tra sau đây:

public class CreateEmptyFileActivity extends BaseDemoActivity { 
    private static final String TAG = "CreateEmptyFileActivity"; 

    final private ChangeListener mChgeLstnr = new ChangeListener() { 
    @Override 
    public void onChange(ChangeEvent event) { 
     Log.d(TAG, "event: " + event + " resId: " + event.getDriveId().getResourceId()); 
    } 
    }; 


    @Override 
    public void onConnected(Bundle connectionHint) { super.onConnected(connectionHint); 

    MetadataChangeSet meta = new MetadataChangeSet.Builder() 
     .setTitle("EmptyFile.txt").setMimeType("text/plain") 
     .build(); 

    Drive.DriveApi.getRootFolder(getGoogleApiClient()) 
     .createFile(getGoogleApiClient(), meta, null) 
     .setResultCallback(new ResultCallback<DriveFileResult>() { 
     @Override 
     public void onResult(DriveFileResult result) { 
      if (result.getStatus().isSuccess()) { 
      DriveId driveId = result.getDriveFile().getDriveId(); 
      Log.d(TAG, "Created a empty file: " + driveId); 
      Drive.DriveApi.getFile(getGoogleApiClient(), driveId).addChangeListener(getGoogleApiClient(), mChgeLstnr); 
      } 
     } 
     }); 
    } 
} 

... và đang chờ đợi một cái gì đó xảy ra. Tệp đã được tải lên hạnh phúc lên số Drive trong vòng vài giây, nhưng không có sự kiện onChange(). 10 phút, 20 phút, ... Tôi không thể tìm ra cách làm cho ChangeListener thức dậy.

Vì vậy, giải pháp duy nhất khác, tôi có thể đưa ra là thúc đẩy GDAA. Vì vậy, tôi thực hiện một cách đơn giản handler-poker tickles siêu dữ liệu cho đến khi một cái gì đó sẽ xảy ra:

public class CreateEmptyFileActivity extends BaseDemoActivity { 
    private static final String TAG = "CreateEmptyFileActivity"; 

    final private ChangeListener mChgeLstnr = new ChangeListener() { 
    @Override 
    public void onChange(ChangeEvent event) { 
     Log.d(TAG, "event: " + event + " resId: " + event.getDriveId().getResourceId()); 
    } 
    }; 

    static DriveId driveId; 
    private static final int ENOUGH = 4; // nudge 4x, 1+2+3+4 = 10seconds 
    private static int mWait = 1000; 
    private int mCnt; 
    private Handler mPoker; 
    private final Runnable mPoke = new Runnable() { public void run() { 
    if (mPoker != null && driveId != null && driveId.getResourceId() == null && (mCnt++ < ENOUGH)) { 
     MetadataChangeSet meta = new MetadataChangeSet.Builder().build(); 
     Drive.DriveApi.getFile(getGoogleApiClient(), driveId).updateMetadata(getGoogleApiClient(), meta).setResultCallback(
     new ResultCallback<DriveResource.MetadataResult>() { 
      @Override 
      public void onResult(DriveResource.MetadataResult result) { 
      if (result.getStatus().isSuccess() && result.getMetadata().getDriveId().getResourceId() != null) 
       Log.d(TAG, "resId COOL " + result.getMetadata().getDriveId().getResourceId()); 
      else 
       mPoker.postDelayed(mPoke, mWait *= 2); 
      } 
     } 
    ); 
    } else { 
     mPoker = null; 
    } 
    }}; 

    @Override 
    public void onConnected(Bundle connectionHint) { super.onConnected(connectionHint); 

    MetadataChangeSet meta = new MetadataChangeSet.Builder() 
     .setTitle("EmptyFile.txt").setMimeType("text/plain") 
     .build(); 

    Drive.DriveApi.getRootFolder(getGoogleApiClient()) 
     .createFile(getGoogleApiClient(), meta, null) 
     .setResultCallback(new ResultCallback<DriveFileResult>() { 
     @Override 
     public void onResult(DriveFileResult result) { 
      if (result.getStatus().isSuccess()) { 
      driveId = result.getDriveFile().getDriveId(); 
      Log.d(TAG, "Created a empty file: " + driveId); 
      Drive.DriveApi.getFile(getGoogleApiClient(), driveId).addChangeListener(getGoogleApiClient(), mChgeLstnr); 

      mCnt = 0; 
      mPoker = new Handler(); 
      mPoker.postDelayed(mPoke, mWait); 
      } 
     } 
     }); 
    } 
} 

Và thì đấy, 4 giây (cho hoặc mất) sau đó, ChangeListener cung cấp một RESOURCEID sáng bóng mới. Tất nhiên, các ChangeListener trở nên lỗi thời, kể từ khi thói quen poker được ResourceId là tốt.

Vì vậy, đây là câu trả lời cho những người không thể đợi ResourceId. Câu trả lời tiếp theo:

Tại sao tôi phải đánh dấu siêu dữ liệu (hoặc cam kết lại nội dung), rất có thể tạo lưu lượng truy cập mạng không cần thiết, để nhận được sự kiện onChange(), khi tôi thấy rõ ràng tệp đã được phổ biến từ lâu rồi và GDAA có sẵn ResourceId không?

+0

Đối với trường hợp sử dụng của bạn, tôi nghĩ bạn đang tìm kiếm nhiều hơn cho người nghe hoàn thành thay vì người nghe thay đổi. Kết quả bạn thấy với người nghe thay đổi được mong đợi. Bạn không thêm trình xử lý thay đổi cho đến khi gọi lại kết quả, * sau * bạn đã thực hiện thay đổi. Vì vậy, yeah, bạn sẽ không nhận được bất kỳ bản cập nhật cho đến khi * tiếp theo * thời gian bạn tickle tập tin. Xem https://developers.google.com/drive/android/completion để biết cách nhận thông báo khi thay đổi được truyền cho máy chủ. Đó là sự kiện bạn quan tâm nếu bạn muốn lấy ID tệp cơ bản. –

+0

Cảm ơn, xin lỗi tôi không biết về 'hoàn thành' không có xung quanh khi tôi đã có vấn đề này ban đầu. Và tôi đã ở trong 'vũ trụ REST Api' kể từ đó, vì vậy tôi đã bỏ lỡ nó. Sẽ thử nó. – seanpj

9

ResourceIds trở nên khả dụng khi tài nguyên mới được tạo được cam kết với máy chủ. Trong trường hợp thiết bị ngoại tuyến, điều này có thể tùy ý kéo dài sau khi tạo tệp ban đầu. Nó sẽ xảy ra càng sớm càng tốt sau khi yêu cầu tạo ra, vì vậy bạn không cần phải làm bất cứ điều gì để tăng tốc nó cùng.

Nếu bạn thực sự cần nó ngay lập tức, bạn có thể sử dụng số change notifications để nghe cho resourceId thay đổi.

+0

Cảm ơn bạn, ngay cả khi điều này không phải là mới. Hầu hết các sự cố này đang xảy ra vì tôi phải trộn RESTFul với GDAA. (ví dụ tôi tạo một tệp trong GDAA và phải tải lên 'mô tả' thông qua RESTful, nhưng không có resID xung quanh). Mã này là một mớ hỗn độn ngay bây giờ, nhưng ít nhất tôi đã có tất cả các căn cứ được bảo hiểm và khi bạn tiếp tục thêm công cụ, có vẻ như nó xuống dốc từ đây. – seanpj

+0

Mất bao lâu để cam kết? – Nabin

Các vấn đề liên quan