2013-03-26 30 views
11

Tôi đang cố gắng tìm ra cách syncAdapter hoạt động, tôi đã sử dụng adapter SampleSync làm ví dụ/điểm bắt đầu và tôi dựa trên thử nghiệm đầu tiên của mình trên đó. Sự khác biệt duy nhất là tôi không làm việc với nhà cung cấp danh sách liên hệ mặc định, nhưng tôi cần một người của riêng mình.SyncAdapter periodicsync() không kích hoạt

Phương pháp này giống như trong bản trình diễn mẫuSyncAdapter (trong AccountAuthenticatorActivity), tôi vừa thêm đồng bộ hóa định kỳ.

public void finishLogin(String authToken) { 
    Log.i(TAG, "finishLogin()"); 
    final Account account = new Account(mUsername, "be.company.syncAdapterTest"); 
    if(mRequestNewAccount) { 
     mAccountManager.addAccountExplicitly(account, mPassword, null); 
     ContentResolver.setIsSyncable(account, MY_AUTHORITY, 1); 

     Bundle params = new Bundle(); 
     params.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false); 
     params.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false); 
     params.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);   
     ContentResolver.addPeriodicSync(account, MY_AUTHORITY, params, 30); 
     ContentResolver.setSyncAutomatically(account, MY_AUTHORITY, true); 
     ContentResolver.requestSync(account,MY_AUTHORITY,params); 
    } else { 
     mAccountManager.setPassword(account, mPassword); 
    } 
    final Intent intent = new Intent(); 
    intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, "ACCOUNT_TEST"); 
    intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, "be.company.syncAdapterTest"); 
    setAccountAuthenticatorResult(intent.getExtras()); 
    setResult(RESULT_OK, intent); 
    finish(); 
} 

Trong phương pháp perfomSync() i có phương pháp sau đây:

@Override 
public void onPerformSync(Account account, Bundle extras, String authority, 
     ContentProviderClient provider, SyncResult syncResult) { 
    Log.d(TAG, "onPerformSync() start"); 
    // Testje 
    try { 
     final String authToken = mAccountManager.blockingGetAuthToken(account, "be.company.syncAdapterTest", NOTIFY_AUTH_FAILURE); 
     Log.d(TAG, SAPNetworkUtilities.getWeek(account, authToken, getRandomDate())); 
    } catch (OperationCanceledException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (AuthenticatorException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    Log.d(TAG, "onPerformSync() end"); 
} 

Ở đây tôi chỉ cần gọi một webservice SAP đơn giản và hiển thị nó trong nhật ký. Bây giờ tôi có hai câu hỏi sau đây:

  1. SYNC không được khởi động tự động khi tôi thêm Tài khoản trong cài đặt. Tôi cần phải đi vào bên trong tài khoản và chọn hộp kiểm để bắt đầu đồng bộ hóa?
  2. Đồng bộ hóa không được kích hoạt cứ 30 giây một lần trong ví dụ này ... Tôi có cần thêm điều gì đó trong phương thức perfomSync() để hệ thống biết rằng quá trình đồng bộ được thực hiện và lần chạy tiếp theo có thể bắt đầu không?

Tại thời điểm này tôi không viết giá trị trong contentProvider, chỉ vì tôi đang cố gắng tìm hiểu cách đồng bộ hóa hoạt động chi tiết.

Hiện tại tôi đang thử nghiệm trên trình giả lập Android.

Cảm ơn trước vì đã phản hồi của bạn.

Trân trọng!

Robin

+0

trùng lặp càng tốt này của [Tại sao ContentResolver.requestSync không kích hoạt đồng bộ?] (http://stackoverflow.com/questions/5253858/why-does-contentresolver-requestsync-not-trigger-a-sync) – jcwenger

+0

Tôi thiết lập một periodicSync với tần số <60s, và thấy một thông điệp logcat rằng hệ thống đã làm tròn nó lên đến 60 - tối thiểu không được đề cập trong tài liệu. Tất nhiên, tôi sẽ không đọc trang này nếu sau đó nó thực sự đồng bộ hóa - periodicSync cũng không làm việc cho tôi, bất kể setIsSyncable hay http://stackoverflow.com/questions/7925802/syncadapter- các cuộc gọi không được gọi-tùy-theo-của-tài-khoản-gọi-số- –

+0

@rpan Bạn có tìm thấy câu trả lời cho điều này không? –

Trả lời

1

Một đồng bộ hóa định kỳ chỉ có thể chạy nếu thiết lập tính năng tự động đồng bộ hóa của nó là ON và nó syncable = true. Một cách tiếp cận tốt hơn cho vấn đề này sẽ là sử dụng GCM. Máy chủ có thể gửi thông báo đẩy tới (các) thiết bị bất cứ khi nào có thay đổi mà khách hàng cần biết. Trên máy khách, chúng tôi yêu cầu đồng bộ hóa theo cách thủ công khi nhận được thông báo như vậy. Pin này hiệu quả hơn và chúng tôi được cập nhật ngay khi máy chủ của chúng tôi, mà không cần chờ chu kỳ đồng bộ hóa tiếp theo.

5

Tôi chỉ đập đầu vào tường trong nhiều giờ để tìm hiểu lý do đồng bộ hóa định kỳ không hoạt động. Nó chỉ ra rằng tần số thăm dò cần phải được tính bằng giây (theo chữ) không phải là mili giây, và không tính bằng giây tính bằng mili giây. Vì vậy, ví dụ: nếu bạn muốn đồng bộ hóa sau mỗi phút rưỡi, bạn sẽ cần phải gọi:

  ContentResolver.addPeriodicSync(
        account, 
        authority, 
        Bundle.EMPTY, 
        90 
      ); 

Ngoài ra, gói được chuyển vào không thể rỗng như trong tài liệu, nó sẽ ném một NullPointerException.

13

Tôi cũng đang gặp khó khăn với đồng bộ hóa định kỳ với bộ điều hợp đồng bộ hóa. Tôi có thể kích hoạt SyncAdapter theo cách thủ công với requestSync, nhưng addPeriodicSync sẽ không kích hoạt.

Tôi nhận thấy rằng trong tất cả của các ví dụ, đi tới Cài đặt-> Tài khoản đã hiển thị tài khoản SyncAdapter với "bánh xe đồng bộ" nhỏ (thường xanh nếu đồng bộ hóa tốt; đỏ nếu không đồng bộ hóa gần đây) cùng với dấu thời gian "Được đồng bộ hóa lần cuối". Tài khoản của tôi (một tài khoản giả được sao chép và dán từ Google Docs) không có bất kỳ thứ gì như bánh xe đồng bộ hoặc dấu thời gian được liệt kê.

Tiếp tục đào sâu hơn những gì đã xảy ra là vấn đề: nhà cung cấp nội dung của tôi không có nhãn trong XML của nó (trước đây tôi đã sử dụng nó không có vấn đề gì, vì vậy tôi lướt qua phần tài liệu đó). Thêm một nhãn đơn giản cho nhà cung cấp nội dung của tôi đã khiến nó hiển thị trong tài khoản của tôi trong Cài đặt, cùng với một bánh xe đồng bộ và dấu thời gian.

Dưới đây là một số mã được lấy từ ứng dụng của tôi để lấy cảm hứng. Hy vọng rằng nó sẽ giúp một ai đó, một nơi nào đó!

/res/xml/sync_adapter.xml

<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" 
android:accountType="com.example.database" 
android:allowParallelSyncs="false" 
android:contentAuthority="com.example.database.data.provider" 
android:isAlwaysSyncable="true" 
android:supportsUploading="false" 
android:userVisible="true" /> 

/com/example/cơ sở dữ liệu/dữ liệu/MySyncAdapter

public class MySyncAdapter extends AbstractThreadedSyncAdapter { 
    private static final String TAG = MySyncAdapter.class.getSimpleName(); 
    Context context; 

    public MySyncAdapter(Context context, boolean autoInitialize) { 
     super(context, autoInitialize); 
     this.context = context; 
    } 

    public MySyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) { 
     super(context, autoInitialize, allowParallelSyncs); 
     this.context = context; 
    } 

    @Override 
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { 
     Log.e(TAG, "Performing Sync"); 
    } 
} 

AndroidManifest.xml (CẦN Label cho nhà cung cấp nội dung để hiển thị trong tài khoản)

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    package="com.example.database"> 

    <uses-sdk tools:node="replace" /> 

    <uses-permission 
     android:name="android.permission.WRITE_EXTERNAL_STORAGE" 
     android:maxSdkVersion="18" /> 

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.VIBRATE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" /> 
    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" /> 
    <uses-permission android:name="android.permission.READ_SYNC_STATS" /> 


    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:logo="@drawable/chef_collection_logo_white" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 

     <provider 
      android:name="com.example.database.data.MyContentProvider" 
      android:authorities="com.example.database.data.provider" 
      android:label="my provider" 
      android:exported="false" 
      android:multiprocess="true" 
      android:syncable="true" /> 

     <activity 
      android:name=".app.MainActivity" 
      android:label="@string/title_activity_main"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <service 
      android:name="com.example.database.data.AuthenticatorService" 
      android:exported="true" 
      android:process=":auth"> 
      <intent-filter> 
       <action android:name="android.accounts.AccountAuthenticator" /> 
      </intent-filter> 
      <meta-data 
       android:name="android.accounts.AccountAuthenticator" 
       android:resource="@xml/authenticator" /> 
     </service> 

     <service 
      android:name="com.example.database.data.MySyncAdapterService" 
      android:exported="true" 
      android:process=":sync"> 
      <intent-filter> 
       <action android:name="android.content.SyncAdapter" /> 
      </intent-filter> 
      <meta-data 
       android:name="android.content.SyncAdapter" 
       android:resource="@xml/sync_adapter" /> 
     </service> 

    </application> 

</manifest> 

MainActivity. Tôi gọi mã này sau thuật sĩ thiết lập lần đầu tiên, nhưng bạn có thể gọi nó ở bất cứ đâu. Điều này sẽ cố gắng đồng bộ hóa mỗi 30 giây (được sử dụng để thử nghiệm). Lưu ý rằng Google Documents cho điều này hiện không chính xác, vì nó đề cập rằng nó muốn mili giây thay vì giây. Một điều cần lưu ý là bạn không thể vượt qua null như một bó. Làm như vậy sẽ ném một IllegalArgumentException hoặc một cái gì đó tương tự.

//Create Account 
mAccount = createSyncAccount(this); 


//Turn on periodic syncing 
ContentResolver resolver = getContentResolver(); 
resolver.setIsSyncable(mAccount, AUTHORITY, 1); 
resolver.setSyncAutomatically(mAccount, AUTHORITY, true); 

resolver.addPeriodicSync(
     mAccount, 
     AUTHORITY, 
     Bundle.EMPTY, 
     30); 
+0

Tính năng này chỉ có trên các phiên bản Android cụ thể không? Tôi đã đồng bộ hóa hoạt động trên tất cả các thiết bị ở đây mà không có nhãn trên nhà cung cấp nội dung ngoại trừ một số ở khách hàng. Và tôi không muốn thực hiện một bản phát hành mà không sửa chữa gì cả. – Roel

+0

@DalvikVM Có thể nó hoạt động mà không có nhãn và, nếu nó làm việc cho bạn, tôi sẽ không sửa chữa những gì không bị hỏng. Tôi đã làm việc với một bộ máy tính bảng Samsung Android cụ thể và đây là những gì dường như làm cho nó hoạt động. – welshk91

+0

@ wwlshk91: Nó bị hỏng trên một số máy tính bảng của khách hàng. Đây là Samsung Galaxy Notes 10.1 chạy Android 4.1.2. Wil cập nhật các máy tính bảng này để hỗ trợ 4.4? – Roel

12

Đồng bộ định kỳ không kích hoạt trong một số thiết bị nếu tùy chọn đồng bộ không được đặt. Tôi trở nên cuồng nhiệt với vấn đề này với một Samsung Galaxy Grand 2 thời gian gần đây ...

enter image description here

+0

Cảm ơn bạn rất nhiều ... :) – W00di

+0

cảm ơn một triệu – Trinity

0

đồng bộ định kỳ sẽ không hoạt động nếu thiết bị lưu trữ nội bộ là gần như đầy đủ, ngay cả khi tất cả các cấu hình đồng bộ của bạn được thiết ở bên phải way.Tôi nghĩ rằng đồng bộ sẽ ngừng hoạt động nếu 96 hoặc 97% bộ nhớ được sử dụng. Tôi không biết là bất kỳ điều khoản nào của họ để làm cho nó hoạt động ngay cả khi bộ nhớ gần đầy. Bạn có thể quan sát cùng một vấn đề trong ứng dụng gmail trong điện thoại di động Android, nơi đồng bộ sẽ không hoạt động khi bộ nhớ gần đầy. Bạn không thể nhận hoặc gửi tin nhắn bằng ứng dụng gmail android khi bộ nhớ thiết bị gần đầy.

0

Cái này hoạt động tốt đối với tôi Có hai sai lầm trong hướng dẫn đào tạo như xa như giải thích làm thế nào để làm cho addPeriodicSync công việc:

  1. Bạn phải gọi ContentResolver.setSyncAutomatically với đúng như (sync) thứ ba tham số để bật đồng bộ hóa cho bộ điều hợp của bạn trước khi addPeriodicSync. như thế này: ContentResolver.setSyncAutomatically (tài khoản, MY_AUTHORITY, true);

  2. Tham số thứ tư (pollFrequency) của ContentResolver.addPeriodicSync là một số giây, như đã nêu ở đây và không phải là mili giây, như ngụ ý trong hướng dẫn đào tạo. Mã demo cho addPeriodicSync trong hướng dẫn đào tạo sẽ gây ra đồng bộ một lần mỗi nghìn giờ thay vì mỗi giờ một lần. Vì vậy, tần số tối thiểu là 1 phút.

Tham khảo Để http://digitalassassin.net/2014/03/contentresolver-addperiodicsync-doesnt-work-never-syncs/

Các vấn đề liên quan