counterexample

فعلن فقط برنامه نویسی

counterexample

فعلن فقط برنامه نویسی

دوشنبه, ۲۳ مرداد ۱۳۹۶، ۰۱:۴۵ ب.ظ

۰

امکان backup و restore در برنامه های اندروید

دوشنبه, ۲۳ مرداد ۱۳۹۶، ۰۱:۴۵ ب.ظ

- تهیه نسخه پشتیبان اطلاعات و بازیابی اون اطلاعات

کاربردش برای زمانهایی همچون مواقعی که یک ریست فکتوری انجام بگیره و تمام داده های شما از بین میرن هستش. یا مثلن کاربر اطلاعاتی که تو اپلیکیشن شما داشته رو بعد از تعویض موبایلش بتونه رو موبایل جدیدش هم همون اطلاعات رو داشته باشه!

بدون مقدمه ی اضافه میریم سر اصل مطلب:

1- باید در یک سرویس بکاپ عضو بشید. برای استفاده از سرویس بکاپ گوگل تو این لینک برید و ثبت نام کنید و کلیدی که بهتون میده رو بردارید.

کلیدی که بهتون میده رو باید در فایل manifest داخل یک meta-data قرار بدید، به این صورت:

    <meta-data android:name="com.google.android.backup.api_key"
       
android:value="AEdPqrEAAAAIDaYEVgU6DJnyJdBmU7KLH3kszDXLv_4DIsEIyQ" />

با فرض اینکه کلیدی که در اختیار دارید "AEdPqrEAAAAIDaYEVgU6DJnyJdBmU7KLH3kszDXLv_4DIsEIyQ" بوده باشه.


2-در ادامه در فایل manifest  باید یک  backup agent را توسط android: backupAgent تعریف کنید:



<manifest ... >

     ...

     <application android:label="NewApp."

                  android:backupAgent="MyBackupAgent">

</application>

 </manifest>


3- شما تو این گام دو انتخاب دارید: یا Extending BackupAgent و یا Extending BackupAgentHelper رو انجام بدید. که ما بیشتر رو حالت دوم توضیح میدیم و توضیحات حالت اول ممکنه کامل نباشه.


حالت اول»

 extend BackupAgent:

زمانی که از extend BackupAgent استفاده شود، باید دو متد زیر را تعریف کنیم:


onBackup() : زمانی که نیاز به بکاپ باشد، این متد فراخوانی خواهد شد.

هنگام فراخوانی این متد، 3 پارامتر دریافت خواهند شد:

oldState, data, newState

با استفاده از این سه پارامتر، متد را بصورت زیر میتوان پیاده سازی کرد:


FileInputStream MyStr = new FileInputStream(oldState.getFileDescriptor());

//Get the stream [oldState]

DataInputStream temp = new DataInputStream(MyStr);

try {

long stModify = temp.readLong();// Get the last modified timestamp from the state fl.

   long flModify = mDataFile.lastModified();

  if (stModify != flModify) {

//The contents have been changed, so get backup

} else {

//Do nothing

      return; }

} catch (IOException exp) {

//handle exceptions

}



onRestore() : زمانی که سیستم درخواست بازیابی اطلاعات را داده باشد، این متد فراخوانی خواهد شد.


@Override

public void onRestore(BackupDataInput MyData, int MyCode,

ParcelFileDescriptor nextSt) throws IOException {

while (MyData.readNextHeader()) {

String value = data.getKey();

int Size = MyData.getDataSize();

if (TOPSCORE_BACKUP_KEY.equals(value)) {

// Create an input stream for the BackupDataInput

byte[] Buf = new byte[Size];

data.readEntityData(Buf, 0, Size);

ByteArrayInputStream MyStream = new ByteArrayInputStream(Buf);

DataInputStream temp = new DataInputStream(MyStream);

// reading backup data for restore , player name and score

PName = temp.readUTF();

PScore = temp.readInt();


// Recording the data

recordScore(PName, PScore);

} else {            MyData.skipEntityData();

}

}

FileOutputStream outMystream = new FileOutputStream(newState.getFileDescriptor());

DataOutputStream Myout = new DataOutputStream(outMystream);

out.writeUTF(PName);

out.writeInt(PScore);

}حالت دوم»

Extending BackupAgentHelper:


اگر قصد داشته باشید که کل فایل رو بکاپ بگیرید از این حالت استفاده میکنیم. چرا که طول کد کمتری داره چرا که در اینجا نیازی به تعریف متدهای ()onBackup() , onRestore وجود نداره.

 در اینجا دو نوع Helper وجود داره: 

- SharedPreferencesBackupHelper : برای بکاپ گیری از فایلهای SharedPreference

- FileBackupHelper : برای بکاپ گیری از فایل های موجود در حافظه داخلی


شما ممکنه چندین Helper رو به کار بگیرید اما برای هر نوع از فایلها، داشتنِ فقط یک Helper کافیه.

برای هر Helper باید یک BackupAgentHelper را تعریف کنید، که در متد ()onCreate اون باید دو کار رو انجام بدید که در مثال زیر برای یک SharedPreferences که اسم فایل اون "user_preferences" هست رو میبینید:

public class MyPrefsBackupAgent extends BackupAgentHelper {
   
// The name of the SharedPreferences file
   
static final String PREFS = "user_preferences";

   
// A key to uniquely identify the set of backup data
   
static final String PREFS_BACKUP_KEY = "prefs";

   
// Allocate a helper and add it to the backup agent
   
@Override
   
public void onCreate() {
       
SharedPreferencesBackupHelper helper =
               
new SharedPreferencesBackupHelper(this, PREFS);
        addHelper
(PREFS_BACKUP_KEY, helper);

   
}
}

همین ! شما با این کار یک backup agent رو بصورت کامل تعریف کردید.

SharedPreferencesBackupHelper تمام کدهای مورد نیاز برای backup و restore رو داخل خودش داره.


اما یک مثال هم از بکاپ گیری از فایل ها ببینیم و طرز استفاده از FileBackupHelper رو هم یاد بگیریم:

برای مثال اگر بخوایم دو فایل با نامهای "scores" و"stats"  رو بکاپ بگیریم، backup agent ما به صورت زیر خواهد بود:

public class MyFileBackupAgent extends BackupAgentHelper {
   
// The name of the file
   
static final String TOP_SCORES = "scores";
   
static final String PLAYER_STATS = "stats";

   
// A key to uniquely identify the set of backup data
   
static final String FILES_BACKUP_KEY = "myfiles";

   
// Allocate a helper and add it to the backup agent
   
@Override
   
public void onCreate() {
       
FileBackupHelper helper = new FileBackupHelper(this,
                TOP_SCORES
, PLAYER_STATS);
        addHelper
(FILES_BACKUP_KEY, helper);
   
}
}

اما برای کنترل و مدیریت دسترسی ها به فایل ها باید از قفل هایی استفاده کرد:

// Object for intrinsic lock
static final Object sDataLock = new Object();

مثلن برای write:

try {
   
synchronized (MyActivity.sDataLock) {
       
File dataFile = new File(getFilesDir(), TOP_SCORES);
       
RandomAccessFile raFile = new RandomAccessFile(dataFile, "rw");
        raFile
.writeInt(score);
   
}
} catch (IOException e) {
   
Log.e(TAG, "Unable to write to file");
}

برای read هم چنین چیزی باید نوشته بشه.

در نهایت در BackupAgentHelper باید متدهای onBackup() و onRestore() را بصورت زیر  override کرد تا عملیات خواندن و نوشتن همگام سازی بشن. بنابراین در فایلی که قبلن داشتیم این خط ها رو باید اضافه کنیم:

@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
         
ParcelFileDescriptor newState) throws IOException {
   
// Hold the lock while the FileBackupHelper performs backup
   
synchronized (MyActivity.sDataLock) {
       
super.onBackup(oldState, data, newState);
   
}
}

@Override
public void onRestore(BackupDataInput data, int appVersionCode,
       
ParcelFileDescriptor newState) throws IOException {
   
// Hold the lock while the FileBackupHelper restores the file
   
synchronized (MyActivity.sDataLock) {
       
super.onRestore(data, appVersionCode, newState);
   
}
}


نکته:

برای رفع مشکل احتمالی در مواردی همچون نسخه های متفاوت از برنامه، خصیصه android:restoreAnyVersion را در فایل manifest برابر "true" قرار بدید. چرا که در صورتیکه در نسخه ی جدیدی از برنامه قصد بازیابی اطلاعات از اطلاعاتی که در نسخه های پیشین بکاپ گیری شده اند را داشته باشید بصورت پیشفرض این عمل بدلیل اینکه نسخه برنامه شما تغییر یافته صورت نمیگیرد.


فراخوانی بکاپ:

برای فراخوانی و اعمال این عمل در هر جایی از برنامه خود که نیاز به بکاپ گیری باشد کافیست از متد dataChanged() استفاده کنید. با این کار  Backup Manager شما از اینکه شما قصد بکاپ گیری توسط backup agent را دارید باخبر میشود.


فراخوانی restore:

اگرچه در روال عادی نیازی به فراخوانی دستی این متد نیست، چرا که این کار معمولا زمانی که برنامه به تازگی نصب شود صورت میگیرد که بصورت اتوماتیک هم صورت میگیرد. با این حال برای فراخوانی دستی این عمل میتوانید از متد requestRestore() بهر ببرید.



موافقین ۰ مخالفین ۰ ۹۶/۰۵/۲۳
counter example

نظرات  (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">