Android için Azure Mobile Apps SDK'sı kullanma

Bu kılavuzda, aşağıdakiler gibi yaygın senaryoları uygulamak Mobile Apps için Android istemci SDK'sı nasıl kullanılır?

  • Veri sorgulama (ekleme, güncelleştirme ve silme).
  • Kimlik doğrulaması.
  • Hataları işleme.
  • İstemciyi özelleştirme.

Bu kılavuz, istemci tarafı Android SDK. Mobile Apps için sunucu tarafı SDK'ları hakkında daha fazla bilgi edinmek için bkz. .NET arka uç SDK'sı ile çalışma veya Node.js SDK'sı kullanma.

Başvuru Belgeleri

Android istemci kitaplığı için Javadocs API başvurularını aşağıdaki GitHub.

Desteklenen Platformlar

Android için Azure Mobile Apps SDK'sı, telefon ve tablet form faktörleri için API düzeylerini 19 ile 24 (KitKat- Nookat) destekler. Kimlik doğrulaması, özellikle kimlik bilgilerini toplamak için ortak bir web çerçevesi yaklaşımı kullanır. Sunucu akışı kimlik doğrulaması, saatler gibi küçük form faktörü cihazlarıyla birlikte çalışmaz.

Kurulum ve Önkoşullar

Hızlı başlangıç Mobile Apps öğreticiyi tamamlama. Bu görev, Azure hizmetleri geliştirmeyle ilgili tüm önk Mobile Apps karşılar. Hızlı Başlangıç ayrıca, hesabınız yapılandırmanıza ve ilk Mobil Uygulama arka ucu oluşturmanıza yardımcı olur.

Hızlı Başlangıç öğreticisi'nin tamamlanmadı mı?

Gradle derleme dosyasını güncelleştirme

Her iki build.gradle dosyalarını da değiştirme:

  1. Bu kodu Project düzeyi build.gradle dosyasına ekleyin:

    buildscript {
        repositories {
            jcenter()
            google()
        }
    }
    
    allprojects {
        repositories {
            jcenter()
            google()
        }
    }
    
  2. Bu kodu Dependenciesetiketinin içindekiModule uygulama düzeyi build.gradle dosyasına ekleyin:

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

    Şu anda en son sürüm 3.4.0'dır. Desteklenen sürümler bintray üzerinde listelenir.

İnternet iznini etkinleştirme

Azure'a erişmek için, uygulamanıza İnternet izninin etkinleştirilmiş olması gerekir. Henüz etkinleştirilmemişse aşağıdaki kod satırı dosyasını dosyanıza AndroidManifest.xml ekleyin:

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

İstemci Bağlantısı Oluşturma

Azure Mobile Apps mobil uygulamanıza dört işlev sağlar:

  • Azure Mobile Apps Hizmeti ile Veri Erişimi ve Çevrimdışı Eşitleme.
  • Azure Mobile Apps Server SDK'sı ile yazılmış özel API'leri çağırma.
  • Kimlik Doğrulaması Azure App Service Yetkilendirme ile kimlik doğrulaması.
  • Notification Hubs ile Anında Notification Hubs.

Bu işlevlerin her biri için öncelikle bir nesnesi oluşturmanız MobileServiceClient gerekir. Mobil istemciniz MobileServiceClient içinde yalnızca bir nesne oluşturularak (tekli desen olması gerekir). Nesne oluşturmak MobileServiceClient için:

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

, <MobileAppUrl> mobil arka ucunıza yönelik bir dize veya URL nesnesidir. Mobil arka ucu Azure App Service için bir uygulama kullanıyorsanız URL'nin güvenli sürümünü kullanmaya https:// devam edin.

İstemci, örnekteki parametre olan Etkinlik veya Bağlam'a this da erişim gerektirir. MobileServiceClient yapısı, dosyasında başvurulan onCreate() Etkinliğin yöntemi içinde gerçekleşecektir AndroidManifest.xml .

En iyi uygulama olarak, sunucu iletişimini kendi (tek desenli) sınıfına soyutlamalısınız. Bu durumda, hizmeti uygun şekilde yapılandırmak için oluşturucu içindeki Etkinlik'i geçebilirsiniz. Örnek:

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.
}

Artık ana etkinliğinizin AzureServiceAdapter.Initialize(this);onCreate() yönteminde çağrısı da kullanabilirsiniz. Hizmet bağdaştırıcısına başvuru almak için istemci kullanımına AzureServiceAdapter.getInstance(); erişmesi gereken diğer yöntemler.

Veri İşlemleri

Azure Mobile Apps SDK'sı temel olarak Mobil Uygulama arka uçta SQL Azure verilerine erişim sağlamaktır. Bu verilere kesin olarak türü kesin olarak yazılmış sınıfları (tercih edilen) veya yazlanmamış sorguları kullanarak erişebilirsiniz (önerilmez). Bu bölümün büyük bölümü kesin olarak türü kesin olarak yazıldı sınıflarını kullanmayla ilgilenmektedir.

İstemci veri sınıflarını tanımlama

Veri tablolarından SQL Azure için, Mobil Uygulama arka uçta tablolara karşılık gelen istemci veri sınıflarını tanımlayın. Bu konudaki örneklerde, aşağıdaki sütunlara sahip MyDataTable adlı bir tablo varsayıldı:

  • kimlik
  • metin
  • tamamlama

İlgili türe sahip istemci tarafı nesnesi MyDataTable.java adlı bir dosyada bulunur:

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

Ekley istediğiniz her alan için getter ve setter yöntemleri ekleyin. Tablo SQL Azure fazla sütun içeriyorsa, karşılık gelen alanları bu sınıfa eklersiniz. Örneğin, DTO (veri aktarımı nesnesi) bir tamsayı Priority sütununa sahipse, bu alanı, onun getter ve setter yöntemleriyle birlikte eklersiniz:

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;
}

Mobile Apps arka ucunda ek tablolar oluşturma hakkında bilgi edinmek için bkz . Nasıl? Nasıl? Tablo denetleyicisi (.NET arka ucu) tanımlama veya Dinamik Şema kullanarak Tabloları Tanımlama (Node.js arka ucu).

Azure Mobile Apps arka uç tablosu, dört tane istemci tarafından kullanılabilen beş özel alan tanımlar:

  • String id: Kaydın genel olarak benzersiz kimliği. En iyi uygulama olarak, kimliği bir UUID nesnesinin Dize gösterimi olarak kullanın.
  • DateTimeOffset updatedAt: Son güncelleştirmenin tarihi/saati. updatedAt alanı sunucu tarafından ayarlanır ve hiçbir zaman istemci kodunuz tarafından ayarlenmez.
  • DateTimeOffset createdAt: Nesnenin oluşturulma tarihi/saati. createdAt alanı sunucu tarafından ayarlanır ve istemci kodunuz tarafından hiçbir zaman ayar oluşturulmaz.
  • byte[] version: Normalde dize olarak temsil edilen sürüm de sunucu tarafından ayarlanır.
  • boolean deleted: Kaydın silindi ancak henüz temiz olmadığını gösterir. sınıfınıza deleted bir özellik olarak kullanmayın.

id alanı gereklidir. Alan updatedAt ve alan version çevrimdışı eşitleme için kullanılır (sırasıyla artımlı eşitleme ve çakışma çözümlemesi için). alanı createdAt bir başvuru alanıdır ve istemci tarafından kullanılmaz. Adları özelliklerin "kablolar arasında" adlarıdır ve ayarlanabilir değildir. Ancak, gson kitaplığını kullanarak nesneniz ve "kablolar arası" adlar arasında bir eşleme oluşturabilirsiniz . Örnek:

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();
    }
}

Tablo Başvurusu Oluşturma

Bir tabloya erişmek için, önce MobileServiceClient üzerinde getTable yöntemini çağırarak bir MobileServiceTable nesnesi oluşturun. Bu yöntemin iki aşırı yüklemesi vardır:

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

Aşağıdaki kodda mClient, MobileServiceClient nesnenize bir başvurudur. İlk aşırı yükleme, sınıf adı ve tablo adının aynı olduğu ve Hızlı Başlangıç'ta kullanılan yük olduğu yerde kullanılır:

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

İkinci aşırı yükleme, tablo adı sınıf adlarından farklı olduğunda kullanılır: ilk parametre tablo adıdır.

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

Arka Uç Tablosu Sorgulama

İlk olarak bir tablo başvurusu alın. Ardından tablo başvurusunda bir sorgu yürütün. Sorgu, şunların herhangi bir birleşimidir:

Yan tümceleri önceki sırayla sun gerekir.

Sonuçları Filtreleme

Sorgunun genel biçimi şöyledir:

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

Yukarıdaki örnek tüm sonuçları döndürür (sunucu tarafından ayarlanmış en büyük sayfa boyutuna kadar). .execute()Yöntemi arka uçta sorguyu yürütür. Sorgu, Mobile Apps arka uca iletilmeyen bir OData v3 sorgusuna dönüştürülür. alındı, Mobile Apps arka ucu sorguyu SQL Azure örneğinde yürütmeden önce bir SQL ifadesine dönüştürür. Ağ etkinliği biraz zaman alacağından, .execute() yöntemi döndürür ListenableFuture<E> .

Döndürülen verileri filtrele

Aşağıdaki sorgu yürütmesi, TodoItemtablosundan tüm öğeleri döndürür ve bunun tümü eşittir falseşeklindedir.

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

mToDoTable , daha önce oluşturduğumuz mobil hizmet tablosuna başvurudur.

Tablo başvurusunda WHERE yöntemi çağrısını kullanarak bir filtre tanımlayın. WHERE yönteminin ardından bir field yöntemi ve ardından mantıksal koşulu belirten bir yöntem gelir. Olası koşul yöntemlerinde EQ (eşittir), ne (eşit değildir), gt (büyüktür), Ge (büyüktür veya eşittir), lt (küçüktür), Le (küçüktür veya eşittir) bulunur. Bu yöntemler, sayı ve dize alanlarını belirli değerlerle karşılaştırmanızı sağlar.

Tarihlere filtre uygulayabilirsiniz. Aşağıdaki yöntemler tarih alanını veya tarihin tüm parçalarını karşılaştırmanızı sağlar: yıl, ay, gün, saat, dakikave saniye. Aşağıdaki örnek, son tarihi 2013 'e eşit olan öğeler için bir filtre ekler.

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

Aşağıdaki yöntemler dize alanlarında karmaşık filtreleri destekler: StartsWith, EndsWith, Concat, subString, IndexOf, Replace, ToLower, ToUpper, trimve length. Aşağıdaki örnek, metin SÜTUNUNUN "PRI0" ile başladığı tablo satırları için filtre uygular.

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

Şu işleç yöntemleri sayı alanlarında desteklenir: Add, Sub, MUL, div, mod, Floor, tavanve yuvarlak. Aşağıdaki örnek, sürenin çift sayı olduğu tablo satırları için filtre uygular.

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

Koşulları şu mantıksal yöntemlerle birleştirebilirsiniz: ve, veya. Aşağıdaki örnek, Yukarıdaki örneklerin ikisini de birleştirir.

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

Grup ve iç içe mantıksal işleçler:

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

Daha ayrıntılı tartışmalar ve filtreleme örnekleri için bkz. Android istemci sorgu modelinin zenginliğini keşfetme.

Döndürülen verileri Sırala

Aşağıdaki kod, metin alanına göre artan sıralanmış bir todoıtems tablosundan tüm öğeleri döndürür. mToDoTable , daha önce oluşturduğunuz arka uç tablosuna yapılan başvurudur:

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

OrderBy yönteminin ilk parametresi, sıralanacak alanın adına eşit bir dizedir. İkinci parametre QueryOrder sabit listesini kullanarak artan veya azalan sıralama yapılıp yapılmayacağını belirtir. WHERE yöntemini kullanarak filtrelerken, OrderBy yönteminden önce WHERE yöntemi çağrılması gerekir.

Belirli sütunları seç

Aşağıdaki kod, birtodoıtemstablosundan tüm öğelerin nasıl döndürüldiğini gösterir, ancak yalnızca tüm ve metin alanlarını görüntüler. mToDoTable , daha önce oluşturduğumuz arka uç tablosuna yapılan başvurudur.

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

Select işlevine yönelik parametreler, döndürmek istediğiniz tablo sütunlarının dize adlarıdır. Select yönteminin WHERE ve OrderBygibi yöntemleri izlemesi gerekir. Bu, Skip ve topgibi sayfalama yöntemleri tarafından izlenebilir.

Sayfalarda verileri döndürme

Veriler her zaman sayfalarda döndürülür. Döndürülen en fazla kayıt sayısı sunucu tarafından ayarlanır. İstemci daha fazla kayıt isterse, sunucu en fazla kayıt sayısını döndürür. Varsayılan olarak, sunucudaki en büyük sayfa boyutu 50 kayıtlardır.

İlk örnek, bir tablodan en üstteki beş öğenin nasıl görüntüleneceğini gösterir. Sorgu, öğeleri bir todoıtemstablosundan döndürür. mToDoTable , daha önce oluşturduğunuz arka uç tablosuna yapılan başvurudur:

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

İlk beş öğeyi atlayan bir sorgu, sonra da sonraki beş öğeyi döndürür:

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

Bir tablodaki tüm kayıtları almak isterseniz, tüm sayfalar üzerinde yinelemek için kodu uygulayın:

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);

Bu yöntemi kullanan tüm kayıtlar için bir istek, Mobile Apps arka uca en az iki istek oluşturur.

İpucu

Doğru sayfa boyutunu seçme, istek gerçekleştiği sırada bellek kullanımı, bant genişliği kullanımı ve verileri tamamen alma gecikmesi arasındaki bir dengedir. Varsayılan (50 kayıt) tüm cihazlar için uygundur. Daha büyük bellek cihazlarında özel olarak çalışıyorsanız, 500 'e kadar artırın. Sayfa boyutunu 500 kaydın ötesine artırmanın kabul edilemez gecikmelere ve büyük bellek sorunlarına neden olduğunu bulduk.

Nasıl yapılır: sorgu yöntemlerini birleştirme

Arka uç tablolarını sorgulamak için kullanılan yöntemler birleştirilebilir. Sorgu yöntemleri zincirleme, sıralanmış ve disk belleğine alınmış filtrelenmiş satırlardaki belirli sütunları seçmenizi sağlar. Karmaşık mantıksal filtreler oluşturabilirsiniz. Her sorgu yöntemi bir sorgu nesnesi döndürür. Yöntem dizisini sonlandırmak ve sorguyu çalıştırmak için Execute metodunu çağırın. Örnek:

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();

Zincirleme sorgu yöntemleri aşağıdaki gibi sıralanmalıdır:

  1. Filtreleme (WHERE) yöntemleri.
  2. Sıralama (OrderBy) yöntemleri.
  3. Seçim (Select) yöntemleri.
  4. sayfalama (atlama ve üst) yöntemleri.

Verileri Kullanıcı arabirimine bağlama

Veri bağlama üç bileşenden oluşur:

  • Veri kaynağı
  • Ekran düzeni
  • İkisini birlikte birbirine bağlayan bağdaştırıcı.

örnek kodumuzda, verileri bir diziye Mobile Apps SQL Azure tablo todoıtem geri döndürüyoruz. Bu etkinlik, veri uygulamaları için ortak bir modeldir. Veritabanı sorguları genellikle istemcinin bir liste veya dizide aldığı bir satır koleksiyonu döndürür. Bu örnekte, dizi veri kaynağıdır. Kod, cihazda görüntülenen verilerin görünümünü tanımlayan bir ekran düzeni belirtir. İkisi bir bağdaştırıcı ile birbirine bağlanır, bu kodda Arrayadapter < TodoItem > sınıfının bir uzantısıdır.

Düzeni tanımlama

Düzen, XML kodunun çeşitli parçacıkları tarafından tanımlanır. Var olan bir düzen verildiğinde, aşağıdaki kod sunucu verilerimizden doldurmak istediğimiz ListView 'u temsil eder.

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

Yukarıdaki kodda, ListItem özniteliği listedeki tek bir satır için düzenin kimliğini belirtir. Bu kod, bir onay kutusunu ve ilişkili metnini belirtir ve listedeki her öğe için bir kez oluşturulur. Bu düzen ID alanını göstermez ve daha karmaşık bir düzen, ekranda ek alanlar belirtmektir. Bu kod row_list_to_do.xml dosyasıdır.

<?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>

Bağdaştırıcıyı tanımlama

Görünümümüzde bulunan veri kaynağı bir TodoItemdizisi olduğundan, Bağdaştırıcımızı arrayadapter < TodoItem > sınıfından alt sınıflıyoruz. Bu alt sınıf row_list_to_do düzeni kullanarak her TodoItem için bir görünüm üretir. Kodunuzda Arrayadapter < E > sınıfının bir uzantısı olan aşağıdaki sınıfı tanımlayacağız:

public class ToDoItemAdapter extends ArrayAdapter<ToDoItem> {
}

Bağdaştırıcıları GetView metodunu geçersiz kılın. Örnek:

    @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;
    }

Etkinlikimizde bu sınıfın bir örneğini aşağıda gösterildiği gibi oluşturacağız:

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

ToDoItemAdapter oluşturucusunun ikinci parametresi, düzene yönelik bir başvurudur. Artık ListView 'u örneklendiriyoruz ve bu bağdaştırıcıyı ListViewöğesine atayabiliriz.

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

Kullanıcı arabirimine bağlamak için bağdaştırıcıyı kullanın

Artık veri bağlamayı kullanmaya hazırsınız. Aşağıdaki kod, tablodaki öğelerin nasıl alınacağını ve yerel bağdaştırıcıyı döndürülen öğelerle nasıl doldurduğunu gösterir.

    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);
    }

TodoItem tablosunu her değiştirdiğiniz zaman bağdaştırıcıyı çağırın. Değişiklikler kayıt temelinde kayıt üzerinde yapıldığından, bir koleksiyon yerine tek bir satır işleyebilirsiniz. Bir öğe eklediğinizde, bağdaştırıcıdaki Add metodunu çağırın; silme sırasında Remove metodunu çağırın.

Android hızlı başlangıç Projectbir örnek bulabilirsiniz.

Arka uca veri ekleme

TodoItem sınıfının bir örneğini oluşturun ve özelliklerini ayarlayın.

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

Sonra Insert () kullanarak bir nesne ekleyin:

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

Döndürülen varlık, arka uç tablosuna eklenen verilerle eşleşir, KIMLIĞI ve arka uçta ayarlanan diğer tüm değerleri (örneğin createdAtupdatedAt ,, ve version alanları) içerir.

Mobile Apps tabloları, IDadlı bir birincil anahtar sütunu gerektirir. Bu sütun bir dize olmalıdır. KIMLIK sütununun varsayılan değeri bir GUID 'dir. E-posta adresleri veya Kullanıcı adları gibi diğer benzersiz değerler de sağlayabilirsiniz. Ekli bir kayıt için bir dize KIMLIĞI değeri sağlanmazsa, arka uç yeni bir GUID oluşturur.

Dize KIMLIĞI değerleri aşağıdaki avantajları sağlar:

  • Kimlikler, veritabanına gidiş dönüş yapılmadan oluşturulabilir.
  • Kayıtlar farklı tablolardan veya veritabanlarından birleştirmek daha kolaydır.
  • KIMLIK değerleri bir uygulamanın mantığı ile daha iyi tümleşir.

Çevrimdışı eşitleme desteği için dize KIMLIĞI değerleri gereklidir . Bir kimliği, arka uç veritabanında depolandıktan sonra değiştiremezsiniz.

Mobil uygulamadaki verileri güncelleştirme

Bir tablodaki verileri güncelleştirmek için yeni nesneyi Update () metoduna geçirin.

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

Bu örnekte, öğe , üzerinde yapılan bazı değişiklikler içeren TodoItem tablosundaki bir satıra başvurudur. Aynı kimliğe sahip satır güncelleştirildi.

Mobil uygulamadaki verileri silme

Aşağıdaki kod, veri nesnesini belirterek tablodaki verilerin nasıl silineceğini gösterir.

mToDoTable
    .delete(item);

Ayrıca, silinecek satırın ID alanını belirterek bir öğeyi silebilirsiniz.

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

Kimliğe göre belirli bir öğe ara

LookUp () yöntemiyle belirli bir ID alanı olan bir öğe arar:

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

Nasıl yapılır: türsüz verilerle çalışma

Türsüz programlama modeli, JSON serileştirme üzerinde tam denetim sağlar. Türsüz bir programlama modeli kullanmak isteyebileceğiniz bazı yaygın senaryolar vardır. Örneğin, arka uç tablonuz çok sayıda sütun içeriyorsa ve yalnızca sütunların bir alt kümesine başvurulmasına ihtiyaç duyuyorsanız. Türü belirtilmiş model, veri sınıfınıza Mobile Apps arka uçta tanımlanan tüm sütunları tanımlamanızı gerektirir. Verilere erişmek için API çağrılarının çoğu, yazılan programlama çağrılarına benzerdir. Asıl fark, türü belirsiz bir modelde Mobileservicetable nesnesi yerine mobileservicejsontable nesnesinde çağırmamanızdır.

Türsüz bir tablonun örneğini oluşturma

Yazılı modele benzer şekilde, bir tablo başvurusu alarak başlar, ancak bu durumda bir Mobileservicesjsontable nesnesidir. İstemcinin bir örneğinde GetTable metodunu çağırarak başvuruyu edinin:

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

Mobileservicejsontable'ın bir örneğini oluşturduktan sonra, bu, türü belirlenmiş programlama MODELIYLE aynı API 'ye sahiptir. Bazı durumlarda, yöntemler türü belirlenmiş bir parametre yerine türsüz bir parametre alır.

Türsüz tabloya ekle

Aşağıdaki kod, bir eklemenin nasıl yapılacağını gösterir. İlk adım, gson kitaplığının bir parçası olan bir JsonObjectoluşturmaktır.

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

Ardından, tabloya türsüz nesneyi eklemek için Insert () kullanın.

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

Eklenecek nesnenin KIMLIĞINI almanız gerekiyorsa, Getasjsonilkel () yöntemini kullanın.

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

Türsüz bir tablodan Sil

Aşağıdaki kod, önceki Insert örneğinde oluşturulmuş bir JsonObject örneği olan bu örnekte bir örneğin nasıl silineceğini gösterir. Kod, yazılan durum ile aynıdır, ancak bir JsonObjectöğesine başvurduğundan yöntemin farklı bir imzası vardır.

mToDoTable
    .delete(insertedItem);

Ayrıca, KIMLIĞINI kullanarak doğrudan bir örneği silebilirsiniz:

mToDoTable.delete(ID);

Türsüz bir tablodan tüm satırları döndür

Aşağıdaki kod, tüm bir tablonun nasıl alınacağını gösterir. JSON tablosu kullandığınızdan, tablonun sütunlarından yalnızca birini seçerek alabilirsiniz.

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();
}

Türsüz model için kullanılabilen aynı filtreleme, filtreleme ve sayfalama yöntemleri kümesi vardır.

Çevrimdışı eşitleme Uygula

Azure Mobile Apps Istemci SDK 'Sı, sunucu verilerinin bir kopyasını yerel olarak depolamak için bir SQLite veritabanı kullanarak verilerin çevrimdışı eşitlemesini da uygular. Çevrimdışı bir tabloda gerçekleştirilen işlemler, mobil bağlantının çalışmasını gerektirmez. Çevrimdışı eşitleme, çakışma çözümüne yönelik daha karmaşık mantık masrafına esnekliği ve performans konusunda yardımcı olur. Azure Mobile Apps Istemci SDK 'Sı aşağıdaki özellikleri uygular:

  • Artımlı eşitleme: yalnızca güncelleştirilmiş ve yeni kayıtlar indirilir, bant genişliği ve bellek tüketimi kaydedilir.
  • İyimser eşzamanlılık: Işlemlerin başarılı olduğu varsayılır. Sunucu üzerinde güncelleştirmeler gerçekleştirilene kadar çakışma çözümü ertelenir.
  • Çakışma çözümü: SDK, sunucuda çakışan bir değişikliğin ne zaman yapıldığını algılar ve kullanıcıyı uyarmak için kancalar sağlar.
  • Geçici silme: silinen kayıtlar silinmiş olarak işaretlenir ve diğer cihazların çevrimdışı önbelleklerini güncelleştirmesine izin verilir.

Çevrimdışı Eşitlemeyi Başlat

Her çevrimdışı tablonun kullanılmadan önce çevrimdışı önbellekte tanımlanması gerekir. Normalde, tablo tanımı istemci oluşturulduktan hemen sonra yapılır:

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);
}

Çevrimdışı önbellek tablosuna bir başvuru alın

Çevrimiçi bir tablo için kullanırsınız .getTable() . Çevrimdışı bir tablo için şunu kullanın .getSyncTable() :

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

Çevrimiçi tablolarda (filtreleme, sıralama, sayfalama, veri ekleme, verileri güncelleştirme ve verileri silme dahil) tüm yöntemler, çevrimiçi ve çevrimdışı tablolar üzerinde de aynı şekilde çalışır.

Yerel çevrimdışı önbelleği eşitler

Eşitleme, uygulamanızın denetimi içindedir. Örnek bir eşitleme yöntemi aşağıda verilmiştir:

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);
}

Yöntemine bir sorgu adı sağlanmışsa .pull(query, queryname) , yalnızca son başarılı çekme tamamlandıktan sonra oluşturulmuş veya değiştirilmiş kayıtları döndürmek için artımlı eşitleme kullanılır.

Çevrimdışı eşitleme sırasında çakışmaları işle

Bir işlem sırasında .push() çakışma oluşursa, bir MobileServiceConflictException oluşturulur. Sunucu tarafından verilen öğe özel duruma katıştırılır ve özel durum üzerinde tarafından .getItem() alınabilir. Aşağıdaki öğeleri MobileServiceSyncContext nesnesinde çağırarak gönderimi ayarlayın:

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

Tüm çakışmalar istediğiniz gibi işaretlendiğinde, tüm çakışmaları çözümlemek için yeniden çağırın .push() .

Özel API çağırma

Özel bir API, bir INSERT, Update, DELETE veya Read işlemiyle eşleşmeyen sunucu işlevlerini açığa çıkaran özel uç noktalar tanımlamanızı sağlar. Özel bir API kullanarak ileti üzerinde daha fazla denetime sahip olabilirsiniz ve HTTP ileti üst bilgilerini okumak ve ayarlamak ve JSON dışında bir ileti gövdesi biçimi tanımlamak dahil olabilirsiniz.

Android istemcisinden, özel API uç noktasını çağırmak için ınvokeapı metodunu çağırabilirsiniz. Aşağıdaki örnek, Markallresultadlı bir koleksiyon sınıfı döndüren COMPLETEALLadlı bir API uç noktasının nasıl çağrılacağını gösterir.

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();
        }
    });
}

Invokeapı yöntemi, istemci üzerinde çağrılır, bu da yenı özel API 'ye bir post isteği gönderir. Özel API tarafından döndürülen sonuç, herhangi bir hata gibi bir ileti iletişim kutusunda görüntülenir. Invokeapı 'nin diğer sürümleri isteğe bağlı olarak istek gövdesinde bir nesne GÖNDERMENIZI, http yöntemini belirtmenizi ve istekle birlikte sorgu parametreleri göndermenizi sağlar. Invokeapı 'nin türsüz sürümleri de sağlanmaktadır.

Uygulamanıza kimlik doğrulaması ekleme

Öğreticiler, bu özelliklerin nasıl ekleneceğini ayrıntılı olarak anlatmaktadır.

App Service, farklı dış kimlik sağlayıcıları kullanarak uygulama kullanıcılarının kimlik doğrulamasını destekler: Facebook, Google, Microsoft hesabı, Twitter ve Azure Active Directory. Belirli işlemlere erişimi yalnızca kimliği doğrulanmış kullanıcılarla kısıtlamak için tablolar üzerinde izinler belirleyebilirsiniz. Ayrıca, arka ucunuzdaki yetkilendirme kurallarını uygulamak için kimliği doğrulanmış kullanıcıların kimliğini de kullanabilirsiniz.

İki kimlik doğrulama akışı desteklenir: sunucu akışı ve istemci akışı. Sunucu akışı, kimlik sağlayıcıları web arabirimine dayandığı için en basit kimlik doğrulama deneyimini sağlar. Sunucu akışı kimlik doğrulamasını uygulamak için ek SDK gerekli değildir. Sunucu akışı kimlik doğrulaması, mobil cihaza derin bir tümleştirme sağlamaz ve yalnızca kavram kanıtı senaryoları için önerilir.

İstemci akışı, kimlik sağlayıcısı tarafından belirtilen SDK 'Ları temel aldığından, çoklu oturum açma gibi cihaza özgü yetenekler ile daha derin tümleştirme sağlar. Örneğin, Facebook SDK 'sını Mobil uygulamanızla tümleştirebilirsiniz. Mobil istemci Facebook uygulamasında takas eder ve mobil uygulamanıza geri dönerek oturum açma bilgilerinizi onaylar.

Uygulamanızda kimlik doğrulamasını etkinleştirmek için dört adım gereklidir:

  • Bir kimlik sağlayıcısıyla kimlik doğrulaması için uygulamanızı kaydedin.
  • App Service arka ucunuzu yapılandırın.
  • tablo izinlerini yalnızca App Service arka uçta kimliği doğrulanmış kullanıcılarla kısıtlayın.
  • Uygulamanıza kimlik doğrulama kodu ekleyin.

Belirli işlemlere erişimi yalnızca kimliği doğrulanmış kullanıcılarla kısıtlamak için tablolar üzerinde izinler belirleyebilirsiniz. İstekleri değiştirmek için kimliği doğrulanmış bir kullanıcının SID 'sini de kullanabilirsiniz. daha fazla bilgi için kimlik doğrulaması ve sunucu SDK 'sı ile ilgili Kullanmaya başlayın gözden geçirin.

Kimlik doğrulaması: sunucu Flow

Aşağıdaki kod, Google sağlayıcısını kullanarak bir sunucu akışı oturum açma işlemi başlatır. Google sağlayıcısı için güvenlik gereksinimleri nedeniyle ek yapılandırma gereklidir:

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

Ayrıca, ana etkinlik sınıfına aşağıdaki yöntemi ekleyin:

// 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");
            }
        }
    }
}

GOOGLE_LOGIN_REQUEST_CODEAna etkinliğinizdeki tanımlı yöntem, login() yöntemi ve onActivityResult() yöntemi için kullanılır. Yöntemi ve onActivityResult() yöntemi içinde login() aynı sayı kullanıldığı sürece herhangi bir benzersiz sayı seçebilirsiniz. İstemci kodunu bir hizmet bağdaştırıcısına (daha önce gösterildiği gibi) soyutlamak isterseniz, hizmet bağdaştırıcısında uygun yöntemleri çağırmanız gerekir.

Ayrıca, projesini customtab için de yapılandırmanız gerekir. İlk olarak bir Redirect-URL belirtin. Aşağıdaki kod parçacığını AndroidManifest.xml ekleyin:

<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>

Uygulamanız için dosyaya Redirecturischemebuild.gradle ekleyin:

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

Son olarak, dosyadaki bağımlılıklar listesine build.gradle ekleyin com.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'
}

GetUserID metodunu kullanarak, bir mobileserviceuser 'DAN oturum açmış kullanıcının kimliğini edinin. zaman uyumsuz oturum açma apı 'lerini çağırmak için Futures 'ın nasıl kullanılacağına ilişkin bir örnek için, bkz. kimlik doğrulaması ile Kullanmaya başlayın.

Uyarı

Bahsedilen URL şeması, büyük/küçük harfe duyarlıdır. Tüm eşleşme durumunun geçtiği tüm oluşumların {url_scheme_of_you_app} olduğundan emin olun.

Önbellek kimlik doğrulaması belirteçleri

Önbelleğe Alma kimlik doğrulama belirteçleri, kullanıcı kimliğini ve kimlik doğrulama belirtecini cihazda yerel olarak depolamanızı gerektirir. Uygulamanın bir sonraki açılışında önbelleği kontrol edersiniz ve bu değerler varsa, oturum açma yordamını atlayabilir ve istemciyi bu verilerle yeniden girebilirsiniz. Ancak bu veriler duyarlıdır ve telefonun çalınması durumunda güvenlik için şifrelenmiş olarak depolanması gerekir. Önbellek kimlik doğrulaması belirteçleri bölümündekimlik doğrulama belirteçlerinin nasıl önbelleğe alınacağını gösteren bir örnek görürsünüz.

Kullanım dışı bir belirteci kullanmaya çalıştığınızda, 401 Yetkisiz bir yanıt alırsınız. Filtreleri kullanarak kimlik doğrulama hatalarını işleyebilirsiniz. filtreler App Service arka uca istekleri durdurur. Filtre kodu bir 401 için yanıtı sınar, oturum açma işlemini tetikler ve ardından 401 ' yi oluşturan isteği sürdürür.

Yenileme belirteçlerini kullan

Azure App Service kimlik doğrulaması ve yetkilendirme tarafından döndürülen belirtecin bir saat tanımlı bir yaşam süresi vardır. Bu dönemden sonra, kullanıcıyı yeniden kimlik doğrulaması yapmanız gerekir. istemci akışı kimlik doğrulaması aracılığıyla aldığınız uzun süreli bir belirteç kullanıyorsanız, aynı belirteci kullanarak Azure App Service kimlik doğrulaması ve yetkilendirmeyle yeniden kimlik doğrulama yapabilirsiniz. başka bir Azure App Service belirteci yeni bir yaşam süresi ile oluşturulur.

Ayrıca, sağlayıcıyı yenileme belirteçleri kullanacak şekilde kaydedebilirsiniz. Yenileme belirteci her zaman kullanılabilir değildir. Ek yapılandırma gereklidir:

  • Azure Active Directoryiçin Azure Active Directory uygulaması için bir istemci gizli anahtarı yapılandırın. Azure Active Directory kimlik doğrulamasını yapılandırırken Azure App Service istemci parolasını belirtin. Çağrılırken .login() parametre olarak geçirin response_type=code id_token :

    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);
    
  • Googleiçin bir parametre olarak geçirin access_type=offline :

    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);
    
  • Microsoft hesabıiçin kapsamı seçin wl.offline_access .

Bir belirteci yenilemek için şunu çağırın .refreshUser() :

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

En iyi uygulama olarak, sunucudan 401 yanıtını algılayan ve kullanıcı belirtecini yenilemeye çalışan bir filtre oluşturun.

Istemci akışı kimlik doğrulamasıyla oturum açın

İstemci akışı kimlik doğrulamasıyla oturum açmak için genel süreç aşağıdaki gibidir:

  • sunucu flow kimlik doğrulamasında Azure App Service kimlik doğrulaması ve yetkilendirme yapılandırın.

  • Erişim belirteci üretmek için kimlik doğrulama sağlayıcısı SDK 'sını kimlik doğrulama için tümleştirin.

  • .login()Yöntemini aşağıdaki gibi çağırın ( result bir AuthenticationResult olmalıdır):

    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");
        }
    });
    

Sonraki bölümde tüm kod örneğine bakın.

onSuccess()Yöntemini başarılı bir oturum açma işlemi üzerinde kullanmak istediğiniz kod ile değiştirin. {provider}dize geçerli bir sağlayıcıdır: aad (Azure Active Directory), facebook, google, microsoftaccountveya twitter. Özel kimlik doğrulaması uyguladıysanız, özel kimlik doğrulama sağlayıcısı etiketini de kullanabilirsiniz.

Active Directory Authentication Library (ADAL) ile kullanıcıların kimliğini doğrulama

Azure Active Directory kullanarak uygulamanızdaki kullanıcıları imzalamak için Active Directory Authentication Library (ADAL) kullanabilirsiniz. Daha yerel bir UX sunan ve ek özelleştirmeye izin verdiği için, loginAsync() istemci akışı oturum açmanın kullanılması genellikle yöntemlerin kullanılması tercih edilir.

  1. mobil uygulama arka ucunuzu AAD oturum açma için App Service yapılandırma Active Directory oturum açma öğreticisini izleyerek yapılandırın. Yerel istemci uygulamasını kaydetme işleminin isteğe bağlı adımını tamamladığınızdan emin olun.

  2. Build. Gradle dosyanızı aşağıdaki tanımları içerecek şekilde değiştirerek ADAL 'yi oluşturun:

    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. Aşağıdaki kodu uygulamanıza ekleyin ve aşağıdaki değişiklikleri yapın:

    • Eklentiyi, uygulamanızı sağladığınız kiracının adıyla değiştirin. Biçim olmalıdır https://login.microsoftonline.com/contoso.onmicrosoft.com .
    • Insert-Resource-ID-burada , mobil uygulama arka ucunuzun istemci kimliği ile değiştirin. istemci kimliğini portalda Azure Active Directory Ayarlar altında bulunan gelişmiş sekmesinden elde edebilirsiniz.
    • Ekle-ISTEMCI kimliği- ' ni yerel istemci uygulamasından KOPYALADıĞıNıZ istemci kimliğiyle değiştirin.
    • {1 & gt; Insert-REDIRECT-URI & lt; 1} ÖĞESINI, https şemasını kullanarak sitenizin /.Auth/login/done uç noktasıyla değiştirin Bu değer değerine benzer https://contoso.azurewebsites.net/.auth/login/done olmalıdır.
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);
    }
}

Client-Server Iletişimini ayarlama

Istemci bağlantısı normalde Android SDK ile sağlanan temel HTTP kitaplığını kullanan temel bir HTTP bağlantısıdır. Bunu değiştirmek istemenizin birkaç nedeni vardır:

  • Zaman aşımlarını ayarlamak için alternatif bir HTTP kitaplığı kullanmak istiyorsunuz.
  • Bir ilerleme çubuğu sağlamak istiyorsunuz.
  • API Management işlevselliğini desteklemek için özel bir üst bilgi eklemek istiyorsunuz.
  • Yeniden kimlik doğrulamayı uygulayabilmeniz için, başarısız bir yanıtı kesmeye devam etmek istiyorsunuz.
  • Arka uç isteklerini bir analiz hizmetine kaydetmek istiyorsunuz.

Alternatif bir HTTP Kitaplığı kullanma

.setAndroidHttpClientFactory()İstemci başvurunuz oluşturduktan hemen sonra yöntemi çağırın. Örneğin, bağlantı zaman aşımını 60 saniye olarak ayarlamak için (varsayılan 10 saniye yerine):

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;
    }
});

Ilerleme filtresi uygulama

Bir uygulayarak her istek için bir ServiceFilter kesme uygulayabilirsiniz. Örneğin, aşağıdaki bir önceden oluşturulmuş ilerleme çubuğunu güncelleştirir:

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;
    }
}

Bu filtreyi istemciye aşağıdaki şekilde ekleyebilirsiniz:

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

Istek üstbilgilerini özelleştirme

Aşağıdakileri ServiceFilter kullanın ve filtresi ile aynı şekilde ProgressFilter ekleyin:

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);
        }
    }
}

Otomatik serileştirme yapılandırma

Gson API kullanarak her sütun için geçerli olan bir dönüştürme stratejisi belirtebilirsiniz. Android istemci kitaplığı, veriler Azure App Service gönderilmeden önce Java nesnelerini JSON verilerine seri hale getirmek için arka planda gson 'yı kullanır. Aşağıdaki kod, stratejiyi ayarlamak için Setfieldnamingstrateji () yöntemini kullanır. Bu örnek, ilk karakteri (bir "a") silecek ve sonra her alan adı için bir sonraki karakteri küçük harfe düşüracaktır. Örneğin, "PARÇAAL" öğesini "ID" olarak etkinleştirebilir. Birçok alana ek açıklama gereksinimini SerializedName() azaltmak için bir dönüştürme stratejisi uygulayın.

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)
);

Bu kod, MobileServiceClientkullanarak bir mobil istemci başvurusu oluşturmadan önce yürütülmelidir.