2017-01-02 7 views
2

Google Drive API for Android과 Stack Overflow에 대한 답변을 사용하여 앱에 Google 로그인을 구현하고 사용자 기기에 저장된 SQLite 데이터베이스를 Google 드라이브에 백업했습니다. 그래서 여기Google Drive Android API를 사용하여 SQLite 데이터베이스 업데이트

private static final String LOG_TAG = "DriveDbHandler"; 

private static final String PACKAGE_NAME = "com.package.example"; 

private static final String DATABASE_PATH = 
     "/data/data/" + PACKAGE_NAME + "/databases/" + DbHelper.DATABASE_NAME; 

private static final String FILE_NAME = DbHelper.DATABASE_NAME; 
private static final String MIME_TYPE = "application/x-sqlite-3"; 

private DriveDbHandler() { 
} 


public static void tryCreatingDbOnDrive(final GoogleApiClient googleApiClient) { 
    // We need to check if the database already exists on Google Drive. If so, we won't create 
    // it again. 

    Query query = new Query.Builder() 
      .addFilter(Filters.and(
        Filters.eq(SearchableField.TITLE, FILE_NAME), 
        Filters.eq(SearchableField.MIME_TYPE, MIME_TYPE))) 
      .build(); 
    DriveFolder appFolder = Drive.DriveApi.getAppFolder(googleApiClient); 

    appFolder.queryChildren(googleApiClient, query).setResultCallback(
      new ResultCallback<DriveApi.MetadataBufferResult>() { 
       @Override 
       public void onResult(@NonNull DriveApi.MetadataBufferResult metadataBufferResult) { 
        if (!metadataBufferResult.getStatus().isSuccess()) { 
         Log.e(LOG_TAG, "Query for " + FILE_NAME + " unsuccessful!"); 
         return; 
        } 

        int count = metadataBufferResult.getMetadataBuffer().getCount(); 

        Log.d(LOG_TAG, "Successfully ran query for " + FILE_NAME + " and found " + 
          count + " results"); 

        if (count > 1) { 
         Log.e(LOG_TAG, "App folder contains more than one database file! " + 
           "Found " + count + " matching results."); 
         return; 
        } 

        // Create the database on Google Drive if it doesn't exist already 
        if (count == 0) { 
         Log.d(LOG_TAG, "No existing database found on Google Drive"); 
         saveToDrive(googleApiClient); 
        } 
       } 
      }); 
} 

private static void saveToDrive(final GoogleApiClient googleApiClient) { 
    Log.d(LOG_TAG, "Starting to save to drive..."); 

    // Create content from file 
    Drive.DriveApi.newDriveContents(googleApiClient).setResultCallback(
      new ResultCallback<DriveApi.DriveContentsResult>() { 
       @Override 
       public void onResult(@NonNull DriveApi.DriveContentsResult driveContentsResult) { 
        if (!driveContentsResult.getStatus().isSuccess()) { 
         Log.w(LOG_TAG, "Drive contents result not a success! " + 
           "Not saving data to drive."); 
         return; 
        } 

        Log.d(LOG_TAG, "Created drive contents for file"); 
        createNewFile(googleApiClient, driveContentsResult.getDriveContents()); 
       } 
      }); 
} 

private static void createNewFile(GoogleApiClient googleApiClient, DriveContents driveContents) { 
    // Write file to contents (see http://stackoverflow.com/a/33610727/4230345) 
    File file = new File(DATABASE_PATH); 
    OutputStream outputStream = driveContents.getOutputStream(); 
    try { 
     InputStream inputStream = new FileInputStream(file); 
     byte[] buf = new byte[4096]; 
     int c; 
     while ((c = inputStream.read(buf, 0, buf.length)) > 0) { 
      outputStream.write(buf, 0, c); 
      outputStream.flush(); 
     } 
     outputStream.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    Log.d(LOG_TAG, "Written file to output stream of drive contents"); 

    // Create metadata 
    MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder() 
      .setTitle(FILE_NAME) 
      .setMimeType(MIME_TYPE) 
      .build(); 

    // Create the file on Google Drive 
    DriveFolder folder = Drive.DriveApi.getAppFolder(googleApiClient); 
    folder.createFile(googleApiClient, metadataChangeSet, driveContents).setResultCallback(
      new ResultCallback<DriveFolder.DriveFileResult>() { 
     @Override 
     public void onResult(@NonNull DriveFolder.DriveFileResult driveFileResult) { 
      if (!driveFileResult.getStatus().isSuccess()) { 
       Log.w(LOG_TAG, "File did not get created in Google Drive!"); 
       return; 
      } 

      Log.i(LOG_TAG, "Successfully created file in Google Drive"); 
     } 
    }); 
} 

를 내 문제입니다 : I가 데이터베이스를 저장할 수 있습니다

참고로

, 여기에 내가 Google 드라이브 (이 DriveDbHandler라는 final class에서 이루어집니다)로 데이터베이스를 저장하는 방법입니다 Google 드라이브, 로컬에서 변경 한 내용으로 Google 드라이브 버전을 업데이트하려면 어떻게해야하나요?

예를 들어 테이블 A에서 3 개의 행을 삭제 한 다음 기기 B의 SQLite 데이터베이스에 로컬로 5 개의 행을 추가 할 수 있지만이 변경 사항으로 Google 드라이브 버전을 어떻게 업데이트합니까?

전체 드라이브 파일을 삭제하고 다시 업로드하는 방법을 고려해 보았습니다.하지만이 경우 해당 파일에 대해 DriveId이 달라집니다.

API의 수정 처리 (here 설명)를 활용할 수 있는지 궁금합니다. 장치에 인터넷이 연결되어 있지 않으면 변경 사항을 업로드 대기 중입니다.

+0

나는 데이터베이스를 파일로 사용할 때이 문제에 대한 쉽고 세련된 해결책이 없다고 생각합니다. – Distjubo

+0

[도구] (https://sqlite.org/sqldiff.html)가 있습니다. 2 sqlite 데이터베이스의 차이 – Distjubo

+0

@Distjubo 그래, 그게 내가 의심하는 것. 내가 사용할 수있는 솔루션을 (당신이 얼마나 우아 하냐에 관계없이) 가지고 있습니까? 내가 제안한 _sqldiff_ 도구를 어떻게 사용합니까? –

답변

1

this answer에 따르면 Google 드라이브 용 Android API는 이미 차이 계산을 처리합니다. 따라서 복잡한 작업을 수행 할 필요가 없습니다. 파일을 완전히 다시 작성한 것처럼 API를 사용하십시오.

API의 투명 오프라인 동기화 기능을 활용할 수도 있습니다.

+0

설명해 주셔서 감사합니다. - 여기서는 할 일이 너무 기쁩니다.). 파일을 다시 쓸 때, 그 파일에서 내용을 제거하기 위해 무엇인가를해야합니까, 아니면 그냥 파일에 쓸 수 있습니까? –

+0

업데이트 - [여기] (https://developers.google.com/drive/android/) 및 [여기] (https://developers.google.com)에서 설명한대로 'WRITE_ONLY'모드로 파일을 열어야합니까?/drive/android/files # opening_the_file_contents_1)? –

+0

예, 작동하는 방법입니다. – Distjubo