0

谷歌雲端硬盤API實現我有以下情形在我的應用程序 -從SherlockFragmentActivity行動吧

SherlockFragmentActivity託管包含3個獨立的片段一ViewPager。上面有一個sherlockactionbar,有備份和恢復選項,它們應該基本上將應用數據備份到谷歌賬戶(連接到用戶)。

現在,一切工作正常,通過打開Goog​​le Api Client連接和上傳/下載文件,以及備份還原,但只要設備旋轉,活動從頭開始重新啓動,谷歌API客戶端實例創建並實例化ealier(可能上傳/下載也在進行中)變成孤兒。

我得到一個IllegalStateException(由於活動重新啓動,而實例仍然需要一個原始活動來綁定)。

知道,碎片本身可以保留在整個活動重新啓動,我可以把驅動器API實施在片段,,但頂部有一個共同的操作欄圖標,這不是一個重複,只是把驅動器在所有3個碎片上執行?


另外,當ViewPager刷卡發生時,碎片將被改變,所以我不會再面對同樣的問題,其中原來的驅動api客戶端實例創建者碎片不在範圍內。

什麼是實施這樣的事情的好方法?任何想法都會幫助我在給定的方向進行研究。

回答

0

我有一個viewpager和幾個片段,就像你的情況一樣。我讓我的活動類從Google Drive-exapmle擴展BaseDriveActivity,但讓它擴展FragmentActivity而不是Activity。

旋轉又沒問題,即使是的onResume旋轉過程中調用,sinde它檢查是否mGoogleApiClient爲null:

@Override 
protected void onResume() { 
    super.onResume(); 
    if (mGoogleApiClient == null) { 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addApi(Drive.API).addScope(Drive.SCOPE_FILE) 
       .addScope(Drive.SCOPE_APPFOLDER) 
       // required for App Folder sample 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this).build(); 
    } 
    if (!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting()) 
     mGoogleApiClient.connect(); 

} 

沒有爲ErrorHandling中還有一些邏輯。你可以按原樣使用它。

創建文件夾的操作,內部foldet等我加入到我的主類,像這樣來創建文件夾:

protected void createFolder(String folderName){ 
     MetadataChangeSet changeSet = new MetadataChangeSet.Builder() 
     .setTitle(folderName).build(); 
     Drive.DriveApi.getRootFolder(getGoogleApiClient()).createFolder(
     getGoogleApiClient(), changeSet).setResultCallback(createFolderCallback); 
} 

final ResultCallback<DriveFolderResult> createFolderCallback = new ResultCallback<DriveFolderResult>() { 
    @Override 
    public void onResult(DriveFolderResult result) { 
     if (!result.getStatus().isSuccess()) { 
      showMessage("Error while trying to create the folder"); 
      return; 
     } 
     showMessage("Created a folder: " + result.getDriveFolder().getDriveId()); 

    } 
}; 


private String folderName; 

protected void createFolderInFolder(String exsistingDriveId, String folderName){ 
    Drive.DriveApi.fetchDriveId(getGoogleApiClient(), exsistingDriveId).setResultCallback(idCallback); 
    this.folderName=folderName; 
} 

final ResultCallback<DriveIdResult> idCallback = new ResultCallback<DriveIdResult>() { 
    @Override 
    public void onResult(DriveIdResult result) { 
     if (!result.getStatus().isSuccess()) { 
      showMessage("Cannot find DriveId. Are you authorized to view this file?"); 
      return; 
     } 
     DriveFolder folder = Drive.DriveApi 
       .getFolder(getGoogleApiClient(), result.getDriveId()); 
     MetadataChangeSet changeSet = new MetadataChangeSet.Builder() 
       .setTitle(folderName).build(); 
     folder.createFolder(getGoogleApiClient(), changeSet) 
       .setResultCallback(createFolderCallback); 
    } 
}; 

private DriveId mFolderDriveId; 


protected void createFileInFolder(String exsistingDriveId, String folderName){ 
    Drive.DriveApi.fetchDriveId(getGoogleApiClient(),  exsistingDriveId).setResultCallback(fileIdCallback); 
    this.folderName=folderName; 
} 

final private ResultCallback<DriveIdResult> fileIdCallback = new ResultCallback<DriveIdResult>()  { 
    @Override 
    public void onResult(DriveIdResult result) { 
     if (!result.getStatus().isSuccess()) { 
      showMessage("Cannot find DriveId. Are you authorized to view this file?"); 
      return; 
     } 
     mFolderDriveId = result.getDriveId(); 
     Drive.DriveApi.newDriveContents(getGoogleApiClient()) 
       .setResultCallback(driveContentsCallback); 
    } 
}; 

final private ResultCallback<DriveContentsResult> driveContentsCallback = 
     new ResultCallback<DriveContentsResult>() { 
    @Override 
    public void onResult(DriveContentsResult result) { 
     if (!result.getStatus().isSuccess()) { 
      showMessage("Error while trying to create new file contents"); 
      return; 
     } 
     DriveFolder folder = Drive.DriveApi.getFolder(getGoogleApiClient(), mFolderDriveId); 
     MetadataChangeSet changeSet = new MetadataChangeSet.Builder() 
       .setTitle(folderName) 
       .setMimeType("text/plain") 
       .setStarred(true).build(); 
     folder.createFile(getGoogleApiClient(), changeSet, result.getDriveContents()) 
       .setResultCallback(fileCallback); 
    } 
}; 

final private ResultCallback<DriveFileResult> fileCallback = 
     new ResultCallback<DriveFileResult>() { 
    @Override 
    public void onResult(DriveFileResult result) { 
     if (!result.getStatus().isSuccess()) { 
      showMessage("Error while trying to create the file"); 
      return; 
     } 
     showMessage("Created a file: " + result.getDriveFile().getDriveId()); 
    } 
}; 

編輯: 我發現以下幾點: 如果createFolderInFolder(或任何其他的api-funcions)被調用,就在一個意圖用於調用一個活動之前,調用的活動正在運行時不會調用結果回調。當主要活動正在接收控制權時,將調用onResume併發出異常,因爲再次調用連接。然後結果回調從不被調用。

這意味着api-call和result-callback必須能夠在沒有任何其他調用正在運行的情況下運行。

新編輯: 第一步:你需要一個回調函數在您的片段

private Callbacks mCallbacks; 

interface Callbacks { 
    public void onSaveToDrive(byte[] filecontent); 
} 

第二步:主要活動必須實現片段回調方法

第三步:調用API函數,和在結果回調中添加片段更新調用

如果要存儲driveid,則應該使用DriveId.encodeFromString(exsistingDriveId)和DriveId.decodeFromString(exsistingDriveId)以這種方式將s撕掉existingDriveId,即使驅動器已斷開連接並重新連接,也可以在稍後階段再次安全地引用它。

記住一個API調用必須在不調用其他類的情況下完成,因爲這可能會導致調用onResume()。

+0

因此,當驅動器連接已在onResume中啓動並且由於旋轉而重新啓動活動時會發生什麼。現有的驅動器任務不會在後臺繼續,並且會再次在onResume(第2次)中創建一個新連接,導致先前的對象調用在完成時失敗並嘗試綁定回原始對象? –

+0

是的,我相信你是對的。但是在嘗試執行第二次連接時會調用onConnectionFailed。這應該處理錯誤並保持第一個連接,如果它仍然存在。你的情況不是這樣嗎? – Skywalker

+0

讓我檢查這個場景,但我相信它不會,因爲您在技術上試圖調用另一個driveobject.connect()方法,而無需進入onConnectionFailed。 onConnectionFailed是一個由驅動api自動調用的回調接口,當存在一些連接問題時。但萬一,當連接已經建立以前(輪換之前),沒有理由爲什麼應該調用onConnectionfailed –