การโทรrequestSync()
จะใช้ได้เฉพาะกับคู่ {Account, ContentAuthority} ที่ระบบรู้จัก แอปของคุณต้องทำตามขั้นตอนหลายขั้นตอนเพื่อบอก Android ว่าคุณสามารถซิงโครไนซ์เนื้อหาบางประเภทโดยใช้บัญชีประเภทใดประเภทหนึ่งได้ มันทำสิ่งนี้ใน AndroidManifest
1. แจ้ง Android ว่าแพคเกจแอปพลิเคชันของคุณมีการซิงค์
ก่อนอื่นใน AndroidManifest.xml คุณต้องประกาศว่าคุณมีบริการซิงค์:
<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>
แท็กคือชื่อชั้นเรียนของคุณที่จะเชื่อมต่อการซิงค์ ... ฉันจะคุยกับมันในไม่ช้า
การตั้งค่าที่ส่งออกจริงทำให้ส่วนประกอบอื่น ๆ มองเห็นได้ (จำเป็นจึงContentResolver
สามารถเรียกมันได้)
ตัวกรองความตั้งใจช่วยให้สามารถตรวจจับเจตนาที่ร้องขอการซิงค์ได้ ( Intent
มาจากContentResolver
เวลาที่คุณโทรหาContentResolver.requestSync()
หรือวิธีการจัดตารางเวลาที่เกี่ยวข้อง)
<meta-data>
แท็กจะได้รับการกล่าวถึงด้านล่าง
2. ให้บริการ Android เพื่อค้นหา SyncAdapter ของคุณ
ดังนั้นชั้นเรียนเอง ... นี่คือตัวอย่าง:
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();
}
}
ชั้นเรียนของคุณต้องขยายService
หรือหนึ่ง subclasses ของตนจะต้องดำเนินการpublic IBinder onBind(Intent)
และต้องส่งคืนSyncAdapterBinder
เมื่อที่เรียกว่า ... AbstractThreadedSyncAdapter
คุณต้องตัวแปรประเภท อย่างที่คุณเห็นนั่นคือทุกอย่างในชั้นเรียนนั้น เหตุผลเดียวที่ให้บริการคือมีอินเทอร์เฟซมาตรฐานสำหรับ Android เพื่อสอบถามชั้นเรียนของคุณว่าSyncAdapter
ตัวเองเป็นอย่างไร
3. ระบุclass SyncAdapter
เพื่อทำการซิงค์จริง
mySyncAdapter เป็นที่เก็บตรรกะการซิงค์จริง ใช้onPerformSync()
วิธีการได้รับเรียกว่าเมื่อมันถึงเวลาที่จะซิงค์ ฉันคิดว่าคุณมีสิ่งนี้อยู่แล้ว
4. สร้างความผูกพันระหว่างประเภทบัญชีและหน่วยงานเนื้อหา
เมื่อมองย้อนกลับไปที่ AndroidManifest อีกครั้ง<meta-data>
แท็กแปลก ๆในบริการของเราเป็นส่วนสำคัญที่สร้างการเชื่อมโยงระหว่าง ContentAuthority และบัญชี มันอ้างอิงไฟล์ xml อื่นจากภายนอก (เรียกว่าอะไรก็ได้ที่คุณต้องการสิ่งที่เกี่ยวข้องกับแอปของคุณ) ลองดูที่ sync_myapp.xml:
<?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" />
โอเคแล้วมันทำอะไร? มันบอก Android ว่าอะแดปเตอร์การซิงค์ที่เรากำหนดไว้ (คลาสที่ถูกเรียกในองค์ประกอบชื่อของ<service>
แท็กที่มี<meta-data>
แท็กที่อ้างอิงไฟล์นี้ ... ) จะซิงค์ผู้ติดต่อโดยใช้บัญชีสไตล์ com.google
เนื้อหาทั้งหมดของคุณสตริงผู้มีอำนาจต้องตรงกันทั้งหมดและตรงกับสิ่งที่คุณกำลังซิงค์ - นี่ควรเป็นสตริงที่คุณกำหนดหากคุณกำลังสร้างฐานข้อมูลของคุณเองหรือคุณควรใช้สตริงอุปกรณ์ที่มีอยู่หากคุณรู้จักการซิงค์ ชนิดข้อมูล (เช่นรายชื่อติดต่อหรือกิจกรรมในปฏิทินหรือสิ่งที่คุณมี) ด้านบน ("com.android.contacts") เป็นสตริง ContentAuthority สำหรับข้อมูลประเภทผู้ติดต่อ (แปลกใจแปลกใจ)
accountType ยังต้องจับคู่ประเภทบัญชีที่รู้จักที่ป้อนแล้วหรือต้องตรงกับประเภทที่คุณสร้าง (ซึ่งเกี่ยวข้องกับการสร้างคลาสย่อยของ AccountAuthenticator เพื่อรับการรับรองความถูกต้องบนเซิร์ฟเวอร์ของคุณ ... คุ้มค่ากับบทความนั้นเอง) อีกครั้ง "com.google" คือสตริงที่กำหนดไว้ซึ่งระบุ ... ข้อมูลรับรองบัญชีสไตล์ google.com (อีกครั้งไม่น่าแปลกใจ)
5. เปิดใช้งานการซิงค์ในคู่บัญชี / ContentAuthority ที่กำหนด
สุดท้ายต้องเปิดใช้งานการซิงค์ คุณสามารถทำได้ในหน้าบัญชีและการซิงค์ในแผงควบคุมโดยไปที่แอพของคุณและตั้งค่าช่องทำเครื่องหมายถัดจากแอพของคุณภายในบัญชีที่ตรงกัน หรือคุณสามารถทำได้ในรหัสการตั้งค่าบางอย่างในแอปของคุณ:
ContentResolver.setSyncAutomatically(account, AUTHORITY, true);
เพื่อให้การซิงค์เกิดขึ้นคู่บัญชี / ผู้มีอำนาจของคุณต้องเปิดใช้งานเพื่อซิงค์ (เหมือนข้างบน) และต้องตั้งค่าสถานะการซิงค์ส่วนกลางโดยรวมบนระบบและอุปกรณ์ต้องมีการเชื่อมต่อเครือข่าย
หากการซิงค์บัญชี / ผู้มีอำนาจของคุณหรือการซิงค์ส่วนกลางถูกปิดใช้งานการเรียก RequestSync () จะมีผล - ตั้งค่าสถานะว่ามีการร้องขอการซิงค์และจะดำเนินการทันทีที่เปิดใช้งานการซิงค์
นอกจากนี้ตามmgvการตั้งค่าContentResolver.SYNC_EXTRAS_MANUAL
เป็นจริงในชุดพิเศษของ requestSync ของคุณจะขอให้ Android บังคับให้ซิงค์แม้ว่าการซิงค์ทั่วโลกจะปิดอยู่ก็ตาม (โปรดเคารพผู้ใช้ของคุณที่นี่!)
สุดท้ายคุณสามารถตั้งค่าการซิงค์ตามกำหนดเวลาเป็นระยะได้อีกครั้งด้วยฟังก์ชัน ContentResolver
6. พิจารณาความหมายของบัญชีหลายบัญชี
เป็นไปได้ที่จะมีบัญชีประเภทเดียวกันมากกว่าหนึ่งบัญชี (สองบัญชี @ gmail.com ตั้งค่าบนอุปกรณ์หนึ่งหรือสองบัญชี Facebook หรือสองบัญชี Twitter เป็นต้น) คุณควรพิจารณาถึงผลกระทบของแอปพลิเคชันในการทำเช่นนั้น .. หากคุณมีสองบัญชีคุณคงไม่อยากพยายามซิงค์ทั้งสองบัญชีลงในตารางฐานข้อมูลเดียวกัน บางทีคุณอาจต้องระบุว่าสามารถใช้งานได้ครั้งละหนึ่งรายการเท่านั้นและล้างตารางและซิงค์ใหม่หากคุณเปลี่ยนบัญชี (ผ่านหน้าคุณสมบัติที่สอบถามว่ามีบัญชีอะไรบ้าง) บางทีคุณอาจสร้างฐานข้อมูลที่แตกต่างกันสำหรับแต่ละบัญชีอาจเป็นตารางที่แตกต่างกันอาจจะเป็นคอลัมน์หลักในแต่ละตาราง แอปพลิเคชันทั้งหมดเฉพาะและคุ้มค่ากับความคิด ContentResolver.setIsSyncable(Account account, String authority, int syncable)
อาจสนใจที่นี่ setSyncAutomatically()
ควบคุมว่าจะตรวจสอบคู่บัญชี / ผู้มีอำนาจหรือไม่ได้ทำเครื่องหมายในขณะที่setIsSyncable()
มีวิธีการยกเลิกการเลือกและทำให้เส้นเป็นสีเทาเพื่อให้ผู้ใช้ไม่สามารถเปิดได้ คุณอาจตั้งค่าให้บัญชีหนึ่งซิงค์ได้และอีกบัญชีหนึ่งไม่สามารถซิงค์ได้ (dsabled)
7. ระวัง ContentResolver.notifyChange ()
สิ่งที่ยุ่งยากอย่างหนึ่ง ContentResolver.notifyChange()
เป็นฟังก์ชันที่ใช้ContentProvider
เพื่อแจ้งให้ Android ทราบว่ามีการเปลี่ยนแปลงฐานข้อมูลภายในเครื่อง สิ่งนี้ทำหน้าที่สองฟังก์ชั่นอย่างแรกมันจะทำให้เคอร์เซอร์หลังจากที่เนื้อหานั้นอัปเดต uri และในทางกลับกันการร้องขอและทำให้ไม่ถูกต้องและวาดใหม่ListView
ฯลฯ ... มันวิเศษมากฐานข้อมูลจะเปลี่ยนและListView
อัปเดตของคุณโดยอัตโนมัติ น่ากลัว นอกจากนี้เมื่อฐานข้อมูลมีการเปลี่ยนแปลง Android จะร้องขอการซิงค์ให้คุณแม้จะอยู่นอกกำหนดการปกติของคุณเพื่อให้การเปลี่ยนแปลงเหล่านั้นถูกลบออกจากอุปกรณ์และซิงค์กับเซิร์ฟเวอร์โดยเร็วที่สุด ยังน่ากลัว
แม้ว่าจะมีขอบกรณีเดียว หากคุณดึงออกจากเซิร์ฟเวอร์และผลักดันการอัปเดตเข้าสู่ระบบContentProvider
จะเรียกตามหน้าที่notifyChange()
และ Android จะไป "โอ้การเปลี่ยนแปลงฐานข้อมูลดีกว่าวางไว้บนเซิร์ฟเวอร์!" (Doh!) เขียนอย่างดีContentProviders
จะมีการทดสอบเพื่อดูว่าการเปลี่ยนแปลงมาจากเครือข่ายหรือจากผู้ใช้และจะตั้งค่าsyncToNetwork
สถานะบูลีนเป็นเท็จหากเป็นเช่นนั้นเพื่อป้องกันการซิงค์สองครั้งที่สิ้นเปลือง หากคุณกำลังป้อนข้อมูลลงใน a ContentProvider
คุณจะต้องคิดหาวิธีทำงานนี้ - มิฉะนั้นคุณจะต้องทำการซิงค์สองครั้งเสมอเมื่อต้องการเพียงอันเดียว
8. รู้สึกมีความสุข!
เมื่อคุณมีข้อมูลเมตา xml ทั้งหมดนี้และเปิดใช้งานการซิงค์แล้ว Android จะรู้วิธีเชื่อมต่อทุกอย่างให้คุณและการซิงค์จะเริ่มทำงาน ณ จุดนี้หลายสิ่งที่ดีจะคลิกเข้าที่และมันจะรู้สึกเหมือนมีเวทมนตร์ สนุก!