2015-04-24 8 views
7

मैंने एक एसडी कार्ड पर अपने डेटाबेस का बैकअप बनाने में कामयाब रहा है और वहां से बहाल किया है लेकिन मुझे एहसास हुआ कि मेरे बैकअप का उद्देश्य डेटा की सुरक्षा सुनिश्चित करना है और इसमें अगर भौतिक उपकरण स्वयं क्षतिग्रस्त, खो गया है, या स्वचालित रूप से दहन करता है तो एसडी कार्ड पर बैकअप होगा। इसलिए इस मामले में मूल के समान स्थान पर बैकअप रखना, बैकअप लेने के उद्देश्य से काफी हद तक हरा देता है।SQL ड्राइव डेटाबेस को पुनर्स्थापित करने और पुनर्स्थापित करने के लिए Google ड्राइव का उपयोग

तो मैंने डीबी फ़ाइल को रखने के लिए एक सुरक्षित स्थान के रूप में Google ड्राइव का उपयोग करने का विचार किया, और यह मुफ़्त है। मैंने Google के quickstart डेमो में एक झलक लिया है जिसे मैं ठीक काम कर रहा हूं। लेकिन मुझे अभी भी पता नहीं है कि यह मेरे मामले के लिए कैसे किया जाए।

मुझे कुछ कोड मिल गया है लेकिन यह अभी भी कुछ बहिष्कृत तरीकों का उपयोग कर रहा है और अब तक मैंने इसे हटाए गए क्षेत्र को छोड़ते समय इसे चलाने में कामयाब रहा है, लेकिन यह केवल मेरे Google ड्राइव में एक खाली बाइनरी फ़ाइल बनाता है। लगता है कि बहिष्कृत क्षेत्र वह जगह है जहां यह वास्तव में डीबी बैकअप सामग्री अपलोड करता है। अगर कोई मदद कर सकता है तो इसकी बहुत सराहना की जाएगी।

अगर मैं इसे बेहतर तरीके से समझाने के लिए इसका उपयोग कर सकता हूं तो मैं इसे नीचे छोड़ दूंगा। मैंने नीचे बहिष्कृत विधि भी चिह्नित की है, यह अंत के करीब है।

public class ExpectoPatronum extends Activity implements ConnectionCallbacks, OnConnectionFailedListener { 

private static final String TAG = "MainActivity"; 
private GoogleApiClient api; 
private boolean mResolvingError = false; 
private DriveFile mfile; 
private static final int DIALOG_ERROR_CODE =100; 
private static final String DATABASE_NAME = "demodb"; 
private static final String GOOGLE_DRIVE_FILE_NAME = "sqlite_db_backup"; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // Create the Drive API instance 
    api = new GoogleApiClient.Builder(this).addApi(Drive.API).addScope(Drive.SCOPE_FILE). 
      addConnectionCallbacks(this).addOnConnectionFailedListener(this).build(); 
} 

@Override 
public void onStart() { 
    super.onStart(); 
    if(!mResolvingError) { 
     api.connect(); // Connect the client to Google Drive 
    } 
} 

@Override 
public void onStop() { 
    super.onStop(); 
    api.disconnect(); // Disconnect the client from Google Drive 
} 

@Override 
public void onConnectionFailed(ConnectionResult result) { 
    Log.v(TAG, "Connection failed"); 
    if(mResolvingError) { // If already in resolution state, just return. 
     return; 
    } else if(result.hasResolution()) { // Error can be resolved by starting an intent with user interaction 
     mResolvingError = true; 
     try { 
      result.startResolutionForResult(this, DIALOG_ERROR_CODE); 
     } catch (SendIntentException e) { 
      e.printStackTrace(); 
     } 
    } else { // Error cannot be resolved. Display Error Dialog stating the reason if possible. 
     ErrorDialogFragment fragment = new ErrorDialogFragment(); 
     Bundle args = new Bundle(); 
     args.putInt("error", result.getErrorCode()); 
     fragment.setArguments(args); 
     fragment.show(getFragmentManager(), "errordialog"); 
    } 
} 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if(requestCode == DIALOG_ERROR_CODE) { 
     mResolvingError = false; 
     if(resultCode == RESULT_OK) { // Error was resolved, now connect to the client if not done so. 
      if(!api.isConnecting() && !api.isConnected()) { 
       api.connect(); 
      } 
     } 
    } 
} 

@Override 
public void onConnected(Bundle connectionHint) { 
    Log.v(TAG, "Connected successfully"); 

    /* Connection to Google Drive established. Now request for Contents instance, which can be used to provide file contents. 
     The callback is registered for the same. */ 
    Drive.DriveApi.newDriveContents(api).setResultCallback(contentsCallback); 
} 

final private ResultCallback<DriveApi.DriveContentsResult> contentsCallback = new ResultCallback<DriveApi.DriveContentsResult>() { 

    @Override 
    public void onResult(DriveApi.DriveContentsResult result) { 
     if (!result.getStatus().isSuccess()) { 
      Log.v(TAG, "Error while trying to create new file contents"); 
      return; 
     } 

     String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("db"); 
     MetadataChangeSet changeSet = new MetadataChangeSet.Builder() 
       .setTitle(GOOGLE_DRIVE_FILE_NAME) // Google Drive File name 
       .setMimeType(mimeType) 
       .setStarred(true).build(); 
     // create a file on root folder 
     Drive.DriveApi.getRootFolder(api) 
       .createFile(api, changeSet, result.getDriveContents()) 
       .setResultCallback(fileCallback); 
    } 

}; 

final private ResultCallback<DriveFileResult> fileCallback = new ResultCallback<DriveFileResult>() { 

    @Override 
    public void onResult(DriveFileResult result) { 
     if (!result.getStatus().isSuccess()) { 
      Log.v(TAG, "Error while trying to create the file"); 
      return; 
     } 
     mfile = result.getDriveFile(); 
     mfile.open(api, DriveFile.MODE_WRITE_ONLY, null).setResultCallback(contentsOpenedCallback); 
    } 
}; 

final private ResultCallback<DriveApi.DriveContentsResult> contentsOpenedCallback = new ResultCallback<DriveApi.DriveContentsResult>() { 

    @Override 
    public void onResult(DriveApi.DriveContentsResult result) { 

     if (!result.getStatus().isSuccess()) { 
      Log.v(TAG, "Error opening file"); 
      return; 
     } 

     try { 
      FileInputStream is = new FileInputStream(getDbPath()); 
      BufferedInputStream in = new BufferedInputStream(is); 
      byte[] buffer = new byte[8 * 1024]; 
      DriveContents content = result.getDriveContents(); 
      BufferedOutputStream out = new BufferedOutputStream(content.getOutputStream()); 
      int n = 0; 
      while((n = in.read(buffer)) > 0) { 
       out.write(buffer, 0, n); 
      } 

      in.close(); 
commitAndCloseContents is DEPRECATED -->/**mfile.commitAndCloseContents(api, content).setResultCallback(new ResultCallback<Status>() { 
       @Override 
       public void onResult(Status result) { 
        // Handle the response status 
       } 
      });**/ 
     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

}; 

private File getDbPath() { 
    return this.getDatabasePath(DATABASE_NAME); 
} 

@Override 
public void onConnectionSuspended(int cause) { 
    // TODO Auto-generated method stub 
    Log.v(TAG, "Connection suspended"); 

} 

public void onDialogDismissed() { 
    mResolvingError = false; 
} 

public static class ErrorDialogFragment extends DialogFragment { 
    public ErrorDialogFragment() {} 

    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     int errorCode = this.getArguments().getInt("error"); 
     return GooglePlayServicesUtil.getErrorDialog(errorCode, this.getActivity(), DIALOG_ERROR_CODE); 
    } 

    public void onDismiss(DialogInterface dialog) { 
     ((ExpectoPatronum) getActivity()).onDialogDismissed(); 
    } 
} 
} 
+0

सुनिश्चित करें कि आप ड्राइव बाकी एपीआई और GDAA के बीच अंतर को समझते हैं। आपके उपयोग के मामले के लिए, gdaa जाना सबसे अच्छा तरीका है, तो आप किसी भी जल्दी शुरू ट्यूटोरियल कि gdaa नहीं है अनदेखा कर देना चाहिए। एक तरफ, एक प्रश्न में इतना कोड पोस्ट करना बहुत उपयोगी नहीं है। – pinoyyid

+0

इसे देखें: http://stackoverflow.com/questions/33602812/backup-restore-sqllite-database-to-google-drive-app-folder/39044477#39044477 – Jose19589

उत्तर

4

एक द्विआधारी सामग्री से Google डिस्क सौदा पहुँचने के लिए उपयोग दोनों एपीआई। तो केवल एक चीज जो आपको करना है वह है अपनी बाइनरी डीबी फ़ाइल अपलोड करना, इसे उचित एमआईएम प्रकार और एक NAME (शीर्षक) दें।
एपीआई का चयन आप पर निर्भर करता है, GDAA Google Play Services द्वारा प्रबंधित अपलोड/डाउनलोड के साथ 'स्थानीय' इकाई की तरह व्यवहार करता है, REST एपी अधिक कम स्तर वाला है, जिससे आपको अधिक नियंत्रण मिल रहा है, लेकिन आपको नेटवर्किंग समस्याओं का ख्याल रखना होगा (वाईफाई चालू/बंद, आदि), यानी आपको आमतौर पर ऐसा करने के लिए एक सिंक सेवा बनाना होता है। जीडीएए के साथ यह आपके लिए GooPlaySvcs द्वारा किया जाता है। लेकिन मैं पीछे हटा।
मैं आपको इस GitHub demo पर इंगित कर सकता हूं, काफी हालिया (GooPlaySvcs 7.00। +), मैं विभिन्न आरईएसटी/जीडीएए मुद्दों का परीक्षण करने के लिए उपयोग करता हूं। मुख्य गतिविधि इस तथ्य से थोड़ा जटिल है कि यह विभिन्न Google खातों के बीच स्विच करने की अनुमति देती है, लेकिन यदि आप these hurdles से गुजरते हैं, तो आप या तो आरईएसटी या जीडीएए सीआरयूडी रैपर का उपयोग कर सकते हैं।

this line पर नज़र डालें। बाइट [] बफर में बाइनरी जेपीईजी डेटा होता है और यह "छवि/जेपीईजी" माइम प्रकार (और एक समय-आधारित नाम) के साथ जाता है। केवल एक चीज आप अगर है एक बाइट में अपने डीबी फ़ाइल को लोड करना है [] इस तरह एक निर्माण का उपयोग कर बफ़र:

private static final int BUF_SZ = 4096; 

    static byte[] file2Bytes(File file) { 
    if (file != null) try { 
     return is2Bytes(new FileInputStream(file)); 
    } catch (Exception ignore) {} 
    return null; 
    } 

    static byte[] is2Bytes(InputStream is) { 
    byte[] buf = null; 
    BufferedInputStream bufIS = null; 
    if (is != null) try { 
     ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); 
     bufIS = new BufferedInputStream(is); 
     buf = new byte[BUF_SZ]; 
     int cnt; 
     while ((cnt = bufIS.read(buf)) >= 0) { 
     byteBuffer.write(buf, 0, cnt); 
     } 
     buf = byteBuffer.size() > 0 ? byteBuffer.toByteArray() : null; 
    } catch (Exception e) {le(e);} 
    finally { 
     try { 
     if (bufIS != null) bufIS.close(); 
     } catch (Exception e) {le(e);} 
    } 
    return buf; 
    } 

मैं अब SQLite DB के लिए MIME प्रकार याद नहीं है, लेकिन मैं इसे यकीन ऐसा किया जा सकता है क्योंकि मैं ठीक उसी समय कर रहा था (कोड अब चला गया है, दुर्भाग्य से)। और मुझे याद है कि मैं वास्तव में कुछ वेब ऐप का उपयोग करके SQLite DB 'क्लाउड में अप' को एक्सेस और संशोधित कर सकता हूं।

गुड लक

अद्यतन:
बाद मैं शेख़ी लिखा ऊपर मैं डेमो आप के बारे में बात कर रहे हैं पर देखा। यदि आप इसे काम कर रहे हैं, तो सबसे आसान तरीका वास्तव में आपकी डीबी फ़ाइल को here प्लग करने के लिए सही है, सही एमआईएम सेट करें और आप जाने के लिए अच्छे हैं। आप ले लो
और अपने 'बहिष्कृत' मुद्दे को संबोधित करने के लिए। जीडीएए अभी भी विकसित किया जा रहा है और क्विकस्टार्ट एक वर्ष से अधिक पुराना है।
सामग्री: यह दुनिया में हम :-)

+0

लिंक और स्पष्टीकरण के लिए धन्यवाद, उन्होंने साफ़ कर दिया है मेरे कुछ प्रश्न उठाओ। , आपके सुझाव के साथ जाने के लिए बस "तस्वीर लेने" हिस्से को हटाने और कुछ और इसकी जगह पर काम कर फैसला किया। मैंने दूसरे पर काम करने की कोशिश की लेकिन अब तक एक खाली बाइनरी मिल रही है। मैं बस उस कुछ और समय के लिए मिल जाएगा। अभी मैं सिर्फ ड्राइव फ़ाइल से डाटाबेस बहाल करने पर काम करेंगे, तो आप उस के लिए किसी भी संकेत दिए गए तुम करोगी है करने के लिए नहीं होगा? – Cytus

+0

कोर आप पर ध्यान देना चाहिए यहाँ है: https://github.com/seanpjanson/GDAADemo/blob/master/src/main/java/com/andyscan/gdaademo/GDAA.java#L143। विधि को संशोधित करें ताकि वह अपने वातावरण को फिट और 'buf' की जाँच के माध्यम से कदम (नोटिस यह buf.length है)। अंत में, आपको फ़ाइल को GooDrive में देखना चाहिए और इसकी लंबाई समान होनी चाहिए। इसे अपने डेस्कटॉप पर डाउनलोड करने का प्रयास करें, इसे अपने एंड्रॉइड डिवाइस से मूल के साथ तुलना करें। जीडीएए परवाह नहीं है कि आप किस प्रकार की फाइल शिपिंग कर रहे हैं, यह केवल बाइट्स को ऊपर ले जाता है, एक ऑब्जेक्ट बनाता है और मेटाडेटा (शीर्षक, माइम, विवरण, ...) – seanpj

+0

@seanpj लिंक टूटा हुआ लगता है !! क्या आप अपडेट कर सकते हैं! – shadygoneinsane

1

में रहते हैं आप के साथ पदावनत कोड को बदलने के लिए की जरूरत है।प्रतिबद्ध (एपीआई, शून्य);

देखें https://developer.android.com/reference/com/google/android/gms/drive/DriveContents.html

+0

क्षमा करें, मैंने एक साल पहले सेवानिवृत्त हो गए हैं। – seanpj

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