Android için Azure Mobile Apps SDK'sını kullanma
Bu kılavuz, aşağıdakiler gibi yaygın senaryoları uygulamak üzere Mobile Apps için Android istemci SDK'sını nasıl kullanacağınızı gösterir:
- Veri sorgulama (ekleme, güncelleştirme ve silme).
- Kimlik Doğrulaması.
- Hataları işleme.
- İstemciyi özelleştirme.
Bu kılavuz, istemci tarafı Android SDK'sı üzerinde durmaktadır. 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 arka uç SDK'sını kullanma.
Başvuru Belgeleri
GitHub'da Android istemci kitaplığı için Javadocs API başvurusunu bulabilirsiniz.
Desteklenen Platformlar
Android için Azure Mobile Apps SDK'sı, telefon ve tablet form faktörleri için 19 ile 24 (KitKat ile Nougat arasında) API düzeylerini destekler. Kimlik doğrulaması, özellikle kimlik bilgilerini toplamak için ortak bir web çerçevesi yaklaşımı kullanır. Sunucu akışı kimlik doğrulaması, saat gibi küçük form faktörü cihazlarıyla çalışmaz.
Kurulum ve Önkoşullar
Mobile Apps hızlı başlangıç öğreticisini tamamlayın. Bu görev, Azure Mobile Apps geliştirmeye yönelik tüm önkoşulların karşılanmasını sağlar. Hızlı Başlangıç, hesabınızı yapılandırmanıza ve ilk Mobil Uygulama arka ucunuzu oluşturmanıza da yardımcı olur.
Hızlı Başlangıç öğreticisini tamamlamamaya karar verirseniz aşağıdaki görevleri tamamlayın:
- Android uygulamanızla kullanmak için bir Mobil Uygulama arka ucu oluşturun.
- Android Studio'da Gradle derleme dosyalarını güncelleştirin.
- İnternet iznini etkinleştirin.
Gradle derleme dosyasını güncelleştirme
Her iki build.gradle dosyasını da değiştirin:
Bu kodu Project level build.gradle dosyasına ekleyin:
buildscript { repositories { jcenter() google() } } allprojects { repositories { jcenter() google() } }
Bu kodu dependencies etiketinin içindeki Module 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'da listelenir.
İnternet iznini etkinleştirme
Azure'a erişmek için uygulamanızın İnternet izni etkinleştirilmiş olmalıdır. Henüz etkinleştirilmemişse, AndroidManifest.xml dosyanıza aşağıdaki kod satırını 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 Sunucu SDK'sı ile yazılmış Özel API'leri çağırın.
- Azure Uygulaması Hizmet Kimlik Doğrulaması ve Yetkilendirme ile kimlik doğrulaması.
- Notification Hubs ile Anında İletme Bildirimi Kaydı.
Bu işlevlerin her biri önce bir MobileServiceClient
nesne oluşturmanızı gerektirir. Mobil istemcinizde yalnızca bir MobileServiceClient
nesne oluşturulmalıdır (yani Tekil desen olmalıdır). Nesne oluşturmak MobileServiceClient
için:
MobileServiceClient mClient = new MobileServiceClient(
"<MobileAppUrl>", // Replace with the Site URL
this); // Your application Context
<MobileAppUrl>
, mobil arka ucunuzu işaret eden bir dize veya URL nesnesidir. Mobil arka ucunuzu barındırmak için Azure Uygulaması Hizmeti kullanıyorsanız URL'nin güvenli https://
sürümünü kullandığınızdan emin olun.
İstemci ayrıca örnekteki parametre olan Etkinlik veya Bağlam'a this
da erişim gerektirir. MobileServiceClient yapısı, dosyasında başvurulan Etkinliğin yöntemi içinde onCreate()
AndroidManifest.xml
gerçekleşmelidir.
En iyi yöntem olarak, sunucu iletişimini kendi (tekil desen) sınıfına soyutlamanız gerekir. Bu durumda, hizmeti uygun şekilde yapılandırmak için Oluşturucu içinde Etkinliği geçirmeniz gerekir. Örneğin:
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 yöntemini çağırabilirsiniz AzureServiceAdapter.Initialize(this);
onCreate()
. İstemciye erişmesi gereken diğer yöntemler, hizmet bağdaştırıcısına başvuru almak için kullanır AzureServiceAdapter.getInstance();
.
Veri İşlemleri
Azure Mobile Apps SDK'sının temeli, Mobil Uygulama arka uçta SQL Azure'da depolanan verilere erişim sağlamaktır. Kesin olarak yazılmış sınıflar (tercih edilen) veya yazılmamış sorgular (önerilmez) kullanarak bu verilere erişebilirsiniz. Bu bölümün büyük bölümü, kesin olarak yazılan sınıfların kullanılmasıyla ilgilidir.
İstemci veri sınıflarını tanımlama
SQL Azure tablolarındaki verilere erişmek için Mobil Uygulama arka uçtaki tablolara karşılık gelen istemci veri sınıflarını tanımlayın. Bu konudaki örneklerde, aşağıdaki sütunları içeren MyDataTable adlı bir tablo olduğu varsayılır:
- id
- text
- tamamlandı
Karşılık gelen yazılan istemci tarafı nesnesi MyDataTable.java adlı bir dosyada bulunur:
public class ToDoItem {
private String id;
private String text;
private Boolean complete;
}
Eklediğiniz her alan için alıcı ve ayarlayıcı yöntemleri ekleyin. SQL Azure tablonuz daha fazla sütun içeriyorsa, ilgili alanları bu sınıfa eklersiniz. Örneğin, DTO'da (veri aktarımı nesnesi) tamsayı Öncelik sütunu varsa, bu alanı, alıcı ve ayarlayıcı yöntemleriyle birlikte ekleyebilirsiniz:
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 ucunuzda ek tablolar oluşturmayı öğrenmek için bkz . Nasıl yapılır: Tablo denetleyicisi tanımlama (.NET arka ucu) veya Dinamik Şema Kullanarak Tablo Tanımlama (Node.js arka uç).
Azure Mobile Apps arka uç tablosu, dört tane istemci tarafından kullanılabilen beş özel alanı tanımlar:
String id
: Kaydın genel benzersiz kimliği. En iyi yöntem olarak, id değerini bir UUID nesnesinin Dize gösterimi yapın.DateTimeOffset updatedAt
: Son güncelleştirmenin tarihi/saati. updatedAt alanı sunucu tarafından ayarlanır ve hiçbir zaman istemci kodunuz tarafından ayarlanmamalıdır.DateTimeOffset createdAt
: Nesnenin oluşturulduğu tarih/saat. createdAt alanı sunucu tarafından ayarlanır ve hiçbir zaman istemci kodunuz tarafından ayarlanmamalıdır.byte[] version
: Normalde bir dize olarak temsil edilir, sürüm sunucu tarafından da ayarlanır.boolean deleted
: Kaydın silindiğini ancak henüz temizlenmediğini gösterir. Sınıfınızda özellik olarak kullanmayındeleted
.
id
alanı gereklidir. Alan updatedAt
ve version
alan çevrimdışı eşitleme için kullanılır (sırasıyla artımlı eşitleme ve çakışma çözümü için). Bu createdAt
alan bir başvuru alanıdır ve istemci tarafından kullanılmaz. Adlar özelliklerin "kablo boyunca" adlarıdır ve ayarlanmaz. Bununla birlikte, gson kitaplığını kullanarak nesnenizle "kablo arasında" adları arasında bir eşleme oluşturabilirsiniz. Örneğin:
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
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ıyla tablo adının aynı olduğu ve Hızlı Başlangıçta kullanılan aşırı yüklemedir:
MobileServiceTable<ToDoItem> mToDoTable = mClient.getTable(ToDoItem.class);
İkinci aşırı yükleme, tablo adı sınıf adından farklı olduğunda kullanılır: ilk parametre tablo adıdır.
MobileServiceTable<ToDoItem> mToDoTable = mClient.getTable("ToDoItemBackup", ToDoItem.class);
Arka Uç Tablosunu Sorgulama
İlk olarak bir tablo başvurusu alın. Ardından tablo başvurusunda bir sorgu yürütür. Sorgu, şu bileşimlerden herhangi biridir:
- Filter
.where()
yan tümcesi. - Ordering
.orderBy()
yan tümcesi. - Alan
.select()
seçimi yan tümcesi. - A
.skip()
ve.top()
sayfalanmış sonuçlar için.
Yan tümceler önceki sırada sunulmalıdır.
Sonuçları Filtreleme
Sorgunun genel biçimi:
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 ayarlanan sayfa boyutu üst sınırına kadar). .execute()
yöntemi sorguyu arka uçta yürütür. Sorgu, Mobile Apps arka ucuna iletim öncesinde bir OData v3 sorgusuna dönüştürülür. Alındıktan sonra Mobile Apps arka ucu sorguyu SQL Azure örneğinde yürütmeden önce bir SQL deyimine dönüştürür. Ağ etkinliği biraz zaman aldığından .execute()
, yöntemi bir ListenableFuture<E>
döndürür.
Döndürülen verileri filtreleme
Aşağıdaki sorgu yürütme, ToDoItem tablosundaki tüm öğeleri döndürür ve burada tamamlandı değeri false'a eşittir.
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 alan yöntemi ve ardından mantıksal koşulu belirten bir yöntem eklenir. Olası koşul yöntemleri arasında eq (eşittir), ne (eşit değil), 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ıza olanak sağlar.
Tarihlere göre filtreleyebilirsiniz. Aşağıdaki yöntemler tarih alanının tamamını veya tarihin bölümlerini karşılaştırmanıza olanak tanır: yıl, ay, gün, saat, dakika ve 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, trim ve length. Aşağıdaki örnek, metin sütununun "PRI0" ile başladığı tablo satırları için filtreler.
List<ToDoItem> results = mToDoTable
.where()
.startsWith("text", "PRI0")
.execute()
.get();
Sayı alanlarında aşağıdaki işleç yöntemleri desteklenir: add, sub, mul, div, mod, floor, ceiling ve round. Aşağıdaki örnek, sürenin çift sayı olduğu tablo satırları için filtreler.
List<ToDoItem> results = mToDoTable
.where()
.field("duration").mod(2).eq(0)
.execute()
.get();
Koşulları şu mantıksal yöntemlerle birleştirebilirsiniz: ve veya değil. Aşağıdaki örnek, önceki örneklerden ikisini birleştirir.
List<ToDoItem> results = mToDoTable
.where()
.year("due").eq(2013).and().startsWith("text", "PRI0")
.execute()
.get();
Mantıksal işleçleri gruplandırma ve iç içe yerleştirme:
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ışma ve filtreleme örnekleri için bkz . Android istemci sorgu modelinin zenginliğini keşfetme.
Döndürülen verileri sıralama
Aşağıdaki kod, ToDoItems tablosundaki tüm öğeleri metin alanına göre artan düzende sıralanmış olarak döndürür. mToDoTable , daha önce oluşturduğunuz arka uç tablosuna 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, artan veya azalan sıralamanın yapılıp yapılmayacağını belirtmek için QueryOrder numaralandırmasını kullanır. where yöntemini kullanarak filtreleme gerçekleştiriyorsanız where yöntemi orderBy yönteminden önce çağrılmalıdır.
Belirli sütunları seçme
Aşağıdaki kod, ToDoItems tablosundaki tüm öğelerin nasıl döndürüleceği gösterilmektedir, ancak yalnızca tam ve metin alanlarını görüntüler. mToDoTable , daha önce oluşturduğumuz arka uç tablosuna başvurudur.
List<ToDoItemNarrow> result = mToDoTable
.select("complete", "text")
.execute()
.get();
Select işlevinin parametreleri, döndürmek istediğiniz tablo sütunlarının dize adlarıdır. Select yönteminin where ve orderBy gibi yöntemleri izlemesi gerekir. Bunu atlama ve üst gibi sayfalama yöntemleri takip edebilir.
Sayfalarda veri 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 sayfa boyutu üst sınırı 50 kayıttır.
İlk örnekte, bir tablodan ilk beş öğenin nasıl seç örnekleri gösterilmektedir. Sorgu, ToDoItems tablosundaki öğeleri döndürür. mToDoTable , daha önce oluşturduğunuz arka uç tablosuna başvurudur:
List<ToDoItem> result = mToDoTable
.top(5)
.execute()
.get();
İlk beş öğeyi atlayan ve ardından sonraki beş öğeyi döndüren bir sorgu aşağıdadır:
List<ToDoItem> result = mToDoTable
.skip(5).top(5)
.execute()
.get();
Tablodaki tüm kayıtları almak istiyorsanız, tüm sayfaları yinelemek için kod 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 ucuna en az iki istek oluşturur.
İpucu
doğru sayfa boyutunu seçmek, istek gerçekleştiği sırada bellek kullanımı, bant genişliği kullanımı ve verilerin tamamen alınmasındaki gecikme arasındaki dengedir. Varsayılan (50 kayıt) tüm cihazlar için uygundur. Yalnızca daha büyük bellek cihazlarında çalışırsanız 500'e kadar artırın. Sayfa boyutunun 500 kaydın üzerinde artırılmasının kabul edilemez gecikmelere ve büyük bellek sorunlarına neden olduğunu tespit ettik.
Nasıl yapılır: Sorgu yöntemlerini birleştirme
Arka uç tablolarını sorgulamada kullanılan yöntemler birleştirilebilir. Sorgu yöntemlerini zincirleme, sıralanmış ve sayfalandırılmış filtrelenmiş satırlardan oluşan belirli sütunları seçmenize olanak tanır. Karmaşık mantıksal filtreler oluşturabilirsiniz. Her sorgu yöntemi bir Query nesnesi döndürür. Yöntem serisini sonlandırmak ve sorguyu çalıştırmak için execute yöntemini çağırın. Örneğin:
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:
- Filtreleme (where) yöntemleri.
- Sıralama (orderBy) yöntemleri.
- Seçim (seçme) yöntemleri.
- disk belleği (atlama ve üst) yöntemleri.
Kullanıcı arabirimine veri bağlama
Veri bağlama üç bileşen içerir:
- Veri kaynağı
- Ekran düzeni
- İkisini birbirine bağlayan bağdaştırıcı.
Örnek kodumuzda, Mobile Apps SQL Azure tablosundaki ToDoItem tablosundaki verileri bir diziye döndüreceğiz. Bu etkinlik, veri uygulamaları için yaygın bir desendir. Veritabanı sorguları genellikle istemcinin bir liste veya diziye aldığı satır koleksiyonunu döndürür. Bu örnekte dizi veri kaynağıdır. Kod, cihazda görünen verilerin görünümünü tanımlayan bir ekran düzeni belirtir. İkisi, bu kodda ArrayAdapter ToDoItem> sınıfının bir uzantısı olan bir bağdaştırıcıyla birbirine<bağlıdır.
Düzeni Tanımlama
Düzen, XML kodunun birkaç kod parçacığı tarafından tanımlanır. Mevcut bir düzen göz önünde bulundurulduğunda, aşağıdaki kod sunucu verilerimizle doldurmak istediğimiz ListView'ı 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ın düzeninin kimliğini belirtir. Bu kod, bir onay kutusunu ve ilişkili metnini belirtir ve listedeki her öğe için bir kez örneklenir. Bu düzen kimlik alanını görüntülemez ve daha karmaşık bir düzen görüntüde ek alanlar belirtir. Bu kod row_list_to_do.xml dosyasındadı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üzün veri kaynağı bir ToDoItem dizisi olduğundan, bağdaştırıcımızı ArrayAdapter <ToDoItem sınıfından> alt sınıfa ekleriz. Bu alt sınıf, row_list_to_do düzenini kullanarak her ToDoItem için bir Görünüm oluşturur. Kodumuzda ArrayAdapter<E> sınıfının 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 yöntemini geçersiz kılın. Örneğin:
@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;
}
Etkinliğimizde aşağıdaki gibi bu sınıfın bir örneğini oluşturuyoruz:
ToDoItemAdapter mAdapter;
mAdapter = new ToDoItemAdapter(this, R.layout.row_list_to_do);
ToDoItemAdapter oluşturucusunun ikinci parametresi, düzene başvurudur. Artık ListView örneğini oluşturabilir ve bağdaştırıcıyı ListView'a atayabiliriz.
ListView listViewToDo = (ListView) findViewById(R.id.listViewToDo);
listViewToDo.setAdapter(mAdapter);
Bağdaştırıcıyı Kullanarak Kullanıcı Arabirimine Bağlama
Artık veri bağlamayı kullanmaya hazırsınız. Aşağıdaki kod, tablodaki öğelerin nasıl alınduğunu gösterir ve yerel bağdaştırıcıyı döndürülen öğelerle doldurur.
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ğinizde bağdaştırıcıyı çağırın. Değişiklikler kayıt temelinde yapıldığından, koleksiyon yerine tek bir satırı işlersiniz. Bir öğe eklediğinizde, bağdaştırıcıda add yöntemini çağırın; silerken remove yöntemini çağırın.
Android Hızlı Başlangıç Projesi'nde tam bir örnek bulabilirsiniz.
Arka uçtan 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;
Ardından nesne eklemek için insert() kullanın:
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 değerleri (, ve version
alanları gibicreatedAt
updatedAt
) içerir.
Mobile Apps tabloları id adlı 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 başka benzersiz değerler de sağlayabilirsiniz. Eklenen kayıt için dize kimliği değeri sağlanmadığında, arka uç yeni bir GUID oluşturur.
Dize Kimliği değerleri aşağıdaki avantajları sağlar:
- Veritabanına gidiş dönüş yapmadan kimlikler oluşturulabilir.
- Kayıtları farklı tablolardan veya veritabanlarından birleştirmek daha kolaydır.
- Kimlik değerleri bir uygulamanın mantığıyla daha iyi tümleşir.
Dize kimliği değerleri çevrimdışı eşitleme desteği için GEREKLIDIR . Kimliği arka uç veritabanında depolandıktan sonra değiştiremezsiniz.
Mobil uygulamadaki verileri güncelleştirme
Tablodaki verileri güncelleştirmek için yeni nesneyi update() yöntemine geçirin.
mToDoTable
.update(item) // Returns a ListenableFuture<ToDoItem>
.get();
Bu örnekte öğe, ToDoItem tablosunda bazı değişiklikler yapılmış bir satıra başvurudur. Aynı kimlikle satır güncelleştirilir.
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 kimlik alanını belirterek bir öğeyi silebilirsiniz.
String myRowId = "2FA404AB-E458-44CD-BC1B-3BC847EF0902";
mToDoTable
.delete(myRowId);
Belirli bir öğeyi kimliğine göre arama
lookUp() yöntemiyle belirli bir kimlik alanına sahip bir öğeyi arayın:
ToDoItem result = mToDoTable
.lookUp("0380BAFB-BCFF-443C-B7D5-30199F730335")
.get();
Nasıl yapılır: Yazılmamış verilerle çalışma
Yazılmamış programlama modeli, JSON serileştirmesi üzerinde tam denetim sağlar. Yazılmamış 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 sütunların yalnızca bir alt kümesine başvurmanız gerekiyorsa. Yazılan model, veri sınıfınızdaki Mobile Apps arka uçta tanımlanan tüm sütunları tanımlamanızı gerektirir. Verilere erişmek için yapılan API çağrılarının çoğu, yazılan programlama çağrılarına benzer. Temel fark, yazılmamış modelde MobileServiceTable nesnesi yerine MobileServiceJsonTable nesnesinde yöntemleri çağırmanızdır.
Yazılmamış bir tablonun örneğini oluşturma
Yazılan modele benzer şekilde, bir tablo başvurusu alarak başlarsınız, ancak bu durumda bir MobileServicesJsonTable nesnesidir. İstemcinin bir örneğinde getTable yöntemini çağırarak başvuruyu alın:
private MobileServiceJsonTable mJsonToDoTable;
//...
mJsonToDoTable = mClient.getTable("ToDoItem");
MobileServiceJsonTable'ın bir örneğini oluşturduktan sonra, yazılan programlama modeliyle neredeyse aynı API'ye sahiptir. Bazı durumlarda yöntemler, yazılan parametre yerine yazılmamış bir parametre alır.
Yazılmamış bir tabloya ekleme
Aşağıdaki kod, ekleme işleminin nasıl yapılacağını gösterir. İlk adım, gson kitaplığının parçası olan bir JsonObject oluşturmaktır.
JsonObject jsonItem = new JsonObject();
jsonItem.addProperty("text", "Wake up");
jsonItem.addProperty("complete", false);
Ardından, insert() kullanarak yazılmamış nesneyi tabloya ekleyin.
JsonObject insertedItem = mJsonToDoTable
.insert(jsonItem)
.get();
Eklenen nesnenin kimliğini almanız gerekiyorsa getAsJsonPrimitive() yöntemini kullanın.
String id = insertedItem.getAsJsonPrimitive("id").getAsString();
Yazılmamış bir tablodan silme
Aşağıdaki kod, önceki ekleme örneğinde oluşturulan bir JsonObject örneğinin aynı örneğinin nasıl silindiğini gösterir. Kod, türü belirtilen büyük/küçük harfle aynıdır, ancak yöntemin JsonObject'e başvurdığından farklı bir imzası vardır.
mToDoTable
.delete(insertedItem);
Ayrıca, örneğin kimliğini kullanarak da doğrudan silebilirsiniz:
mToDoTable.delete(ID);
Yazılmamış bir tablodaki tüm satırları döndürme
Aşağıdaki kodda tablonun tamamının nasıl alınacakları gösterilmektedir. JSON Tablosu kullandığınızdan, tablonun sütunlarından yalnızca bazılarını seçmeli olarak 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ürü belirlenmiş model için kullanılabilen aynı filtreleme, filtreleme ve sayfalama yöntemleri, yazılmamış model için de kullanılabilir.
Çevrimdışı Eşitleme Uygulama
Azure Mobile Apps İstemci SDK'sı, sunucu verilerinin bir kopyasını yerel olarak depolamak için SQLite veritabanı kullanarak verilerin çevrimdışı eşitlemesini de uygular. Çevrimdışı tabloda gerçekleştirilen işlemlerin çalışması için mobil bağlantı gerekmez. Çevrimdışı eşitleme, çakışma çözümü için daha karmaşık bir mantık harcamadan dayanıklılık ve performansa yardımcı olur. Azure Mobile Apps İstemci SDK'sı aşağıdaki özellikleri uygular:
- Artımlı Eşitleme: Bant genişliği ve bellek tüketimi tasarrufu sağlayan yalnızca güncelleştirilmiş ve yeni kayıtlar indirilir.
- İyimser Eşzamanlılık: İşlemlerin başarılı olduğu varsayılır. Sunucuda güncelleştirmeler gerçekleştirilene kadar Çakışma Çözümü erteleniyor.
- Çakışma Çözümü: SDK, sunucuda çakışan bir değişiklik 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 olanak tanır.
Çevrimdışı Eşitlemeyi Başlat
Her çevrimdışı tablo, kullanımdan önce çevrimdışı önbellekte tanımlanmalıdır. 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 başvuru alma
Çevrimiçi bir tablo için kullanırsınız .getTable()
. Çevrimdışı tablo için kullanın .getSyncTable()
:
MobileServiceSyncTable<ToDoItem> mToDoTable = mClient.getSyncTable("ToDoItem", ToDoItem.class);
Çevrimiçi tablolar için kullanılabilen tüm yöntemler (filtreleme, sıralama, sayfalama, veri ekleme, verileri güncelleştirme ve verileri silme dahil) çevrimiçi ve çevrimdışı tablolarda eşit derecede iyi çalışır.
Yerel Çevrimdışı Önbelleği Eşitleme
Eşitleme, uygulamanızın denetimindedir. Aşağıda örnek bir eşitleme yöntemi 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 .pull(query, queryname)
bir sorgu adı sağlanırsa, artımlı eşitleme yalnızca başarıyla tamamlanan son çekmeden sonra oluşturulan veya değiştirilen kayıtları döndürmek için kullanılır.
Çevrimdışı Eşitleme Sırasında Çakışmaları İşleme
Bir işlem sırasında .push()
çakışma oluşursa, bir MobileServiceConflictException
oluşturulur. Sunucu tarafından verilen öğe özel duruma eklenir ve özel durumda tarafından .getItem()
alınabilir. MobileServiceSyncContext nesnesinde aşağıdaki öğeleri çağırarak gönderimi ayarlayın:
.cancelAndDiscardItem()
.cancelAndUpdateItem()
.updateOperationAndItem()
Tüm çakışmalar istediğiniz gibi işaretlendikten sonra, tüm çakışmaları çözmek için yeniden arayın .push()
.
Özel API çağırma
Özel API, ekleme, güncelleştirme, silme veya okuma işlemiyle eşleşmeyen sunucu işlevselliğini kullanıma sunan özel uç noktalar tanımlamanızı sağlar. Özel BIR API kullanarak, HTTP ileti üst bilgilerini okuma ve ayarlama ve JSON dışında bir ileti gövdesi biçimi tanımlama da dahil olmak üzere mesajlaşma üzerinde daha fazla denetime sahip olabilirsiniz.
Bir Android istemcisinden, özel API uç noktasını çağırmak için invokeApi yöntemini çağırırsınız. Aşağıdaki örnekte, MarkAllResult adlı bir koleksiyon sınıfı döndüren completeAll adlı bir API uç noktasının nasıl çağrıldığı gösterilmektedir.
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();
}
});
}
invokeApi yöntemi istemcide çağrılır ve bu yöntem yeni özel API'ye bir POST isteği gönderir. Özel API tarafından döndürülen sonuç, hatalarda olduğu gibi bir ileti iletişim kutusunda görüntülenir. InvokeApi'nin diğer sürümleri isteğe bağlı olarak istek gövdesinde bir nesne göndermenize, HTTP yöntemini belirtmenize ve istekle birlikte sorgu parametreleri göndermenize olanak tanır. InvokeApi'nin yazılmamış sürümleri de sağlanır.
Uygulamanıza kimlik doğrulaması ekleme
Öğreticilerde bu özelliklerin nasıl ekleneceği ayrıntılı olarak açıklanmaktadır.
App Service çeşitli dış kimlik sağlayıcıları kullanarak uygulama kullanıcılarının kimliğini doğrulamayı 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 tablolarda izinleri ayarlayabilirsiniz. Arka ucunuzda yetkilendirme kuralları 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 arabirimini temel alan en basit kimlik doğrulama deneyimini sağlar. Sunucu akışı kimlik doğrulamasını uygulamak için ek SDK'lar gerekmez. Sunucu akışı kimlik doğrulaması, mobil cihazla 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 sağlanan SDK'ları kullandığından çoklu oturum açma gibi cihaza özgü özelliklerle daha ayrıntılı tümleştirme sağlar. Örneğin, Facebook SDK'sını mobil uygulamanızla tümleştirebilirsiniz. Mobil istemci Facebook uygulamasıyla değiştirilir ve mobil uygulamanıza geri dönmeden önce oturum açma işleminizi onaylar.
Uygulamanızda kimlik doğrulamasını etkinleştirmek için dört adım gerekir:
- Uygulamanızı bir kimlik sağlayıcısıyla kimlik doğrulaması için 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 tablolarda izinleri ayarlayabilirsiniz. İ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ını kullanmaya başlama ve Sunucu SDK'sı HOWTO belgelerini gözden geçirin.
Kimlik Doğrulaması: Sunucu Akışı
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ının 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 Activity 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_CODE
ana Etkinliğinizde tanımlanan yöntemi için login()
ve yöntemi içinde onActivityResult()
kullanılır. Yönteminde ve onActivityResult()
yönteminde login()
aynı sayı kullanıldığı sürece herhangi bir benzersiz sayı seçebilirsiniz. İstemci kodunu bir hizmet bağdaştırıcısına soyutlarsanız (daha önce gösterildiği gibi), hizmet bağdaştırıcısında uygun yöntemleri çağırmanız gerekir.
Projeyi özel sekmeler için de yapılandırmanız gerekir. İlk olarak bir redirect-URL belirtin. aşağıdaki kod parçacığını içine 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>
RedirectUriScheme dosyasını uygulamanızın build.gradle
dosyasına 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, dosyasındaki bağımlılıklar listesine build.gradle
ekleyincom.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 yöntemini kullanarak bir MobileServiceUser'dan oturum açmış kullanıcının kimliğini alın. Zaman uyumsuz oturum açma API'lerini çağırmak için Futures'ı kullanma örneği için bkz . Kimlik doğrulamasını kullanmaya başlama.
Uyarı
Bahsedilen URL Düzeni büyük/küçük harfe duyarlıdır. Büyük/küçük harf eşleşmesinin tüm örneklerinin {url_scheme_of_you_app}
olduğundan emin olun.
Önbellek kimlik doğrulama belirteçleri
Kimlik doğrulama belirteçlerini önbelleğe almak için Kullanıcı Kimliği ve kimlik doğrulama belirtecini cihazda yerel olarak depolamanız gerekir. Uygulama bir sonraki başlatıldığında önbelleği denetlersiniz ve bu değerler varsa, oturum açma yordamını atlayabilir ve istemciyi bu verilerle yeniden doldurmanız gerekir. Ancak bu veriler hassastır ve telefonun çalınması durumunda güvenlik için şifrelenmiş olarak depolanmalıdır. Kimlik doğrulama belirteçlerini önbelleğe alma işleminin tam bir örneğini Önbellek kimlik doğrulama belirteçleri bölümünde görebilirsiniz.
Süresi dolmuş bir belirteç kullanmaya çalıştığınızda 401 yetkisiz yanıt alırsınız. Filtreleri kullanarak kimlik doğrulama hatalarını işleyebilirsiniz. Filtreler App Service arka ucuna yönelik istekleri durdurur. Filtre kodu yanıtı 401 için test eder, oturum açma işlemini tetikler ve ardından 401'i oluşturan isteği sürdürür.
Yenileme Belirteçlerini Kullanma
Azure Uygulaması Hizmet Kimlik Doğrulaması ve Yetkilendirmesi tarafından döndürülen belirteç, bir saatlik tanımlı bir yaşam süresine sahiptir. Bu süreden sonra kullanıcının kimlik doğrulamasını yeniden oluşturmanız gerekir. İstemci akışı kimlik doğrulaması aracılığıyla aldığınız uzun ömürlü bir belirteç kullanıyorsanız, aynı belirteci kullanarak Azure Uygulaması Hizmet Kimlik Doğrulaması ve Yetkilendirme ile yeniden kimlik doğrulaması yapabilirsiniz. Yeni bir yaşam süresiyle başka bir Azure Uygulaması Hizmet belirteci oluşturulur.
Yenileme Belirteçlerini kullanmak için sağlayıcıyı da kaydedebilirsiniz. Yenileme Belirteci her zaman kullanılamaz. Ek yapılandırma gereklidir:
Azure Active Directory için Azure Active Directory Uygulaması için bir istemci gizli dizisi yapılandırın. Azure Active Directory Kimlik Doğrulamasını yapılandırırken Azure Uygulaması Hizmeti'nde istemci gizli dizisini belirtin. çağrısı
.login()
yaparken parametre olarak geçirinresponse_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);
Google için parametresini
access_type=offline
geçirin: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
.
Belirteci yenilemek için öğesini ç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.
İstemci akışı Kimlik Doğrulaması ile oturum açma
İstemci akışı kimlik doğrulamasıyla oturum açmak için genel işlem aşağıdaki gibidir:
Azure Uygulaması Hizmet Kimlik Doğrulaması ve Yetkilendirme'yi sunucu akışı kimlik doğrulaması gibi yapılandırın.
Erişim belirteci oluşturmak için kimlik doğrulaması için kimlik doğrulama sağlayıcısı SDK'sını tümleştirin.
yöntemini şu şekilde çağırın
.login()
(result
birAuthenticationResult
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ümdeki kod örneğinin tamamına bakın.
onSuccess()
yöntemini başarılı bir oturum açmada kullanmak istediğiniz kodla değiştirin. Dize {provider}
geçerli bir sağlayıcıdır: aad (Azure Active Directory), facebook, google, microsoftaccount veya twitter. Özel kimlik doğrulaması uyguladıysanız, özel kimlik doğrulama sağlayıcısı etiketini de kullanabilirsiniz.
Active Directory Kimlik Doğrulama Kitaplığı (ADAL) ile kullanıcıların kimliğini doğrulama
Azure Active Directory kullanarak uygulamanızda kullanıcıları oturum açmak için Active Directory Kimlik Doğrulama Kitaplığı'nı (ADAL) kullanabilirsiniz. daha yerel bir UX hissi sağladığından ve ek özelleştirmeye izin verdiğinden loginAsync()
, genellikle bir istemci akışı oturum açma bilgisi kullanmak, yöntemleri kullanmak için tercih edilir.
Active Directory için App Service'i yapılandırma oturum açma öğreticisini izleyerek mobil uygulama arka ucunuzu AAD oturum açma için yapılandırın. Yerel istemci uygulamasını kaydetmenin isteğe bağlı adımını tamamladığınızdan emin olun.
build.gradle dosyanızı aşağıdaki tanımları içerecek şekilde değiştirerek ADAL yükleyin:
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' }
Aşağıdaki değişiklikleri yaparak aşağıdaki kodu uygulamanıza ekleyin:
- INSERT-AUTHORITY-HERE yerine uygulamanızı sağladığınız kiracının adını yazın. Biçimi olmalıdır https://login.microsoftonline.com/contoso.onmicrosoft.com.
- INSERT-RESOURCE-ID-HERE yerine mobil uygulama arka ucunuzun istemci kimliğini girin. İstemci kimliğini portaldaki Azure Active Directory Ayarları altındaki Gelişmiş sekmesinden alabilirsiniz.
- INSERT-CLIENT-ID-HERE yerine yerel istemci uygulamasından kopyaladığınız istemci kimliğini girin.
- HTTPS düzenini kullanarak INSERT-REDIRECT-URI-HERE yerine sitenizin /.auth/login/done uç noktasını yazın. Bu değer ile https://contoso.azurewebsites.net/.auth/login/donebenzer 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);
}
}
İstemci-Sunucu İletişimini Ayarlama
İstemci 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 istemenin birkaç nedeni vardır:
- Zaman aşımlarını ayarlamak için alternatif bir HTTP kitaplığı kullanmak istiyorsunuz.
- İlerleme çubuğu sağlamak istiyorsunuz.
- API yönetimi işlevselliğini desteklemek için özel bir üst bilgi eklemek istiyorsunuz.
- Yeniden kimlik doğrulama uygulayabilmek için başarısız bir yanıtı kesmek istiyorsunuz.
- Arka uç isteklerini bir analiz hizmetine kaydetmek istiyorsunuz.
Alternatif HTTP Kitaplığı kullanma
.setAndroidHttpClientFactory()
İstemci başvurunuzu oluşturduktan hemen sonra yöntemini çağırın. Örneğin, bağlantı zaman aşımını varsayılan 10 saniye yerine 60 saniye olarak ayarlamak için:
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;
}
});
İlerleme Filtresi Uygulama
bir uygulayarak her isteğin kesme noktasını uygulayabilirsiniz ServiceFilter
. Örneğin, aşağıdakiler önceden oluşturulmuş bir 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 gibi ekleyebilirsiniz:
mClient = new MobileServiceClient(applicationUrl).withFilter(new ProgressFilter());
İstek Üst Bilgilerini Özelleştirme
Aşağıdakileri ServiceFilter
kullanın ve filtreyi 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ştirmeyi Yapılandırma
gson API'sini kullanarak her sütun için geçerli olan bir dönüştürme stratejisi belirtebilirsiniz. Android istemci kitaplığı, veriler Azure Uygulaması Hizmetine gönderilmeden önce Java nesnelerini JSON verilerine seri hale getirmek için arka planda gson kullanır. Aşağıdaki kod, stratejiyi ayarlamak için setFieldNamingStrategy() yöntemini kullanır. Bu örnek, her alan adı için ilk karakteri ("m") ve ardından sonraki karakteri küçük harfle siler. Örneğin, "mId"yi "id" olarak çevirir. Çoğu alanda ek açıklama gereksinimini azaltmak için SerializedName()
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, MobileServiceClient kullanılarak bir mobil istemci başvurusu oluşturmadan önce yürütülmelidir.