Çağrı requestSync()
, yalnızca sistem tarafından bilinen bir {Account, ContentAuthority} çifti üzerinde çalışacaktır. Uygulamanızın, Android'e belirli bir hesap türü kullanarak belirli bir tür içeriği senkronize edebileceğinizi söylemek için birkaç adımdan geçmesi gerekir. Bunu AndroidManifest'te yapar.
1. Android'e uygulama paketinizin senkronizasyon sağladığını bildirin
Öncelikle, AndroidManifest.xml'de bir Eşitleme Hizmetine sahip olduğunuzu beyan etmeniz gerekir:
<service android:name=".sync.mySyncService" android:exported="true">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/sync_myapp" />
</service>
<service>
Etiketin name özniteliği, senkronizasyonu bağlamak için sınıfınızın adıdır ... Bununla biraz sonra konuşacağım.
Dışa aktarılan true ayarı, diğer bileşenlere görünür hale getirir (gerekli olduğu ContentResolver
için çağrılabilir).
Amaç filtresi, senkronizasyon isteyen bir amacı yakalamasını sağlar. (Bu Intent
, ContentResolver
aradığınızda ContentResolver.requestSync()
veya ilgili zamanlama yöntemlerinden gelir.)
<meta-data>
Etiket aşağıda ele alınacaktır.
2. Android'e SyncAdapter bulmak için kullanılan bir hizmet sağlayın
Yani sınıfın kendisi ... İşte bir örnek:
public class mySyncService extends Service {
private static mySyncAdapter mSyncAdapter = null;
public SyncService() {
super();
}
@Override
public void onCreate() {
super.onCreate();
if (mSyncAdapter == null) {
mSyncAdapter = new mySyncAdapter(getApplicationContext(), true);
}
}
@Override
public IBinder onBind(Intent arg0) {
return mSyncAdapter.getSyncAdapterBinder();
}
}
Sınıfınız genişletilmeli Service
veya alt sınıflarından biri uygulanmalı public IBinder onBind(Intent)
ve SyncAdapterBinder
çağrıldığında bir döndürmelidir ... Bir tür değişkenine ihtiyacınız var AbstractThreadedSyncAdapter
. Gördüğünüz gibi, bu sınıftaki hemen hemen her şey. Var olmasının tek nedeni, Android'in sınıfınızı kendinizin ne olduğu konusunda sorgulaması için standart bir arayüz sunan bir Hizmet sağlamaktır SyncAdapter
.
3. class SyncAdapter
Eşitlemeyi gerçekten gerçekleştirmek için a sağlayın .
mySyncAdapter, gerçek eşitleme mantığının kendisinin depolandığı yerdir. Onun onPerformSync()
zamanı senkronizasyonu geldiğinde yöntem çağrılır. Sanırım bunu zaten yerine getirdin.
4. Bir Hesap türü ile bir İçerik Yetkilisi arasında bir bağlantı kurun
AndroidManifest'e tekrar dönüp baktığımızda <meta-data>
, hizmetimizdeki bu garip etiket, bir ContentAuthority ile bir hesap arasındaki bağlantıyı kuran anahtar parçadır. Harici olarak başka bir xml dosyasına referansta bulunur (istediğinizi adlandırın, uygulamanızla ilgili bir şey.) Sync_myapp.xml'e bakalım:
<?xml version="1.0" encoding="utf-8" ?>
<sync-adapter
xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.android.contacts"
android:accountType="com.google"
android:userVisible="true" />
Tamam, peki bu ne yapıyor? Android'e, tanımladığımız senkronizasyon adaptörünün ( bu dosyaya referans <service>
veren <meta-data>
etiketi içeren etiketin ad öğesinde çağrılan sınıf ...) kişileri com.google tarzı bir hesap kullanarak senkronize edeceğini söyler.
Tüm contentAuthority dizelerinizin tümü eşleşmeli ve senkronize ettiğiniz şeyle eşleşmelidir - Bu, kendi veritabanınızı oluşturuyorsanız tanımladığınız bir dize olmalıdır veya senkronize ediyorsanız bazı mevcut cihaz dizelerini kullanmalısınız. veri türleri (kişiler veya takvim etkinlikleri gibi veya sizde ne var.) Yukarıdaki ("com.android.contacts"), kişi türü verileri (sürpriz, sürpriz) için ContentAuthority dizesidir.
accountType ayrıca önceden girilmiş olan bilinen hesap türlerinden biriyle eşleşmeli veya oluşturduğunuz hesap türleriyle eşleşmelidir (Bu, sunucunuzda kimlik doğrulaması almak için bir AccountAuthenticator alt sınıfı oluşturmayı içerir ... Bir makaleye değer.) Yine "com.google", google.com tarzı hesap kimlik bilgilerini tanımlayan tanımlı dizedir (yine, bu bir sürpriz olmamalıdır.)
5. Belirli bir Hesap / ContentAuthority çiftinde Senkronizasyonu etkinleştirin
Son olarak, senkronizasyonun etkinleştirilmesi gerekir. Bunu, kontrol panelindeki Hesaplar ve Senkronizasyon sayfasında uygulamanıza gidip eşleşen hesapta uygulamanızın yanındaki onay kutusunu ayarlayarak yapabilirsiniz. Alternatif olarak, bunu uygulamanızdaki bazı kurulum kodlarında yapabilirsiniz:
ContentResolver.setSyncAutomatically(account, AUTHORITY, true);
Senkronizasyonun gerçekleşmesi için, hesap / yetki çiftinizin senkronizasyon için etkinleştirilmesi (yukarıdaki gibi) ve sistemdeki genel global senkronizasyon bayrağının ayarlanması ve cihazın ağ bağlantısının olması gerekir.
Hesabınız / yetki eşitlemeniz veya genel eşitleme devre dışı bırakılırsa, RequestSync () 'i çağırmanın bir etkisi olur - Eşitlemenin istendiği bir bayrak belirler ve eşitleme etkinleştirilir etkinleştirilmez gerçekleştirilir.
Ayrıca, mgv başına, isteğinizinContentResolver.SYNC_EXTRAS_MANUAL
ekstra paketinde doğru olarak ayarlamak , Android'den global senkronizasyon kapalı olsa bile bir senkronizasyonu zorlamasını ister (burada kullanıcınıza karşı saygılı olun!)
Son olarak, yine ContentResolver işlevleriyle periyodik bir zamanlanmış senkronizasyon ayarlayabilirsiniz.
6. Birden çok hesabın sonuçlarını düşünün
Aynı türden birden fazla hesaba sahip olmak mümkündür (bir cihazda veya iki facebook hesabında kurulu iki @ gmail.com hesabı veya iki twitter hesabı, vb.) Bunu yapmanın uygulama sonuçlarını göz önünde bulundurmalısınız. .. İki hesabınız varsa, muhtemelen her ikisini de aynı veritabanı tablolarına eşitlemeyi denemek istemezsiniz. Belki bir seferde yalnızca birinin etkin olabileceğini belirtmeniz ve hesap değiştirirseniz tabloları temizleyip yeniden senkronize etmeniz gerekebilir. (hangi hesapların mevcut olduğunu sorgulayan bir mülk sayfası aracılığıyla). Belki her hesap için farklı bir veritabanı, belki farklı tablolar, belki her tabloda bir anahtar sütun oluşturursunuz. Tüm uygulamalara özel ve biraz düşünmeye değer. ContentResolver.setIsSyncable(Account account, String authority, int syncable)
burada ilgi çekici olabilir. setSyncAutomatically()
bir hesap / yetki çiftinin kontrol edilip edilmeyeceğini kontrol eder veyaişaretlenmemiş , oysa setIsSyncable()
hattın işaretini kaldırıp grileştirmenin bir yolunu sağlar , böylece kullanıcı onu açamaz. Bir hesabı Senkronize Edilebilir, diğerini Senkronize Edilemez (dsabled) olarak ayarlayabilirsiniz.
7. ContentResolver.notifyChange () konusunda bilgi sahibi olun
Zor bir şey. s ContentResolver.notifyChange()
tarafından ContentProvider
Android'e yerel veritabanının değiştirildiğini bildirmek için kullanılan bir işlevdir . Bu, iki işleve hizmet eder, birincisi, içerik uri'nin ardından gelen imleçlerin güncellenmesine ve daha sonra a ListView
, vb.'nin yeniden sorgulanmasına ve geçersiz kılınmasına ve yeniden çizilmesine neden olur ... Bu çok sihirli, veritabanı değişir ve ListView
yalnızca otomatik olarak güncellemeleriniz. Muhteşem. Ayrıca, veritabanı değiştiğinde, Android, normal programınızın dışında bile sizin için Senkronizasyon talep eder, böylece bu değişiklikler cihazdan çıkarılır ve mümkün olan en hızlı şekilde sunucuyla senkronize edilir. Ayrıca harika.
Yine de bir uç durum var. Sunucudan çeker ve bir güncellemeyi içine gönderirseniz, görev ContentProvider
bilinciyle arayacak notifyChange()
ve android "Oh, veritabanı değişiklikleri, bunları sunucuya koysanız iyi olur!" (Doh!) ContentProviders
Değişikliklerin ağdan mı yoksa kullanıcıdan mı geldiğini görmek için iyi yazılmış bazı testler olacak ve syncToNetwork
eğer öyleyse bu gereksiz çift senkronizasyonu önlemek için boole bayrağını yanlış ayarlayacaktır . Bir veriyi ContentProvider
a'ya besliyorsanız , bunun nasıl çalıştırılacağını anlamanız gerekir - Aksi takdirde, yalnızca birine ihtiyaç duyulduğunda her zaman iki senkronizasyon gerçekleştirirsiniz.
8. Mutlu hissedin!
Tüm bu xml meta verilerini yerleştirip senkronizasyonu etkinleştirdikten sonra, Android her şeyi sizin için nasıl bağlayacağını bilecek ve senkronizasyon çalışmaya başlayacaktır. Bu noktada, hoş olan pek çok şey yerine oturacak ve sihir gibi hissedecek. Zevk almak!