2014-04-04 11 views
7

मुद्दा यह है कि से 'DriveId.getResourceId()' 'RESOURCEID' (नई बनाई गई फ़ाइलों पर उपलब्ध (NULL भेजता है) नहीं है 'का उत्पाद है ड्राइवफोल्डर .createFile (जीएसी, मेटा, cont) ')। अगर फ़ाइल नियमित सूची या क्वेरी प्रक्रिया द्वारा पुनर्प्राप्त की जाती है, तो 'resourceID' सही है।अप्रत्याशित परिणाम

मुझे संदेह है कि यह एक समय/विलंबता मुद्दा है, लेकिन यह स्पष्ट नहीं है कि कोई एप्लिकेशन क्रिया है जो ताज़ा करने के लिए मजबूर करेगी। 'ड्राइव। DriveApi.requestSync (GAC)' का कोई प्रभाव नहीं पड़ता है।

उत्तर

15

अद्यतन (2015/07/22)
स्टीवन Bazyl से त्वरित प्रतिक्रिया (नीचे टिप्पणी देखें) के लिए धन्यवाद, मैं अंत में एक संतोषजनक समाधान Completion Events का उपयोग कर सकते है।

फ़ाइल बनाना, परिवर्तन सदस्यता को जोड़ना:

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()); 
      } 
     } 
     }); 
    } 
} 

इवेंट सेवा, कैच यहाँ दो minified कोड के टुकड़े है कि जैसे ही नई बनाई गई फ़ाइल डिस्क में प्रचारित किया जाता है अनुप्रयोग के लिए RESOURCEID देने हैं पूरा होने:

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; 
    } 
    } 
} 

सामान्य परिस्थितियों (वाईफाई) के तहत, मैं लगभग तुरंत RESOURCEID मिलता है।

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

... अभी के लिए किया गया।

मूल पोस्ट, बहिष्कृत, संदर्भ के लिए यहां छोड़ा गया।

मैंने यह जवाब एक वर्ष के लिए बैठने की उम्मीद की है कि GDAA एक समाधान विकसित करेगा जो काम करता है। मेरे घबराहट का कारण सरल है। यदि मेरा ऐप एक फाइल बनाता है, तो इसे इस तथ्य को अपने मित्रों (उदाहरण के लिए, अन्य डिवाइस) को एक आईडी के साथ प्रसारित करने की आवश्यकता है जो अर्थपूर्ण है (वह संसाधन आईडी है)। यह REST एपीआई के तहत एक मामूली कार्य है जहां फ़ाइल सफलतापूर्वक बनाई गई है, जैसे संसाधन आईडी वापस आती है।

सुई कहने के लिए कि मैं नेटवर्क प्राइमेटिव्स, कैशिंग, बैचिंग से ऐप को बचाने के जीडीएए दर्शन को समझता हूं ... लेकिन स्पष्ट रूप से, इस स्थिति में, संसाधन आईडी ऐप को वितरित होने से काफी पहले उपलब्ध है।

मूल रूप से, मैं चेरिल साइमन के सुझाव लागू होने और नई बनाई गई फ़ाइल पर एक ChangeListener कहा, RESOURCEID पाने के लिए जब फाइल प्रचारित कर रहा है उम्मीद कर रहा।क्लासिक CreateEmptyFileActivityसे android-क़ौम का उपयोग करना, मैं एक साथ निम्नलिखित परीक्षण कोड मार:

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); 
      } 
     } 
     }); 
    } 
} 

... और कुछ तो होना ही इंतजार कर रहा था। फाइल को Drive पर सेकंड के भीतर खुशी से अपलोड किया गया था, लेकिन ऑन चेंज() इवेंट। 10 मिनट, 20 मिनट, ... मुझे कोई रास्ता नहीं मिला कि चेंजलिस्टर को जागने के लिए कैसे बनाया जाए।

तो एकमात्र अन्य समाधान, मैं आ सकता था जीडीएए को कुचलने के लिए।

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); 
      } 
     } 
     }); 
    } 
} 

और देखा, 4 सेकंड (दे या लेने के लिए) बाद में, ChangeListener एक नया चमकदार RESOURCEID उद्धार: तो मैं एक साधारण हैंडलर-पोकर कि मेटाडाटा गुदगुदी जब तक कुछ होता है कार्यान्वित किया। बेशक, चेंजलिस्टर इस प्रकार अप्रचलित हो जाता है, क्योंकि पोकर दिनचर्या भी संसाधन आईडी प्राप्त करता है।

तो यह उन लोगों के लिए उत्तर है जो संसाधन आईडी की प्रतीक्षा नहीं कर सकते हैं।

क्यों मैं मेटाडाटा गुदगुदी (या फिर से प्रतिबद्ध सामग्री) की क्या ज़रूरत है, बहुत संभव है अनावश्यक नेटवर्क यातायात का निर्माण, onChange() घटना प्राप्त करने के लिए, जब मैं स्पष्ट रूप से है कि देखें: कौन सा अनुवर्ती सवाल को लाता है फ़ाइल को बहुत समय पहले प्रचारित किया गया है, और जीडीएए में संसाधन आईडी उपलब्ध है?

+0

आपके उपयोग के मामले में, मुझे लगता है कि आप परिवर्तन श्रोता के बजाय पूर्णता श्रोता के लिए और अधिक देख रहे हैं। परिवर्तन श्रोता के साथ आप जो परिणाम देख रहे हैं, वे अपेक्षित हैं। आप परिणाम कॉलबैक तक परिवर्तन श्रोता नहीं जोड़ रहे हैं, * * के बाद * आपने परिवर्तन किया है। तो हाँ, आपको अगली बार जब तक आप फाइल को गुमराह करते हैं तब तक आपको कोई अपडेट नहीं मिलेंगे। सर्वर पर एक परिवर्तन प्रसारित होने पर अधिसूचित होने के तरीके के लिए https://developers.google.com/drive/android/completion देखें। अगर आप अंतर्निहित ड्राइव फ़ाइल आईडी प्राप्त करना चाहते हैं तो वह घटना है जिसमें आप रुचि रखते हैं। –

+0

धन्यवाद, क्षमा करें मुझे 'समापन' के बारे में पता नहीं था, जब मूल रूप से मुझे यह समस्या थी तब आसपास नहीं थे। और मैं 'रीस्ट एपी ब्रह्मांड' में रहा हूं, इसलिए मैंने इसे याद किया। कोशिश करो – seanpj

9

संसाधन निर्मित तब उपलब्ध हो जाते हैं जब नव निर्मित संसाधन सर्वर के लिए प्रतिबद्ध होता है। ऑफ़लाइन होने वाले डिवाइस के मामले में, प्रारंभिक फ़ाइल निर्माण के बाद यह मनमाने ढंग से लंबा हो सकता है। हालांकि सृजन अनुरोध के बाद जल्द से जल्द ऐसा होगा, इसलिए आपको इसे गति देने के लिए कुछ भी करने की आवश्यकता नहीं है।

यदि आपको वास्तव में इसकी आवश्यकता है, तो आप संसाधन बदलने के लिए change notifications का उपयोग कर सकते हैं।

+0

धन्यवाद, भले ही यह नया न हो। इनमें से अधिकतर हिक-अप हो रहे हैं क्योंकि मुझे रीस्टफुल को जीडीएए के साथ मिश्रण करना है। (उदाहरण के लिए मैं जीडीएए में एक फाइल बनाता हूं और रीस्टफुल के माध्यम से 'विवरण' अपलोड करना पड़ता हूं, लेकिन आसपास कोई रेजिड नहीं होता है)। कोड अभी एक गड़बड़ है, लेकिन कम से कम मुझे सभी अड्डों को कवर किया गया है और जैसे ही आप सामान जोड़ते रहते हैं, ऐसा लगता है कि यह यहां से नीचे की ओर है। – seanpj

+0

प्रतिबद्ध करने में कितना समय लगता है? – Nabin

संबंधित मुद्दे