Sdílet prostřednictvím


Jak používat sadu Azure Mobile Apps SDK pro Android

V této příručce se dozvíte, jak pomocí klientské sady SDK pro Android pro Mobile Apps implementovat běžné scénáře, například:

  • Dotazování na data (vkládání, aktualizace a odstraňování)
  • Ověřování.
  • Zpracování chyb
  • Přizpůsobení klienta

Tato příručka se zaměřuje na sadu Android SDK na straně klienta. Další informace o sadách SDK na straně serveru pro Mobile Apps najdete v tématu Práce s back-endovou sadou .NET SDK nebo používání sady NODE.JS back-end SDK.

Referenční dokumentace

Referenční informace k rozhraní Javadocs API pro klientskou knihovnu Androidu najdete na GitHubu.

Podporované platformy

Sada Azure Mobile Apps SDK pro Android podporuje úrovně rozhraní API 19 až 24 (KitKat až Nougat) pro faktory formulářů pro telefon a tablet. Ověřování využívá zejména běžný přístup webové architektury ke shromažďování přihlašovacích údajů. Ověřování toku serveru nefunguje s malými zařízeními, jako jsou hodinky.

Nastavení a požadavky

Dokončete kurz rychlého startu Mobile Apps. Tato úloha zajišťuje splnění všech požadavků na vývoj Azure Mobile Apps. Rychlý start vám také pomůže nakonfigurovat účet a vytvořit první back-end mobilní aplikace.

Pokud se rozhodnete kurz Pro rychlý start nedokončíte, proveďte následující úlohy:

Aktualizace souboru sestavení Gradle

Změňte oba soubory build.gradle :

  1. Přidejte tento kód do souboru build.gradle na úrovni projektu:

    buildscript {
        repositories {
            jcenter()
            google()
        }
    }
    
    allprojects {
        repositories {
            jcenter()
            google()
        }
    }
    
  2. Přidejte tento kód do souboru build.gradle na úrovni aplikace modulu uvnitř značky závislostí:

    implementation 'com.microsoft.azure:azure-mobile-android:3.4.0@aar'
    

    Nejnovější verze je v současné době 3.4.0. Podporované verze jsou uvedené v binárních intervalech.

Povolení oprávnění k internetu

Aby vaše aplikace měla přístup k Azure, musí mít povolené oprávnění k internetu. Pokud ještě není povolený, přidejte do souboru AndroidManifest.xml následující řádek kódu:

<uses-permission android:name="android.permission.INTERNET" />

Vytvoření připojení klienta

Azure Mobile Apps poskytuje mobilní aplikaci čtyři funkce:

  • Přístup k datům a offline synchronizace se službou Azure Mobile Apps
  • Volání vlastních rozhraní API napsaných pomocí sady AZURE Mobile Apps Server SDK
  • Ověřování s ověřováním a autorizací služby Aplikace Azure
  • Registrace nabízených oznámení ve službě Notification Hubs

Každá z těchto funkcí nejprve vyžaduje vytvoření objektu MobileServiceClient . V mobilním klientovi by se měl vytvořit jenom jeden MobileServiceClient objekt (to znamená, že by to měl být vzor Singleton). Vytvoření objektu MobileServiceClient :

MobileServiceClient mClient = new MobileServiceClient(
    "<MobileAppUrl>",       // Replace with the Site URL
    this);                  // Your application Context

Jedná se <MobileAppUrl> o řetězec nebo objekt ADRESY URL, který odkazuje na váš mobilní back-end. Pokud k hostování mobilního back-endu používáte Aplikace Azure Service, ujistěte se, že používáte zabezpečenou https:// verzi adresy URL.

Klient také vyžaduje přístup k aktivitě nebo kontextu – this parametru v příkladu. Ke konstrukci MobileServiceClient by mělo dojít v rámci onCreate() metody aktivity odkazované v AndroidManifest.xml souboru.

Osvědčeným postupem je abstrahovat komunikaci serveru do vlastní třídy (singleton-pattern). V tomto případě byste měli předat aktivitu v rámci konstruktoru, aby se služba správně nakonfiguruje. Příklad:

package com.example.appname.services;

import android.content.Context;
import com.microsoft.windowsazure.mobileservices.*;

public class AzureServiceAdapter {
    private String mMobileBackendUrl = "https://myappname.azurewebsites.net";
    private Context mContext;
    private MobileServiceClient mClient;
    private static AzureServiceAdapter mInstance = null;

    private AzureServiceAdapter(Context context) {
        mContext = context;
        mClient = new MobileServiceClient(mMobileBackendUrl, mContext);
    }

    public static void Initialize(Context context) {
        if (mInstance == null) {
            mInstance = new AzureServiceAdapter(context);
        } else {
            throw new IllegalStateException("AzureServiceAdapter is already initialized");
        }
    }

    public static AzureServiceAdapter getInstance() {
        if (mInstance == null) {
            throw new IllegalStateException("AzureServiceAdapter is not initialized");
        }
        return mInstance;
    }

    public MobileServiceClient getClient() {
        return mClient;
    }

    // Place any public methods that operate on mClient here.
}

Teď můžete volat AzureServiceAdapter.Initialize(this); metodu onCreate() hlavní aktivity. Jakékoli jiné metody, které potřebují přístup k klientovi, používají AzureServiceAdapter.getInstance(); k získání odkazu na adaptér služby.

Operace s daty

Jádrem sady Azure Mobile Apps SDK je poskytnutí přístupu k datům uloženým v SQL Azure v back-endu mobilní aplikace. K datům můžete přistupovat pomocí tříd silného typu (upřednostňovaných) nebo netypových dotazů (nedoporučuje se). Většina této části se zabývá používáním tříd silného typu.

Definování datových tříd klientů

Pokud chcete získat přístup k datům z tabulek SQL Azure, definujte třídy dat klientů, které odpovídají tabulkám v back-endu mobilní aplikace. Příklady v tomto tématu předpokládají tabulku s názvem MyDataTable, která obsahuje následující sloupce:

  • ID
  • text
  • hotovo

Odpovídající typovaný objekt na straně klienta se nachází v souboru s názvem MyDataTable.java:

public class ToDoItem {
    private String id;
    private String text;
    private Boolean complete;
}

Přidejte metody getter a setter pro každé pole, které přidáte. Pokud tabulka SQL Azure obsahuje více sloupců, přidejte do této třídy odpovídající pole. Pokud například objekt DTO (objekt přenosu dat) měl celočíselnou prioritu sloupce, můžete toto pole přidat spolu s jeho metodami getter a setter:

private Integer priority;

/**
* Returns the item priority
*/
public Integer getPriority() {
    return mPriority;
}

/**
* Sets the item priority
*
* @param priority
*            priority to set
*/
public final void setPriority(Integer priority) {
    mPriority = priority;
}

Informace o vytváření dalších tabulek v back-endu Mobile Apps najdete v tématu Postupy: Definování kontroleru tabulky (back-end .NET) nebo definování tabulek pomocí dynamického schématu (Node.js back-endu).

Back-endová tabulka Azure Mobile Apps definuje pět speciálních polí, z nichž čtyři jsou k dispozici pro klienty:

  • String id: Globálně jedinečné ID záznamu. Osvědčeným postupem je nastavit ID řetězcové reprezentace objektu UUID .
  • DateTimeOffset updatedAt: Datum a čas poslední aktualizace. Pole updatedAt je nastaveno serverem a nikdy by neměl být nastaveno klientským kódem.
  • DateTimeOffset createdAt: Datum a čas vytvoření objektu. Pole createdAt je nastaveno serverem a nikdy by neměl být nastaveno klientským kódem.
  • byte[] version: Obvykle vyjádřeno jako řetězec, verze je také nastavena serverem.
  • boolean deleted: Označuje, že záznam byl odstraněn, ale ještě není vyprázdněný. Nepoužívejte deleted ve třídě vlastnost.

Pole id je povinné. Pole updatedAt a version pole se používají pro offline synchronizaci (pro přírůstkovou synchronizaci a řešení konfliktů). Pole createdAt je referenční pole a klient ho nepoužívá. Názvy vlastností jsou "mezi jednotlivými dráty" a nejsou upravitelné. Pomocí knihovny gson však můžete vytvořit mapování mezi objektem a názvy "across-the-wire". Příklad:

package com.example.zumoappname;

import com.microsoft.windowsazure.mobileservices.table.DateTimeOffset;

public class ToDoItem
{
    @com.google.gson.annotations.SerializedName("id")
    private String mId;
    public String getId() { return mId; }
    public final void setId(String id) { mId = id; }

    @com.google.gson.annotations.SerializedName("complete")
    private boolean mComplete;
    public boolean isComplete() { return mComplete; }
    public void setComplete(boolean complete) { mComplete = complete; }

    @com.google.gson.annotations.SerializedName("text")
    private String mText;
    public String getText() { return mText; }
    public final void setText(String text) { mText = text; }

    @com.google.gson.annotations.SerializedName("createdAt")
    private DateTimeOffset mCreatedAt;
    public DateTimeOffset getCreatedAt() { return mCreatedAt; }
    protected void setCreatedAt(DateTimeOffset createdAt) { mCreatedAt = createdAt; }

    @com.google.gson.annotations.SerializedName("updatedAt")
    private DateTimeOffset mUpdatedAt;
    public DateTimeOffset getUpdatedAt() { return mUpdatedAt; }
    protected void setUpdatedAt(DateTimeOffset updatedAt) { mUpdatedAt = updatedAt; }

    @com.google.gson.annotations.SerializedName("version")
    private String mVersion;
    public String getVersion() { return mVersion; }
    public final void setVersion(String version) { mVersion = version; }

    public ToDoItem() { }

    public ToDoItem(String id, String text) {
        this.setId(id);
        this.setText(text);
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof ToDoItem && ((ToDoItem) o).mId == mId;
    }

    @Override
    public String toString() {
        return getText();
    }
}

Vytvoření odkazu na tabulku

Pokud chcete získat přístup k tabulce, nejprve vytvořte objekt MobileServiceTable voláním metody getTable v MobileServiceClient. Tato metoda má dvě přetížení:

public class MobileServiceClient {
    public <E> MobileServiceTable<E> getTable(Class<E> clazz);
    public <E> MobileServiceTable<E> getTable(String name, Class<E> clazz);
}

V následujícím kódu je mClient odkazem na objekt MobileServiceClient. První přetížení se používá tam, kde název třídy a název tabulky jsou stejné a je to ten, který se používá v rychlém startu:

MobileServiceTable<ToDoItem> mToDoTable = mClient.getTable(ToDoItem.class);

Druhé přetížení se používá, když se název tabulky liší od názvu třídy: prvním parametrem je název tabulky.

MobileServiceTable<ToDoItem> mToDoTable = mClient.getTable("ToDoItemBackup", ToDoItem.class);

Dotazování back-endové tabulky

Nejprve získejte odkaz na tabulku. Potom spusťte dotaz na odkaz na tabulku. Dotaz je libovolná kombinace:

Klauzule musí být uvedeny v předchozím pořadí.

Filtrování výsledků

Obecná forma dotazu je:

List<MyDataTable> results = mDataTable
    // More filters here
    .execute()          // Returns a ListenableFuture<E>
    .get()              // Converts the async into a sync result

Předchozí příklad vrátí všechny výsledky (až do maximální velikosti stránky nastavené serverem). Metoda .execute() provede dotaz na back-endu. Dotaz se před přenosem do back-endu Mobile Apps převede na dotaz OData v3 . Back-end Mobile Apps na potvrzení převede dotaz na příkaz SQL před jeho spuštěním v instanci SQL Azure. Vzhledem k tomu, že aktivita sítě nějakou dobu trvá, .execute() metoda vrátí ListenableFuture<E>hodnotu .

Filtrování vrácených dat

Následující spuštění dotazu vrátí všechny položky z tabulky ToDoItem , kde se úplné rovná false.

List<ToDoItem> result = mToDoTable
    .where()
    .field("complete").eq(false)
    .execute()
    .get();

mToDoTable je odkaz na tabulku mobilní služby, kterou jsme vytvořili dříve.

Definujte filtr pomocí volání metody where v odkazu na tabulku. Za metodou where následuje metoda pole následovaná metodou, která určuje logický predikát. Možné predikátové metody zahrnují eq (rovná se), ne (ne rovno), gt (větší než), ge (větší než nebo rovno), lt (menší než), le (menší než nebo rovno). Tyto metody umožňují porovnat číselná a řetězcová pole s konkrétními hodnotami.

Můžete filtrovat podle kalendářních dat. Následující metody umožňují porovnat celé pole kalendářního data nebo části data: rok, měsíc, den, hodinu, minutu a sekundu. Následující příklad přidá filtr pro položky, jejichž termín splnění se rovná 2013.

List<ToDoItem> results = MToDoTable
    .where()
    .year("due").eq(2013)
    .execute()
    .get();

Následující metody podporují komplexní filtry pro pole řetězců: startsWith, endsWith, concat, subString, indexOf, replace, toLower, toUpper, trim a length. Následující příklad filtruje řádky tabulky, ve kterých textový sloupec začíná na "PRI0".

List<ToDoItem> results = mToDoTable
    .where()
    .startsWith("text", "PRI0")
    .execute()
    .get();

U číselných polí jsou podporovány následující metody operátoru: sčítání, sub, mul, div, mod, floor, ceiling a round. Následující příklad filtruje řádky tabulky, ve kterých je doba trvání sudé číslo.

List<ToDoItem> results = mToDoTable
    .where()
    .field("duration").mod(2).eq(0)
    .execute()
    .get();

Predikáty můžete kombinovat s těmito logickými metodami: a nebo ne. Následující příklad kombinuje dva z předchozích příkladů.

List<ToDoItem> results = mToDoTable
    .where()
    .year("due").eq(2013).and().startsWith("text", "PRI0")
    .execute()
    .get();

Logické operátory seskupování a vnoření:

List<ToDoItem> results = mToDoTable
    .where()
    .year("due").eq(2013)
    .and(
        startsWith("text", "PRI0")
        .or()
        .field("duration").gt(10)
    )
    .execute().get();

Podrobnější diskuzi a příklady filtrování najdete v tématu Zkoumání bohatého modelu dotazů klienta androidu.

Řazení vrácených dat

Následující kód vrátí všechny položky z tabulky ToDoItems seřazené vzestupně podle textového pole. mToDoTable je odkaz na back-endovou tabulku, kterou jste vytvořili dříve:

List<ToDoItem> results = mToDoTable
    .orderBy("text", QueryOrder.Ascending)
    .execute()
    .get();

První parametr metody orderBy je řetězec, který se rovná názvu pole, podle kterého se má seřadit. Druhý parametr používá výčet QueryOrder k určení, zda se má seřadit vzestupně nebo sestupně. Pokud filtrujete pomocí where metoda, where metoda musí být vyvolána před orderBy metoda.

Výběr konkrétních sloupců

Následující kód ukazuje, jak vrátit všechny položky z tabulky ToDoItems, ale zobrazí pouze úplná a textová pole. mToDoTable je odkaz na back-endovou tabulku, kterou jsme vytvořili dříve.

List<ToDoItemNarrow> result = mToDoTable
    .select("complete", "text")
    .execute()
    .get();

Parametry vybrané funkce jsou názvy řetězců sloupců tabulky, které chcete vrátit. Výběrová metoda musí postupovat podle metod, jako je where a orderBy. Za ním můžou následovat stránkovací metody, jako je skip a top.

Vrácení dat na stránkách

Data se vždy vrací na stránkách. Server nastaví maximální počet vrácených záznamů. Pokud klient požaduje více záznamů, server vrátí maximální počet záznamů. Ve výchozím nastavení je maximální velikost stránky na serveru 50 záznamů.

První příklad ukazuje, jak vybrat prvních pět položek z tabulky. Dotaz vrátí položky z tabulky ToDoItems. mToDoTable je odkaz na back-endovou tabulku, kterou jste vytvořili dříve:

List<ToDoItem> result = mToDoTable
    .top(5)
    .execute()
    .get();

Tady je dotaz, který přeskočí prvních pět položek a vrátí následující pět položek:

List<ToDoItem> result = mToDoTable
    .skip(5).top(5)
    .execute()
    .get();

Pokud chcete získat všechny záznamy v tabulce, implementujte kód pro iteraci na všech stránkách:

List<MyDataModel> results = new ArrayList<>();
int nResults;
do {
    int currentCount = results.size();
    List<MyDataModel> pagedResults = mDataTable
        .skip(currentCount).top(500)
        .execute().get();
    nResults = pagedResults.size();
    if (nResults > 0) {
        results.addAll(pagedResults);
    }
} while (nResults > 0);

Požadavek na všechny záznamy pomocí této metody vytvoří minimálně dva požadavky na back-end Mobile Apps.

Tip

Volba správné velikosti stránky je vyvážená mezi využitím paměti v době, kdy probíhá požadavek, využití šířky pásma a zpoždění při úplném příjmu dat. Výchozí (50 záznamů) je vhodné pro všechna zařízení. Pokud pracujete výhradně na větších paměťových zařízeních, zvyšte až 500. Zjistili jsme, že zvýšení velikosti stránky nad 500 záznamů vede k nepřijatelným zpožděním a problémům s velkou pamětí.

Postupy: Zřetězení metod dotazů

Metody používané při dotazování back-endových tabulek je možné zřetězením. Řetězení metod dotazu umožňuje vybrat konkrétní sloupce filtrovaných řádků seřazených a stránkovaných. Můžete vytvořit složité logické filtry. Každá metoda dotazu vrátí objekt Query. Chcete-li ukončit řadu metod a skutečně spustit dotaz, zavolejte metodu execute . Příklad:

List<ToDoItem> results = mToDoTable
        .where()
        .year("due").eq(2013)
        .and(
            startsWith("text", "PRI0").or().field("duration").gt(10)
        )
        .orderBy(duration, QueryOrder.Ascending)
        .select("id", "complete", "text", "duration")
        .skip(200).top(100)
        .execute()
        .get();

Zřetězené metody dotazu musí být seřazeny takto:

  1. Filtrování (kde) metody
  2. Metody řazení (orderBy)
  3. Metody výběru (výběr)
  4. metody stránkování (přeskočení a shora).

Vytvoření vazby dat k uživatelskému rozhraní

Datová vazba zahrnuje tři komponenty:

  • Zdroj dat
  • Rozložení obrazovky
  • Adaptér, který obě spojí dohromady.

V našem ukázkovém kódu vrátíme data z tabulky Azure SQL Mobile Apps do pole. Tato aktivita je běžným vzorem pro datové aplikace. Databázové dotazy často vracejí kolekci řádků, které klient získá v seznamu nebo poli. V této ukázce je pole zdrojem dat. Kód určuje rozložení obrazovky, které definuje zobrazení dat, která se zobrazí v zařízení. Obě jsou svázané s adaptérem, který v tomto kódu je rozšíření ArrayAdapter<ToDoItem> třídy.

Definování rozložení

Rozložení je definováno několika fragmenty kódu XML. Vzhledem k existujícímu rozložení představuje následující kód ListView , který chceme naplnit daty serveru.

    <ListView
        android:id="@+id/listViewToDo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:listitem="@layout/row_list_to_do" >
    </ListView>

V předchozím kódu atribut listitem určuje ID rozložení pro jednotlivé řádky v seznamu. Tento kód určuje zaškrtávací políčko a přidružený text a vytvoří instanci jednou pro každou položku v seznamu. Toto rozložení nezobrazuje pole ID a složitější rozložení by na displeji určilo další pole. Tento kód je v souboru row_list_to_do.xml .

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <CheckBox
        android:id="@+id/checkToDoItem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/checkbox_text" />
</LinearLayout>

Definování adaptéru

Vzhledem k tomu, že zdrojem dat našeho zobrazení je pole ToDoItem, podtřídíme náš adaptér z ArrayAdapter<ToDoItem> třídy. Tato podtřída vytvoří zobrazení pro každou položku ToDoItem pomocí rozložení row_list_to_do . V našem kódu definujeme následující třídu, která je rozšířením ArrayAdapter<E> třídy:

public class ToDoItemAdapter extends ArrayAdapter<ToDoItem> {
}

Přepsat adaptéry getView metoda. Příklad:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;

        final ToDoItem currentItem = getItem(position);

        if (row == null) {
            LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
            row = inflater.inflate(R.layout.row_list_to_do, parent, false);
        }
        row.setTag(currentItem);

        final CheckBox checkBox = (CheckBox) row.findViewById(R.id.checkToDoItem);
        checkBox.setText(currentItem.getText());
        checkBox.setChecked(false);
        checkBox.setEnabled(true);

        checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                if (checkBox.isChecked()) {
                    checkBox.setEnabled(false);
                    if (mContext instanceof ToDoActivity) {
                        ToDoActivity activity = (ToDoActivity) mContext;
                        activity.checkItem(currentItem);
                    }
                }
            }
        });
        return row;
    }

V naší aktivitě vytvoříme instanci této třídy následujícím způsobem:

    ToDoItemAdapter mAdapter;
    mAdapter = new ToDoItemAdapter(this, R.layout.row_list_to_do);

Druhý parametr konstruktoru ToDoItemAdapter je odkazem na rozložení. Teď můžeme vytvořit instanci ListView a přiřadit adaptér k ListView.

    ListView listViewToDo = (ListView) findViewById(R.id.listViewToDo);
    listViewToDo.setAdapter(mAdapter);

Vytvoření vazby k uživatelskému rozhraní pomocí adaptéru

Teď jste připraveni použít datová vazba. Následující kód ukazuje, jak získat položky v tabulce a vyplnit místní adaptér vrácenými položkami.

    public void showAll(View view) {
        AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    final List<ToDoItem> results = mToDoTable.execute().get();
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            mAdapter.clear();
                            for (ToDoItem item : results) {
                                mAdapter.add(item);
                            }
                        }
                    });
                } catch (Exception exception) {
                    createAndShowDialog(exception, "Error");
                }
                return null;
            }
        };
        runAsyncTask(task);
    }

Adaptér zavolejte pokaždé, když upravíte tabulku ToDoItem . Vzhledem k tomu, že úpravy se provádějí na záznamu podle záznamu, zpracováváte jeden řádek místo kolekce. Když vložíte položku, zavolejte metodu add na adaptéru; při odstranění zavolejte metodu remove .

Kompletní příklad najdete v Projektu rychlého startu pro Android.

Vložení dat do back-endu

Vytvořte instanci Třídy ToDoItem a nastavte její vlastnosti.

ToDoItem item = new ToDoItem();
item.text = "Test Program";
item.complete = false;

Pak pomocí insert() vložte objekt:

ToDoItem entity = mToDoTable
    .insert(item)       // Returns a ListenableFuture<ToDoItem>
    .get();

Vrácená entita odpovídá datům vložených do back-endové tabulky, včetně ID a dalších hodnot (například createdAt, updatedAta version polí) nastavených na back-endu.

Tabulky Mobile Apps vyžadují sloupec s primárním klíčem s názvem ID. Tento sloupec musí být řetězec. Výchozí hodnota sloupce ID je IDENTIFIKÁTOR GUID. Můžete zadat další jedinečné hodnoty, například e-mailové adresy nebo uživatelská jména. Pokud pro vložený záznam není zadaná hodnota ID řetězce, back-end vygeneruje nový identifikátor GUID.

Hodnoty ID řetězce poskytují následující výhody:

  • ID se dají vygenerovat bez nutnosti provést zpáteční cestu do databáze.
  • Záznamy se snadněji sloučí z různých tabulek nebo databází.
  • Hodnoty ID se integrují lépe s logikou aplikace.

Hodnoty ID řetězce jsou povinné pro podporu offline synchronizace. Jakmile je ID uložené v back-endové databázi, nemůžete změnit.

Aktualizace dat v mobilní aplikaci

Chcete-li aktualizovat data v tabulce, předejte nový objekt metodě update().

mToDoTable
    .update(item)   // Returns a ListenableFuture<ToDoItem>
    .get();

V tomto příkladu je položka odkazem na řádek v tabulce ToDoItem , která obsahovala některé změny. Řádek se stejným ID se aktualizuje.

Odstranění dat v mobilní aplikaci

Následující kód ukazuje, jak odstranit data z tabulky zadáním datového objektu.

mToDoTable
    .delete(item);

Položku můžete odstranit také zadáním pole ID řádku, které chcete odstranit.

String myRowId = "2FA404AB-E458-44CD-BC1B-3BC847EF0902";
mToDoTable
    .delete(myRowId);

Vyhledání konkrétní položky podle ID

Vyhledejte položku s konkrétním polem ID pomocí metody lookUp():

ToDoItem result = mToDoTable
    .lookUp("0380BAFB-BCFF-443C-B7D5-30199F730335")
    .get();

Postupy: Práce s nezatypovanými daty

Netypový programovací model poskytuje přesnou kontrolu nad serializací JSON. Existují některé běžné scénáře, kdy můžete chtít použít netypový programovací model. Pokud například vaše back-endová tabulka obsahuje mnoho sloupců a stačí odkazovat jenom na podmnožinu sloupců. Typový model vyžaduje, abyste ve své datové třídě definovali všechny sloupce definované v back-endu Mobile Apps. Většina volání rozhraní API pro přístup k datům se podobá typovaným programovacím voláním. Hlavním rozdílem je, že v nezatypovaném modelu, který voláte metody na MobileServiceJsonTable objektu, místo MobileServiceTable objektu.

Vytvoření instance netypové tabulky

Podobně jako typový model začnete získáním odkazu na tabulku, ale v tomto případě se jedná o objekt MobileServicesJsonTable . Získejte odkaz voláním metody getTable v instanci klienta:

private MobileServiceJsonTable mJsonToDoTable;
//...
mJsonToDoTable = mClient.getTable("ToDoItem");

Jakmile vytvoříte instanci MobileServiceJsonTable, má prakticky stejné rozhraní API jako u typového programovacího modelu. V některých případech metody místo zadaného parametru přebírají netypový parametr.

Vložení do nezatypované tabulky

Následující kód ukazuje, jak provést vložení. Prvním krokem je vytvoření objektu JsonObject, který je součástí knihovny gson .

JsonObject jsonItem = new JsonObject();
jsonItem.addProperty("text", "Wake up");
jsonItem.addProperty("complete", false);

Potom pomocí insert() vložte nezatypovaný objekt do tabulky.

JsonObject insertedItem = mJsonToDoTable
    .insert(jsonItem)
    .get();

Pokud potřebujete získat ID vloženého objektu, použijte metodu getAsJsonPrimitive().

String id = insertedItem.getAsJsonPrimitive("id").getAsString();

Odstranění z nezatypované tabulky

Následující kód ukazuje, jak odstranit instanci, v tomto případě stejnou instanci JsonObject , která byla vytvořena v předchozím příkladu vložení . Kód je stejný jako u typového případu, ale metoda má jiný podpis, protože odkazuje na JsonObject.

mToDoTable
    .delete(insertedItem);

Instanci můžete také odstranit přímo pomocí jeho ID:

mToDoTable.delete(ID);

Vrácení všech řádků z nezatypované tabulky

Následující kód ukazuje, jak načíst celou tabulku. Vzhledem k tomu, že používáte tabulku JSON, můžete selektivně načíst jenom některé sloupce tabulky.

public void showAllUntyped(View view) {
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                final JsonElement result = mJsonToDoTable.execute().get();
                final JsonArray results = result.getAsJsonArray();
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        mAdapter.clear();
                        for (JsonElement item : results) {
                            String ID = item.getAsJsonObject().getAsJsonPrimitive("id").getAsString();
                            String mText = item.getAsJsonObject().getAsJsonPrimitive("text").getAsString();
                            Boolean mComplete = item.getAsJsonObject().getAsJsonPrimitive("complete").getAsBoolean();
                            ToDoItem mToDoItem = new ToDoItem();
                            mToDoItem.setId(ID);
                            mToDoItem.setText(mText);
                            mToDoItem.setComplete(mComplete);
                            mAdapter.add(mToDoItem);
                        }
                    }
                });
            } catch (Exception exception) {
                createAndShowDialog(exception, "Error");
            }
            return null;
        }
    }.execute();
}

Stejná sada metod filtrování, filtrování a stránkování, které jsou k dispozici pro typový model, jsou k dispozici pro netypový model.

Implementace offline synchronizace

Klientská sada SDK služby Azure Mobile Apps také implementuje offline synchronizaci dat pomocí databáze SQLite k místnímu uložení kopie dat serveru. Operace prováděné v offline tabulce nevyžadují, aby fungovalo mobilní připojení. Offline synchronizace pomáhá při odolnosti a výkonu na úkor složitější logiky pro řešení konfliktů. Klientská sada SDK služby Azure Mobile Apps implementuje následující funkce:

  • Přírůstková synchronizace: Stáhnou se jenom aktualizované a nové záznamy, což šetří šířku pásma a spotřebu paměti.
  • Optimistická souběžnost: Předpokládá se, že operace budou úspěšné. Řešení konfliktů je odloženo, dokud se na serveru neprovedou aktualizace.
  • Řešení konfliktů: Sada SDK zjistí, kdy byla na serveru provedena konfliktní změna, a poskytuje háky pro upozornění uživatele.
  • Obnovitelné odstranění: Odstraněné záznamy jsou označené jako odstraněné, což ostatním zařízením umožňuje aktualizovat offline mezipaměť.

Inicializace offline synchronizace

Před použitím musí být každá offline tabulka definována v offline mezipaměti. Za normálních okolností se definice tabulky provádí okamžitě po vytvoření klienta:

AsyncTask<Void, Void, Void> initializeStore(MobileServiceClient mClient)
    throws MobileServiceLocalStoreException, ExecutionException, InterruptedException
{
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
        @Override
        protected void doInBackground(Void... params) {
            try {
                MobileServiceSyncContext syncContext = mClient.getSyncContext();
                if (syncContext.isInitialized()) {
                    return null;
                }
                SQLiteLocalStore localStore = new SQLiteLocalStore(mClient.getContext(), "offlineStore", null, 1);

                // Create a table definition.  As a best practice, store this with the model definition and return it via
                // a static method
                Map<String, ColumnDataType> toDoItemDefinition = new HashMap<String, ColumnDataType>();
                toDoItemDefinition.put("id", ColumnDataType.String);
                toDoItemDefinition.put("complete", ColumnDataType.Boolean);
                toDoItemDefinition.put("text", ColumnDataType.String);
                toDoItemDefinition.put("version", ColumnDataType.String);
                toDoItemDefinition.put("updatedAt", ColumnDataType.DateTimeOffset);

                // Now define the table in the local store
                localStore.defineTable("ToDoItem", toDoItemDefinition);

                // Specify a sync handler for conflict resolution
                SimpleSyncHandler handler = new SimpleSyncHandler();

                // Initialize the local store
                syncContext.initialize(localStore, handler).get();
            } catch (final Exception e) {
                createAndShowDialogFromTask(e, "Error");
            }
            return null;
        }
    };
    return runAsyncTask(task);
}

Získání odkazu na tabulku offline mezipaměti

Pro online tabulku použijete .getTable(). Pro offline tabulku použijte .getSyncTable():

MobileServiceSyncTable<ToDoItem> mToDoTable = mClient.getSyncTable("ToDoItem", ToDoItem.class);

Všechny dostupné metody pro online tabulky (včetně filtrování, řazení, stránkování, vkládání dat, aktualizace dat a odstraňování dat) fungují stejně dobře u online a offline tabulek.

Synchronizace místní offline mezipaměti

Synchronizace je v rámci řízení vaší aplikace. Tady je příklad metody synchronizace:

private AsyncTask<Void, Void, Void> sync(MobileServiceClient mClient) {
    AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>(){
        @Override
        protected Void doInBackground(Void... params) {
            try {
                MobileServiceSyncContext syncContext = mClient.getSyncContext();
                syncContext.push().get();
                mToDoTable.pull(null, "todoitem").get();
            } catch (final Exception e) {
                createAndShowDialogFromTask(e, "Error");
            }
            return null;
        }
    };
    return runAsyncTask(task);
}

Pokud je metodě .pull(query, queryname) zadán název dotazu, přírůstková synchronizace se použije k vrácení pouze záznamů, které byly vytvořeny nebo změněny od posledního úspěšného dokončení přijetí změn.

Zpracování konfliktů během offline synchronizace

Pokud během operace dojde ke .push() konfliktu, MobileServiceConflictException vyvolá se chyba. Položka vystavená serverem je vložena do výjimky a lze ji načíst .getItem() u výjimky. Nastavte nabízení voláním následujících položek v objektu MobileServiceSyncContext:

  • .cancelAndDiscardItem()
  • .cancelAndUpdateItem()
  • .updateOperationAndItem()

Jakmile jsou všechny konflikty označené jako požadované, zavolejte .push() znovu a vyřešte všechny konflikty.

Volání vlastního rozhraní API

Vlastní rozhraní API umožňuje definovat vlastní koncové body, které zpřístupňují funkce serveru, které se nemapují na operaci vložení, aktualizace, odstranění nebo čtení. Pomocí vlastního rozhraní API můžete mít větší kontrolu nad zasíláním zpráv, včetně čtení a nastavení hlaviček zpráv HTTP a definování jiného formátu textu zprávy než JSON.

Z klienta Androidu zavoláte metodu invokeApi pro volání vlastního koncového bodu rozhraní API. Následující příklad ukazuje, jak volat koncový bod rozhraní API s názvem completeAll, který vrací třídu kolekce s názvem MarkAllResult.

public void completeItem(View view) {
    ListenableFuture<MarkAllResult> result = mClient.invokeApi("completeAll", MarkAllResult.class);
    Futures.addCallback(result, new FutureCallback<MarkAllResult>() {
        @Override
        public void onFailure(Throwable exc) {
            createAndShowDialog((Exception) exc, "Error");
        }

        @Override
        public void onSuccess(MarkAllResult result) {
            createAndShowDialog(result.getCount() + " item(s) marked as complete.", "Completed Items");
            refreshItemsFromTable();
        }
    });
}

Metoda invokeApi je volána v klientovi, který odešle požadavek POST do nového vlastního rozhraní API. Výsledek vrácený vlastním rozhraním API se zobrazí v dialogovém okně zprávy, stejně jako případné chyby. Jiné verze invokeApi umožňují volitelně odeslat objekt v textu požadavku, zadat metodu HTTP a odeslat parametry dotazu s požadavkem. K dispozici jsou také netypové verze invokeApi .

Přidání ověřování do aplikace

Kurzy už podrobně popisují, jak tyto funkce přidat.

App Service podporuje ověřování uživatelů aplikací pomocí různých externích zprostředkovatelů identity: Facebook, Google, účet Microsoft, Twitter a Azure Active Directory. U tabulek můžete nastavit oprávnění k omezení přístupu pro konkrétní operace pouze ověřeným uživatelům. Identitu ověřených uživatelů můžete použít také k implementaci autorizačních pravidel v back-endu.

Podporují se dva toky ověřování: tok serveru a tok klienta . Tok serveru poskytuje nejjednodušší možnosti ověřování, protože spoléhá na webové rozhraní zprostředkovatelů identity. K implementaci ověřování toku serveru nejsou potřeba žádné další sady SDK. Ověřování toku serveru neposkytuje hlubokou integraci do mobilního zařízení a doporučuje se pouze pro testování scénářů konceptu.

Tok klienta umožňuje hlubší integraci s funkcemi specifickými pro zařízení, jako je jednotné přihlašování, protože spoléhá na sady SDK poskytované zprostředkovatelem identity. Sadu SDK pro Facebook můžete například integrovat do mobilní aplikace. Mobilní klient se prohodí do aplikace Facebook a před přepnutím zpět do mobilní aplikace potvrdí vaše přihlášení.

K povolení ověřování ve vaší aplikaci se vyžadují čtyři kroky:

  • Zaregistrujte aplikaci k ověřování u zprostředkovatele identity.
  • Nakonfigurujte back-end služby App Service.
  • Omezte oprávnění tabulky jenom na back-endu služby App Service pro ověřené uživatele.
  • Přidejte do aplikace ověřovací kód.

U tabulek můžete nastavit oprávnění k omezení přístupu pro konkrétní operace pouze ověřeným uživatelům. K úpravě požadavků můžete také použít identifikátor SID ověřeného uživatele. Další informace najdete v tématu Začínáme s ověřováním a dokumentace postupy sady Server SDK.

Ověřování: Tok serveru

Následující kód spustí proces přihlášení toku serveru pomocí poskytovatele Google. Kvůli požadavkům na zabezpečení poskytovatele Google se vyžaduje další konfigurace:

MobileServiceUser user = mClient.login(MobileServiceAuthenticationProvider.Google, "{url_scheme_of_your_app}", GOOGLE_LOGIN_REQUEST_CODE);

Kromě toho přidejte do hlavní třídy Activity následující metodu:

// You can choose any unique number here to differentiate auth providers from each other. Note this is the same code at login() and onActivityResult().
public static final int GOOGLE_LOGIN_REQUEST_CODE = 1;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // When request completes
    if (resultCode == RESULT_OK) {
        // Check the request code matches the one we send in the login request
        if (requestCode == GOOGLE_LOGIN_REQUEST_CODE) {
            MobileServiceActivityResult result = mClient.onActivityResult(data);
            if (result.isLoggedIn()) {
                // login succeeded
                createAndShowDialog(String.format("You are now logged in - %1$2s", mClient.getCurrentUser().getUserId()), "Success");
                createTable();
            } else {
                // login failed, check the error message
                String errorMessage = result.getErrorMessage();
                createAndShowDialog(errorMessage, "Error");
            }
        }
    }
}

Definice GOOGLE_LOGIN_REQUEST_CODE v hlavní aktivitě se používá pro metodu login() a v rámci onActivityResult() metody. Můžete zvolit libovolné jedinečné číslo, pokud se v metodě login() a onActivityResult() metodě použije stejné číslo. Pokud abstrahujete kód klienta do adaptéru služby (jak je znázorněno výše), měli byste na adaptéru služby volat příslušné metody.

Musíte také nakonfigurovat projekt pro vlastnítaby. Nejprve zadejte adresu URL pro přesměrování. Přidejte následující fragment kódu do AndroidManifest.xml:

<activity android:name="com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="{url_scheme_of_your_app}" android:host="easyauth.callback"/>
    </intent-filter>
</activity>

Do souboru pro vaši aplikaci přidejte redirectUriSchemebuild.gradle:

android {
    buildTypes {
        release {
            // … …
            manifestPlaceholders = ['redirectUriScheme': '{url_scheme_of_your_app}://easyauth.callback']
        }
        debug {
            // … …
            manifestPlaceholders = ['redirectUriScheme': '{url_scheme_of_your_app}://easyauth.callback']
        }
    }
}

Nakonec do seznamu závislostí v build.gradle souboru přidejtecom.android.support:customtabs:28.0.0:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.code.gson:gson:2.3'
    implementation 'com.google.guava:guava:18.0'
    implementation 'com.android.support:customtabs:28.0.0'
    implementation 'com.squareup.okhttp:okhttp:2.5.0'
    implementation 'com.microsoft.azure:azure-mobile-android:3.4.0@aar'
    implementation 'com.microsoft.azure:azure-notifications-handler:1.0.1@jar'
}

Pomocí metody getUser získejte ID přihlášeného uživatele z MobileServiceUser. Příklad použití Futures k volání asynchronních přihlašovacích rozhraní API najdete v tématu Začínáme s ověřováním.

Upozorňující

Uvedené schéma adres URL rozlišují malá a velká písmena. Ujistěte se, že všechny výskyty {url_scheme_of_you_app} případu shody.

Tokeny ověřování mezipaměti

Ukládání ověřovacích tokenů do mezipaměti vyžaduje, abyste na zařízení uložili ID uživatele a ověřovací token místně. Při příštím spuštění aplikace zkontrolujete mezipaměť a pokud jsou tyto hodnoty k dispozici, můžete přeskočit postup přihlášení a dosadit klienta s těmito daty. Tato data jsou ale citlivá a měla by být uložena zašifrovaná, aby se v případě odcizení telefonu ukradla. Úplný příklad ukládání ověřovacích tokenů do mezipaměti najdete v části Ověřovací tokeny mezipaměti.

Když se pokusíte použít token s vypršenou platností, obdržíte neautorizovanou odpověď 401. Chyby ověřování můžete zpracovat pomocí filtrů. Filtruje zachytávání požadavků na back-end služby App Service. Kód filtru otestuje odpověď na 401, aktivuje proces přihlášení a pak obnoví požadavek, který vygeneroval 401.

Použití obnovovacích tokenů

Token vrácený ověřováním a autorizací služby Aplikace Azure má definovanou dobu životnosti jedné hodiny. Po uplynutí této doby musíte uživatele znovu autorizovat. Pokud používáte dlouhodobý token, který jste obdrželi prostřednictvím ověřování toku klienta, můžete pomocí stejného tokenu znovu ověřit ověřování služby Aplikace Azure Service Authentication and Authorization. Další Aplikace Azure token služby se vygeneruje s novou životností.

Můžete také zaregistrovat poskytovatele, aby používal obnovovací tokeny. Obnovovací token není vždy k dispozici. Vyžaduje se další konfigurace:

  • Pro Azure Active Directory nakonfigurujte tajný klíč klienta pro aplikaci Azure Active Directory. Při konfiguraci ověřování Azure Active Directory zadejte tajný klíč klienta ve službě Aplikace Azure Service. Při volání .login()předejte response_type=code id_token jako parametr:

    HashMap<String, String> parameters = new HashMap<String, String>();
    parameters.put("response_type", "code id_token");
    MobileServiceUser user = mClient.login
        MobileServiceAuthenticationProvider.AzureActiveDirectory,
        "{url_scheme_of_your_app}",
        AAD_LOGIN_REQUEST_CODE,
        parameters);
    
  • Pro Google předejte access_type=offline jako parametr:

    HashMap<String, String> parameters = new HashMap<String, String>();
    parameters.put("access_type", "offline");
    MobileServiceUser user = mClient.login
        MobileServiceAuthenticationProvider.Google,
        "{url_scheme_of_your_app}",
        GOOGLE_LOGIN_REQUEST_CODE,
        parameters);
    
  • U účtu Microsoft vyberte wl.offline_access obor.

Pokud chcete token aktualizovat, zavolejte .refreshUser():

MobileServiceUser user = mClient
    .refreshUser()  // async - returns a ListenableFuture<MobileServiceUser>
    .get();

Osvědčeným postupem je vytvořit filtr, který zjistí odpověď 401 ze serveru a pokusí se aktualizovat token uživatele.

Přihlášení pomocí ověřování toku klienta

Obecný proces přihlašování pomocí ověřování toku klienta je následující:

  • Nakonfigurujte ověřování a autorizaci služby Aplikace Azure stejně jako ověřování toku serveru.

  • Integrujte sadu SDK zprostředkovatele ověřování pro ověřování, aby se vytvořil přístupový token.

  • Zavolejte metodu .login() následujícím způsobem (result měla by být AuthenticationResult):

    JSONObject payload = new JSONObject();
    payload.put("access_token", result.getAccessToken());
    ListenableFuture<MobileServiceUser> mLogin = mClient.login("{provider}", payload.toString());
    Futures.addCallback(mLogin, new FutureCallback<MobileServiceUser>() {
        @Override
        public void onFailure(Throwable exc) {
            exc.printStackTrace();
        }
        @Override
        public void onSuccess(MobileServiceUser user) {
            Log.d(TAG, "Login Complete");
        }
    });
    

Podívejte se na úplný příklad kódu v další části.

Nahraďte metodu onSuccess() jakýmkoli kódem, který chcete použít při úspěšném přihlášení. Řetězec {provider} je platným poskytovatelem: aad (Azure Active Directory), facebook, google, microsoftaccount nebo twitter. Pokud jste implementovali vlastní ověřování, můžete také použít značku vlastního zprostředkovatele ověřování.

Ověřování uživatelů pomocí knihovny ADAL (Active Directory Authentication Library)

Knihovnu ADAL (Active Directory Authentication Library) můžete použít k přihlášení uživatelů k aplikaci pomocí Azure Active Directory. Použití přihlášení toku klienta je často vhodnější než použití loginAsync() metod, protože poskytuje nativní uživatelské prostředí a umožňuje další přizpůsobení.

  1. Nakonfigurujte back-end mobilní aplikace pro přihlášení AAD podle kurzu Konfigurace služby App Service pro přihlášení ke službě Active Directory. Nezapomeňte dokončit volitelný krok registrace nativní klientské aplikace.

  2. Nainstalujte ADAL úpravou souboru build.gradle tak, aby obsahoval následující definice:

    repositories {
        mavenCentral()
        flatDir {
            dirs 'libs'
        }
        maven {
            url "YourLocalMavenRepoPath\\.m2\\repository"
        }
    }
    packagingOptions {
        exclude 'META-INF/MSFTSIG.RSA'
        exclude 'META-INF/MSFTSIG.SF'
    }
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation('com.microsoft.aad:adal:1.16.1') {
            exclude group: 'com.android.support'
        } // Recent version is 1.16.1
        implementation 'com.android.support:support-v4:28.0.0'
    }
    
  3. Do aplikace přidejte následující kód a proveďte následující nahrazení:

    • Insert-AUTHORITY-HERE nahraďte názvem tenanta, ve kterém jste zřídili aplikaci. Formát by měl být https://login.microsoftonline.com/contoso.onmicrosoft.com.
    • Nahraďte INSERT-RESOURCE-ID-HERE ID klienta pro back-end mobilní aplikace. ID klienta můžete získat na kartě Upřesnit v části Nastavení služby Azure Active Directory na portálu.
    • Nahraďte INSERT-CLIENT-ID-HERE ID klienta, které jste zkopírovali z nativní klientské aplikace.
    • Příkaz INSERT-REDIRECT-URI-HERE nahraďte koncovým bodem /.auth/login/done vašeho webu pomocí schématu HTTPS. Tato hodnota by měla být podobná https://contoso.azurewebsites.net/.auth/login/done.
private AuthenticationContext mContext;

private void authenticate() {
    String authority = "INSERT-AUTHORITY-HERE";
    String resourceId = "INSERT-RESOURCE-ID-HERE";
    String clientId = "INSERT-CLIENT-ID-HERE";
    String redirectUri = "INSERT-REDIRECT-URI-HERE";
    try {
        mContext = new AuthenticationContext(this, authority, true);
        mContext.acquireToken(this, resourceId, clientId, redirectUri, PromptBehavior.Auto, "", callback);
    } catch (Exception exc) {
        exc.printStackTrace();
    }
}

private AuthenticationCallback<AuthenticationResult> callback = new AuthenticationCallback<AuthenticationResult>() {
    @Override
    public void onError(Exception exc) {
        if (exc instanceof AuthenticationException) {
            Log.d(TAG, "Cancelled");
        } else {
            Log.d(TAG, "Authentication error:" + exc.getMessage());
        }
    }

    @Override
    public void onSuccess(AuthenticationResult result) {
        if (result == null || result.getAccessToken() == null
                || result.getAccessToken().isEmpty()) {
            Log.d(TAG, "Token is empty");
        } else {
            try {
                JSONObject payload = new JSONObject();
                payload.put("access_token", result.getAccessToken());
                ListenableFuture<MobileServiceUser> mLogin = mClient.login("aad", payload.toString());
                Futures.addCallback(mLogin, new FutureCallback<MobileServiceUser>() {
                    @Override
                    public void onFailure(Throwable exc) {
                        exc.printStackTrace();
                    }
                    @Override
                    public void onSuccess(MobileServiceUser user) {
                        Log.d(TAG, "Login Complete");
                    }
                });
            }
            catch (Exception exc){
                Log.d(TAG, "Authentication error:" + exc.getMessage());
            }
        }
    }
};

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (mContext != null) {
        mContext.onActivityResult(requestCode, resultCode, data);
    }
}

Úprava komunikace mezi klientem a serverem

Připojení klienta je obvykle základní připojení HTTP pomocí základní knihovny HTTP dodané se sadou Android SDK. Existuje několik důvodů, proč byste to chtěli změnit:

  • K úpravě časových limitů chcete použít alternativní knihovnu HTTP.
  • Chcete poskytnout indikátor průběhu.
  • Chcete přidat vlastní hlavičku pro podporu funkcí služby API Management.
  • Chcete zachytit neúspěšnou odpověď, abyste mohli implementovat opětovné ověření.
  • Chcete protokolovat požadavky back-endu do analytické služby.

Použití alternativní knihovny HTTP

Volejte metodu .setAndroidHttpClientFactory() okamžitě po vytvoření odkazu na klienta. Pokud chcete například nastavit časový limit připojení na 60 sekund (místo výchozích 10 sekund):

mClient = new MobileServiceClient("https://myappname.azurewebsites.net");
mClient.setAndroidHttpClientFactory(new OkHttpClientFactory() {
    @Override
    public OkHttpClient createOkHttpClient() {
        OkHttpClient client = new OkHttpClient();
        client.setReadTimeout(60, TimeUnit.SECONDS);
        client.setWriteTimeout(60, TimeUnit.SECONDS);
        return client;
    }
});

Implementace filtru průběhu

Zachytávání každého požadavku můžete implementovat implementací ServiceFilter. Například následující aktualizace předem vytvořeného indikátoru průběhu:

private class ProgressFilter implements ServiceFilter {
    @Override
    public ListenableFuture<ServiceFilterResponse> handleRequest(ServiceFilterRequest request, NextServiceFilterCallback next) {
        final SettableFuture<ServiceFilterResponse> resultFuture = SettableFuture.create();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (mProgressBar != null) mProgressBar.setVisibility(ProgressBar.VISIBLE);
            }
        });

        ListenableFuture<ServiceFilterResponse> future = next.onNext(request);
        Futures.addCallback(future, new FutureCallback<ServiceFilterResponse>() {
            @Override
            public void onFailure(Throwable e) {
                resultFuture.setException(e);
            }
            @Override
            public void onSuccess(ServiceFilterResponse response) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (mProgressBar != null)
                            mProgressBar.setVisibility(ProgressBar.GONE);
                    }
                });
                resultFuture.set(response);
            }
        });
        return resultFuture;
    }
}

Tento filtr můžete k klientovi připojit následujícím způsobem:

mClient = new MobileServiceClient(applicationUrl).withFilter(new ProgressFilter());

Přizpůsobení hlaviček požadavků

Použijte následující ServiceFilter a připojte filtr stejným způsobem jako ProgressFilter:

private class CustomHeaderFilter implements ServiceFilter {
    @Override
    public ListenableFuture<ServiceFilterResponse> handleRequest(ServiceFilterRequest request, NextServiceFilterCallback next) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                request.addHeader("X-APIM-Router", "mobileBackend");
            }
        });
        SettableFuture<ServiceFilterResponse> result = SettableFuture.create();
        try {
            ServiceFilterResponse response = next.onNext(request).get();
            result.set(response);
        } catch (Exception exc) {
            result.setException(exc);
        }
    }
}

Konfigurace automatické serializace

Pomocí rozhraní API gson můžete zadat strategii převodu, která se vztahuje na každý sloupec. Klientská knihovna pro Android používá gson na pozadí k serializaci objektů Java na data JSON před odesláním dat do služby Aplikace Azure Service. Následující kód používá setFieldNamingStrategy() metoda k nastavení strategie. V tomto příkladu se odstraní počáteční znak ("m") a potom malá a malá písmena pro každý název pole. Například se změní "mId" na "id". Implementujte strategii převodu, která snižuje potřebu poznámek u SerializedName() většiny polí.

FieldNamingStrategy namingStrategy = new FieldNamingStrategy() {
    public String translateName(File field) {
        String name = field.getName();
        return Character.toLowerCase(name.charAt(1)) + name.substring(2);
    }
}

client.setGsonBuilder(
    MobileServiceClient
        .createMobileServiceGsonBuilder()
        .setFieldNamingStrategy(namingStrategy)
);

Tento kód musí být proveden před vytvořením odkazu na mobilního klienta pomocí MobileServiceClient.