android雲同步

通過互聯網連接提供功能強大的API,Android框架,可以幫助你建立豐富的雲功能的應用程序,他們的數據同步到遠程Web服務,確保您的所有設備始終保持同步,和您的寶貴數據備份到雲。

本課程涵蓋瞭不同的策略,雲功能的應用程序。它涵蓋瞭使用自己的後端Web應用程序與雲同步數據,使用雲計算的數據,使用戶可以恢復他們的數據時,一個新的設備上安裝應用程序和備份。

本篇重點分為兩部分講解,1、與App Engine同步  2、使用備份API
 
 
 
一、用App Engine的同步
 
編寫同步到雲中的應用程序,它可以是一個挑戰。有很多的小細節,以得到正確的,如服務器端的認證,客戶端認證,共享數據模型,以及一個API。使這更容易的方法之一是使用谷歌插件為Eclipse,為您構建Android和App Engine應用程序相互交談時,處理大量的管道。這一課,引導您通過建立這樣一個項目
準備好你的環境
如果你想跟隨這一課中的代碼示例,您必須執行以下操作來準備你的開發環境:

1、安裝谷歌的Eclipse插件。
2、安裝GWT SDK和Java App引擎SDK。快速入門指南,告訴你如何安裝這些組件。
3、註冊為C2DM訪問。我們強烈建議創建一個新的Google帳戶,專門用於連接到C2DM。在本課程中的服務器組件重復使用此角色帳戶與谷歌服務器進行身份驗證。
 
創建項目
在安裝谷歌插件為Eclipse,通知瞭一種新的Android項目的存在,當你創建一個新的Eclipse項目:連接App Engine的Android項目(在谷歌項目類別)。此時出現一個向導,該向導將引導您通過創建這個項目,在此過程中,系統會提示您輸入的帳戶憑據創建帳戶的作用。

註:請記住,輸入您的角色帳戶(你創建訪問C2DM服務的),而不是你登錄的用戶帳戶,或以管理員的憑據。

一旦你做,你會看到兩個項目等著你,在您的工作區的Andr​​oid應用程序和App Engine應用程序。萬歲!這兩個應用程序已經完全功能的向導創建瞭一個示例應用程序,它可以讓你進行身份驗證的App Engine應用程序從你的Andr​​oid設備使用的AccountManager(無需輸入您的憑據),和一個App Engine應用程序,可以發送郵件到任何已登錄的設備使用C2DM。以旋轉您的應用程序,並把它用於測試驅動器,請執行以下操作:

要旋轉的Android應用程序,請確保你有一個AVD提供瞭一個平臺版本的Android 2.2(API等級8級)。右鍵單擊Android的Eclipse項目中,去調試連接>本地應用程序引擎Android應用。這將啟動模擬器在這樣一種方式,它可以測試C2DM功能(通常通過谷歌遊戲)

創建數據層
打開你的app項目,在
(yourApp)-AppEngine > src > (yourapp) > server 包下,創建一個新的類,代碼如下:
 
Java代碼
package com.cloudtasks.server; 
import javax.persistence.*; 
@Entity 
public class Task { 
private String emailAddress; 
    private String name; 
    private String userId; 
    private String note; 
@Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
public Task() { 
    } 
public String getEmailAddress() { 
        return this.emailAddress; 
    } 
public Long getId() { 
        return this.id; 
    } 
    … 

 
一旦你寫的所有的類,表示你的數據層中的實體,你需要在Android和App Engine應用程序進行通信有關此數據的一種方式。這種通信可以通過創建一個遠程過程調用(RPC)服務。通常情況下,這涉及到很多的單調的代碼。幸運的是,有一個簡單的方法!右鍵單擊您的應用程序引擎的源文件夾中的服務器項目,並在上下文菜單中,導航到“新建”>“其他”,然後在出現的屏幕中,選擇谷歌> RPC服務。 出現一個向導,預填充的所有實體在上一步中創建的,它通過尋找您添加的源文件中的註釋@Entity。漂亮整潔的,對不對?單擊“ 完成“,向導將創建一個服務類的創建,檢索,更新和刪除(CRUD)操作的所有實體的存根方法。
 
創建持久層
持久層是應用程序數據長期存儲,所以你要保持你的用戶需要的任何信息去這裡。您有幾種選擇寫你的持久層,這取決於你想要什麼樣的數據存儲
創建一個類在您的com.cloudtasks.server包,處理持久層的輸入和輸出。為瞭訪問數據存儲,使用的PersistenceManager實例 類。您可以生成這個類的一個實例,使用PMF類在com.google.android.c2dm.server.PMF包,然後用它來 ​​執行基本的CRUD操作上的數據存儲區,像這樣:
 
Java代碼
/**
* Remove this object from the data store.
*/ 
public void delete(Long id) { 
    PersistenceManager pm = PMF.get().getPersistenceManager(); 
    try { 
        Task item = pm.getObjectById(Task.class, id); 
        pm.deletePersistent(item); 
    } finally { 
        pm.close(); 
    } 

 
你也可以查詢一個對象根據id:
 
Java代碼
public Task find(Long id) { 
    if (id == null) { 
        return null; 
    } 
PersistenceManager pm = PMF.get().getPersistenceManager(); 
    try { 
        Query query = pm.newQuery("select from " + Task.class.getName() 
        + " where id==" + id.toString() + " && emailAddress=='" + getUserEmail() + "'"); 
        List<Task> list = (List<Task>) query.execute(); 
        return list.size() == 0 ? null : list.get(0); 
    } catch (RuntimeException e) { 
        System.out.println(e); 
        throw e; 
    } finally { 
        pm.close(); 
    } 

 
 
從android app上查詢和更新
為瞭保持同步的App Engine應用程序,Android應用程序需要知道如何做兩件事情:從雲中提取數據,以及將數據發送到雲。大部分的管道產生的插件,但是你需要將其連接到您的Andr​​oid用戶界面的自己。
例如,如果您的服務器端數據模型包括一個對象稱為任務當你生成一個RPC層它自動為您創建瞭一個TaskRequest類,以及一個TaskProxy表示單個任務。在代碼中,請求一個列出所有這些任務從服務器看起來像這樣
 
Java代碼
public void fetchTasks (Long id) { 
  // Request is wrapped in an AsyncTask to avoid making a network request 
  // on the UI thread. 
    new AsyncTask<Long, Void, List<TaskProxy>>() { 
        @Override 
        protected List<TaskProxy> doInBackground(Long… arguments) { 
            final List<TaskProxy> list = new ArrayList<TaskProxy>(); 
            MyRequestFactory factory = Util.getRequestFactory(mContext, 
            MyRequestFactory.class); 
            TaskRequest taskRequest = factory.taskNinjaRequest(); 
if (arguments.length == 0 || arguments[0] == -1) { 
                factory.taskRequest().queryTasks().fire(new Receiver<List<TaskProxy>>() { 
                    @Override 
                    public void onSuccess(List<TaskProxy> arg0) { 
                      list.addAll(arg0); 
                    } 
                }); 
            } else { 
                newTask = true; 
                factory.taskRequest().readTask(arguments[0]).fire(new Receiver<TaskProxy>() { 
                    @Override 
                    public void onSuccess(TaskProxy arg0) { 
                      list.add(arg0); 
                    } 
                }); 
            } 
        return list; 
    } 
@Override 
    protected void onPostExecute(List<TaskProxy> result) { 
        TaskNinjaActivity.this.dump(result); 
    } 
}.execute(id); 

… 
public void dump (List<TaskProxy> tasks) { 
    for (TaskProxy task : tasks) { 
        Log.i("Task output", task.getName() + "\n" + task.getNote()); 
    } 

 
為瞭創建新任務,把它們發送到雲,創建一個請求對象,並使用它創建一個代理對象。然後填充代理對象和調用它的update方法。再一次,這應該是做一個AsyncTask來避免做網絡在UI線程上。最終的結果是這個樣子的。
 
Java代碼
new AsyncTask<Void, Void, Void>() { 
    @Override 
    protected Void doInBackground(Void… arg0) { 
        MyRequestFactory factory = (MyRequestFactory) 
                Util.getRequestFactory(TasksActivity.this, 
                MyRequestFactory.class); 
        TaskRequest request = factory.taskRequest(); 
// Create your local proxy object, populate it 
        TaskProxy task = request.create(TaskProxy.class); 
        task.setName(taskName); 
        task.setNote(taskDetails); 
        task.setDueDate(dueDate); 
// To the cloud! 
        request.updateTask(task).fire(); 
        return null; 
    } 
}.execute(); 
 
 
配置C2DM服務端
為瞭建立C2DM消息發送到你的Android設備,回到你的應用程序引擎代碼庫,和開放服務類生成瞭你你的RPC層。如果您的項目名稱是Foo,這個類稱為FooService。添加一行到每個方法來添加、刪除或更新數據,這樣一個C2DM消息被發送到用戶的設備。這裡的一個例子,一個更新的任務:
 
Java代碼
public static Task updateTask(Task task) { 
    task.setEmailAddress(DataStore.getUserEmail()); 
    task = db.update(task); 
    DataStore.sendC2DMUpdate(TaskChange.UPDATE + TaskChange.SEPARATOR + task.getId()); 
    return task; 

// Helper method.  Given a String, send it to the current user's device via C2DM. 
public static void sendC2DMUpdate(String message) { 
    UserService userService = UserServiceFactory.getUserService(); 
    User user = userService.getCurrentUser(); 
    ServletContext context = RequestFactoryServlet.getThreadLocalRequest().getSession().getServletContext(); 
    SendMessage.sendMessage(context, user.getEmail(), message); 

 
 
在接下來的例子中,一個helper類,TaskChange,已經創建瞭一個有幾個常量。創建這樣一個助手類使管理應用程序引擎之間的通信和Android應用程序更加容易。隻是創建它在共享文件夾中,定義一些常量,你就完成瞭。舉個例子,上面的代碼從一個TaskChange工作類的定義是這樣的:
 
Java代碼
public class TaskChange { 
    public static String UPDATE = "Update"; 
    public static String DELETE = "Delete"; 
    public static String SEPARATOR = ":"; 

 
 
配置C2DM客戶端
為瞭定義Android應用程序的行為,當一個C2DM接待、開放C2DMReceiver類,並瀏覽到onMessage()方法。修改這個方法來更新基於消息的內容
 
Java代碼
//In your C2DMReceiver class 
public void notifyListener(Intent intent) { 
    if (listener != null) { 
        Bundle extras = intent.getExtras(); 
        if (extras != null) { 
            String message = (String) extras.get("message"); 
            String[] messages = message.split(Pattern.quote(TaskChange.SEPARATOR)); 
            listener.onTaskUpdated(messages[0], Long.parseLong(messages[1])); 
        } 
    } 

  
// Elsewhere in your code, wherever it makes sense to perform local updates 
public void onTasksUpdated(String messageType, Long id) { 
    if (messageType.equals(TaskChange.DELETE)) { 
        // Delete this task from your local data store 
        … 
    } else { 
        // Call that monstrous Asynctask defined earlier. 
        fetchTasks(id); 
    } 

 
一旦你C2DM觸發設置本地更新,你們都做瞭。祝賀你,你有一個Android應用程序的雲!
 
 
二、使用備份Api
對於數據量的情況下,是比較輕(不到一兆字節),用戶的喜好,遊戲的高分或其他屬性一樣,備份API提供瞭一個輕量級的解決方案。這節課將引導您完成備份API集成到您的應用程序,並恢復數據到新的設備,使用備份API。

註冊api備份服務
一旦完成,服務向導XML標記插入在你的Android Manifest,它看起來像這樣:
 
Xml代碼
<meta-data android:name="com.google.android.backup.api_key" 
android:value="ABcDe1FGHij2KlmN3oPQRs4TUvW5xYZ" /> 
 
註意,每個備份關鍵作品與特定的包名。如果你有不同的應用程序,註冊為每一個單獨的key。
配置你的Mainfest
使用Android備份服務需要兩個添加到你的應用程序清單文件。首先,聲明類的名稱,作為您的備份代理,然後添加上面的代碼片段作為一個應用程序標記的子元素
 
Xml代碼
<application android:label="MyApp" 
             android:backupAgent="TheBackupAgent"> 
    … 
    <meta-data android:name="com.google.android.backup.api_key" 
    android:value="ABcDe1FGHij2KlmN3oPQRs4TUvW5xYZ" /> 
    … 
</application> 
  
 
 
編寫你的備份代理
最簡單的方式來創建你的備份代理是通過擴展BackupAgentHelper包裝類。創建這個helper類實際上是一個非常簡單的過程,這裡的例子用來備份用戶的分數信息:
 
Java代碼
 import android.app.backup.BackupAgentHelper; 
 import android.app.backup.FileBackupHelper; 
public class TheBackupAgent extends BackupAgentHelper { 
    // The name of the SharedPreferences file 
    static final String HIGH_SCORES_FILENAME = "scores"; 
// 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 
    void onCreate() { 
        FileBackupHelper helper = new FileBackupHelper(this, HIGH_SCORES_FILENAME); 
        addHelper(FILES_BACKUP_KEY, helper); 
    } 

 
 
為瞭增加靈活性,FileBackupHelper的構造函數可以接受一個變量數目的文件名。你可以簡單地支持上述兩種分數和一個遊戲進展文件隻需添加一個額外的參數,就像這樣
 
Java代碼
@Override 
   void onCreate() { 
       FileBackupHelper helper = new FileBackupHelper(this, HIGH_SCORES_FILENAME, PROGRESS_FILENAME); 
       addHelper(FILES_BACKUP_KEY, helper); 
   } 
 
 
備份的偏好也同樣容易。創建一個SharedPreferencesBackupHelper相同的方式做瞭一個FileBackupHelper。在這種情況下,而不是添加文件名的構造函數,的名稱添加共享選擇小組被您的應用程序。
 
Java代碼
import android.app.backup.BackupAgentHelper; 
 import android.app.backup.SharedPreferencesBackupHelper; 
public class TheBackupAgent extends BackupAgentHelper { 
     // The names of the SharedPreferences groups that the application maintains.  These 
     // are the same strings that are passed to getSharedPreferences(String, int). 
     static final String PREFS_DISPLAY = "displayprefs"; 
     static final String PREFS_SCORES = "highscores"; 
// An arbitrary string used within the BackupAgentHelper implementation to 
     // identify the SharedPreferencesBackupHelper's data. 
     static final String MY_PREFS_BACKUP_KEY = "myprefs"; 
// Simply allocate a helper and install it 
     void onCreate() { 
         SharedPreferencesBackupHelper helper = 
                 new SharedPreferencesBackupHelper(this, PREFS_DISPLAY, PREFS_SCORES); 
         addHelper(MY_PREFS_BACKUP_KEY, helper); 
     } 
 } 
 
您可以添加盡可能多的備份助手實例備份代理助手如你所願,但記住,你隻需要其中一種類型。一個FileBackupHelper處理所有的文件,你需要備份,一個SharedPreferencesBackupHelper處理所有共享preferencegroups你需要備份。
 
請求一個備份
為瞭請求一個備份,就創建一個實例,並調用它的BackupManager dataChanged()方法。
 
Java代碼
 import android.app.backup.BackupManager; 
 … 
public void requestBackup() { 
   BackupManager bm = new BackupManager(this); 
   bm.dataChanged(); 
 } 
 
 
恢復一個備份
通常你不應該有手工請求恢復,因為它發生時自動應用程序是安裝在一個設備。然而,如果需要觸發一個手動恢復,就調用requestRestore()方法。
 

You May Also Like