2012-06-18 39 views
15

Tôi có một SyncAdapter cho ứng dụng của mình và AccountManager để thêm tài khoản ứng dụng của tôi vào Trình quản lý tài khoản Android. Mã của tôi khi tôi thêm một tài khoản để quản lý tài khoản trông giống như:Android SyncAdapter Tự động khởi chạy Đồng bộ hóa

Bundle data = new Bundle(5); 
data.putString(_PEOPLE_ID, people_id); 
data.putString(_FIRST_NAME, first_name); 
data.putString(_LAST_NAME, last_name); 
data.putString(_PLAN, plan); 
data.putString(_BIRTHDAY, birthday); 
Account account = new Account(username, _ACCOUNT_TYPE); 
try { 
    boolean created; 
    created = _account_manager.addAccountExplicitly(account, 
            _cryptography.encrypt(_SEED, password), data); 
    response.accountCreated(created); 
    _account_manager.setAuthToken(account, _TOKEN_TYPE, session_token); 
    _model.updateActiveAccount(people_id, username, password); 
    SharedPreferences.Editor settings = _settings.edit(); 
    settings.putString(_ACCOUNT_TYPE, account.name); 
    settings.putString(_TOKEN_TYPE, session_token); 
    settings.commit(); 
    // Tells the content provider that it can sync this account 
    ContentResolver.setIsSyncable(account, AUTHORITY, 1); 
    final Bundle extras = new Bundle(1); 
    extras.putBoolean(SYNC_EXTRAS_INITIALIZE, true); 
    ContentResolver.addPeriodicSync(account, AUTHORITY, extras, 900); 
} catch (Exception e) { 
    Ln.e(e.getCause()); 
} 

tôi có thể thêm tài khoản vào tài khoản quản lý thành công thông qua Settings, nhưng tôi phải tự Bật đồng bộ hóa cho tài khoản trong Cài đặt cũng có, thậm chí mặc dù dữ liệu nền và đồng bộ hóa cài đặt tự động được bật trên trình mô phỏng. Nếu tôi bật đồng bộ hóa theo cách thủ công, thì đồng bộ hóa được thực hiện tốt, nó chỉ không được khởi động theo mặc định.

Trả lời

28
ContentResolver.setIsSyncable(account, AUTHORITY, 1); 
ContentResolver.setSyncAutomatically(account, AUTHORITY, true); 

Như Blehi nói sẽ bắt đầu đồng bộ tự động của tài khoản nhất định, trao Cài đặt toàn cầu, "Bối cảnh dữ liệu" và "Auto-sync" được kích hoạt.

Để ngăn chặn các back-to-back đồng bộ (from jcwenger) chắc chắn rằng nếu bất kỳ phương pháp trong SyncAdapter.onPerformSync(...) cuộc gọi ContentResolver.notifyChange(...) nó sử dụng ContentResolver.notifyChange(uri, observer, false) để cờ thông báo không để kích hoạt một cuộc gọi đồng bộ (tham số thứ ba là syncToNetwork).

Nếu bạn đang sử dụng ContentProvider để thực hiện chèn/xóa/cập nhật cho bạn SyncAdapter nó làm cho tinh thần để gọi ContentResolver.notifyChange(...) để khi ứng dụng có thể nhìn thấy người dùng có thể nhận được thông tin cập nhật từ SyncAdapter, có nghĩa là bạn sẽ có cơ ContentProvider thực hiện các cuộc gọi ContentResolver.notifyChange(...). Để thiết lập này hoạt động, tôi đã thêm (sau dev guide) CALLER_IS_SYNC_ADAPTER tham số truy vấn vào mọi URI được sử dụng cho SyncAdapter. Thêm phương pháp này để các ContentProvider để kiểm tra các URI đến

/** 
* Determines if the given URI specifies that the request is coming from the sync adapter. 
* @param uri the given URI 
* @return true if the uri specifies that the request is coming from the sync adapter 
*/ 
private boolean callerIsSyncAdapter(Uri uri) { 
    final String is_sync_adapter = uri.getQueryParameter(CALLER_IS_SYNC_ADAPTER); 
    return is_sync_adapter != null && !is_sync_adapter.equals("0"); 
} 

sau đó bạn có thể làm

getContext().getContentResolver().notifyChange(uri, observer, !callerIsSyncAdapter(uri)); 

bất cứ khi nào bạn cần gửi một thông báo thay đổi.

Và nếu bạn muốn lên lịch đồng bộ được thực hiện định kỳ ở tần suất (bỏ phiếu cho máy chủ), hãy thêm số này bằng lệnh gọi ContentResolver.setSyncAutomatically(...).

ContentResolver.addPeriodicSync(account, AUTHORITY, new Bundle(), frequency_in_seconds) 
6

Bạn phải thiết lập tài khoản để được syncable theo mặc định:

ContentResolver.setIsSyncable(account, AUTHORITY, 1); 
ContentResolver.setSyncAutomatically(account, AUTHORITY, true); 

tôi sử dụng 2 dòng trên và nó hoạt động đúng.

+0

Thêm nội dungResolver.setSyncTự động (tài khoản, AUTHORITY, true); là những gì tôi cần, nhưng có vẻ như nó không thừa nhận sự đồng bộ định kỳ. Sau khi tôi thêm tài khoản, nó chỉ liên tục đồng bộ hóa. –

+0

Vui lòng thử gọi hàm ContentResolver.addPeriodicSync() với Bundle mới() thay vì tính năng bổ sung. – Blehi

+0

extras là một Bundle mới(), tôi thậm chí còn thử nó mà không cố gắng đặt bất kỳ cờ nào (Bundle extras = new Bundle(); addPeriodicSync (tài khoản, AUTHORITY, extras, 900);) –

13

Chỉ cần nhấn mạnh, dường như addPeriodicSync() nhu cầu setSyncAutomatically(), mặc dù các tài liệu nói rằng setSyncAutomatically() là chỉ để phát hiện mạng tickles.

Lưu ý rằng khoảng thời gian sẽ được sửa thành> 60 nếu thời gian đó ít hơn một phút.

+2

Tài liệu của Google có hại tại thời điểm này – cja

+1

Làm thế nào để không có tài liệu này trong tài liệu của họ? – toobsco42

2

Ban đầu hãy tạo tài khoản và kiểm tra hỗ trợ đồng bộ hóa cho cùng một tài khoản bằng Trình quản lý tài khoản. Nếu tài khoản hỗ trợ đồng bộ thì hãy gọi setIsSyncable() và setSyncAutomatically().

AccountManager accountManager = (AccountManager) this.getSystemService(ACCOUNT_SERVICE); 
if(accountManager.addAccountExplicitly(newAccount, null, null)){ 
     ContentResolver.setIsSyncable(account, AUTHORITY, 1); 
     ContentResolver.setSyncAutomatically(account, AUTHORITY, true); 
} 

Sau đó, bạn có thể kích hoạt đồng bộ hóa bất kỳ lúc nào.Nó sẽ kích hoạt.

Lưu ý: onPerformSync() của setSyncAutomatically() sẽ được gọi trước rồi chỉ yêu cầu đồng bộ hóa khác sẽ được kích hoạt. Nhưng để thực hiện đồng bộ hóa lực chỉ cần thêm 2 cờ bổ sung.

Bundle bundle= new Bundle(); 
    bundle.putBoolean(
      ContentResolver.SYNC_EXTRAS_MANUAL, true); 
    bundle.putBoolean(
      ContentResolver.SYNC_EXTRAS_EXPEDITED, true); 
    ContentResolver.requestSync(account, AUTHORITY, bundle); 
Các vấn đề liên quan