2015-11-10 27 views
5

Tôi đang cố gắng viết bộ điều hợp đồng bộ hóa với 'StubProvider' và 'StubAuthenticator', tôi tuân thủ các nguyên tắc chính thức, mã của tôi đang chạy mà không có bất kỳ lỗi nào nhưng 'onPerformSync()' KHÔNG được gọi, tôi đã thử mọi thứ nhưng không sử dụng.ContentResolver.requestSync trong Bộ điều hợp Đồng bộ hóa không hoạt động trong Android

dự án đầy đủ của tôi có thể được tải về từ https://www.dropbox.com/s/48bgj3wweehaieu/MyApplication.zip?dl=0

Dưới đây là các lớp tôi đang sử dụng:

lớp MainActivity

public class MainActivity extends FragmentActivity implements View.OnClickListener { 

    // Constants 
    // The authority for the sync adapter's content provider 
    public static final String AUTHORITY = "com.syncadaptertest.StubProvider"; 
    // An account type, in the form of a domain name 
    public static final String ACCOUNT_TYPE = "com.syncadaptertest"; 
    // The account name 
    public static final String ACCOUNT = "dummyaccount"; 
    // Instance fields 
    Account mAccount; 

    private ImageButton mRefreshBtn = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_main); 

     mRefreshBtn = (ImageButton) findViewById(R.id.refreshBtn); 
     mRefreshBtn.setOnClickListener(this); 

     // Create the dummy account 
     mAccount = CreateSyncAccount(this); 

    } 

    /** 
    * Create a new dummy account for the sync adapter 
    * 
    * @param context The application context 
    */ 
    public static Account CreateSyncAccount(Context context) { 
     // Create the account type and default account 
     Account newAccount = new Account(ACCOUNT, ACCOUNT_TYPE); 
     // Get an instance of the Android account manager 
     AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE); 
     /* 
     * Add the account and account type, no password or user data 
     * If successful, return the Account object, otherwise report an error. 
     */ 
     if (accountManager.addAccountExplicitly(newAccount, null, null)) { 
      /* 
      * If you don't set android:syncable="true" in 
      * in your <provider> element in the manifest, 
      * then call context.setIsSyncable(account, AUTHORITY, 1) 
      * here. 
      */ 
     } else { 
      /* 
      * The account exists or some other error occurred. Log this, report it, 
      * or handle it internally. 
      */ 
     } 
     return newAccount; 
    } 


    @Override 
    public void onClick(View v){ 

     onRefreshButtonClick(v); 
    } 



    /** 
    * Respond to a button click by calling requestSync(). This is an 
    * asynchronous operation. 
    * 
    * This method is attached to the refresh button in the layout 
    * XML file 
    * 
    * @param v The View associated with the method call, 
    * in this case a Button 
    */ 
    public void onRefreshButtonClick(View v) { 

     // Pass the settings flags by inserting them in a bundle 
     Bundle settingsBundle = new Bundle(); 
     settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); 
     settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); 
     /* 
     * Request the sync for the default account, authority, and 
     * manual sync settings 
     */ 
     ContentResolver.setIsSyncable(mAccount, AUTHORITY, 1); 
     ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle); 

     if(ContentResolver.isSyncActive(mAccount, AUTHORITY)) 
     { 
      Log.d("testing1","testttt"); 
     } 
     if(ContentResolver.isSyncPending(mAccount, AUTHORITY)) 
     { 
      Log.d("testing2","testttt2"); 
     } 

     List<SyncInfo> myList = ContentResolver.getCurrentSyncs(); 

    } 

} 

Lớp Đối Stub Authenticator

public class Authenticator extends AbstractAccountAuthenticator { 
    // Simple constructor 
    public Authenticator(Context context) { 
     super(context); 
    } 
    // Editing properties is not supported 
    @Override 
    public Bundle editProperties(
      AccountAuthenticatorResponse r, String s) { 
     throw new UnsupportedOperationException(); 
    } 
    // Don't add additional accounts 
    @Override 
    public Bundle addAccount(
      AccountAuthenticatorResponse r, 
      String s, 
      String s2, 
      String[] strings, 
      Bundle bundle) throws NetworkErrorException { 
     return null; 
    } 
    // Ignore attempts to confirm credentials 
    @Override 
    public Bundle confirmCredentials(
      AccountAuthenticatorResponse r, 
      Account account, 
      Bundle bundle) throws NetworkErrorException { 
     return null; 
    } 
    // Getting an authentication token is not supported 
    @Override 
    public Bundle getAuthToken(
      AccountAuthenticatorResponse r, 
      Account account, 
      String s, 
      Bundle bundle) throws NetworkErrorException { 
     throw new UnsupportedOperationException(); 
    } 
    // Getting a label for the auth token is not supported 
    @Override 
    public String getAuthTokenLabel(String s) { 
     throw new UnsupportedOperationException(); 
    } 
    // Updating user credentials is not supported 
    @Override 
    public Bundle updateCredentials(
      AccountAuthenticatorResponse r, 
      Account account, 
      String s, Bundle bundle) throws NetworkErrorException { 
     throw new UnsupportedOperationException(); 
    } 
    // Checking features for the account is not supported 
    @Override 
    public Bundle hasFeatures(
      AccountAuthenticatorResponse r, 
      Account account, String[] strings) throws NetworkErrorException { 
     throw new UnsupportedOperationException(); 
    } 
} 

Lớp AuthenticatorService

public class AuthenticatorService extends Service { 

    // Instance field that stores the authenticator object 
    private Authenticator mAuthenticator; 
    @Override 
    public void onCreate() { 
     // Create a new authenticator object 
     mAuthenticator = new Authenticator(this); 
    } 
    /* 
    * When the system binds to this Service to make the RPC call 
    * return the authenticator's IBinder. 
    */ 
    @Override 
    public IBinder onBind(Intent intent) { 
     return mAuthenticator.getIBinder(); 
    } 
} 

Lớp SyncService

public class SyncService extends Service { 
    // Storage for an instance of the sync adapter 
    private static SyncAdapter sSyncAdapter = null; 
    // Object to use as a thread-safe lock 
    private static final Object sSyncAdapterLock = new Object(); 
    /* 
    * Instantiate the sync adapter object. 
    */ 
    @Override 
    public void onCreate() { 
     /* 
     * Create the sync adapter as a singleton. 
     * Set the sync adapter as syncable 
     * Disallow parallel syncs 
     */ 
     synchronized (sSyncAdapterLock) { 
      if (sSyncAdapter == null) { 
       sSyncAdapter = new SyncAdapter(getApplicationContext(), true); 
      } 
     } 
    } 
    /** 
    * Return an object that allows the system to invoke 
    * the sync adapter. 
    * 
    */ 
    @Override 
    public IBinder onBind(Intent intent) { 
     /* 
     * Get the object that allows external processes 
     * to call onPerformSync(). The object is created 
     * in the base class code when the SyncAdapter 
     * constructors call super() 
     */ 
     return sSyncAdapter.getSyncAdapterBinder(); 
    } 
} 

Lớp StubProvider

public class StubProvider extends ContentProvider { 
    /* 
    * Always return true, indicating that the 
    * provider loaded correctly. 
    */ 
    @Override 
    public boolean onCreate() { 
     return true; 
    } 
    /* 
    * Return no type for MIME type 
    */ 
    @Override 
    public String getType(Uri uri) { 
     return null; 
    } 
    /* 
    * query() always returns no results 
    * 
    */ 
    @Override 
    public Cursor query(
      Uri uri, 
      String[] projection, 
      String selection, 
      String[] selectionArgs, 
      String sortOrder) { 
     return null; 
    } 
    /* 
    * insert() always returns null (no URI) 
    */ 
    @Override 
    public Uri insert(Uri uri, ContentValues values) { 
     return null; 
    } 
    /* 
    * delete() always returns "no rows affected" (0) 
    */ 
    @Override 
    public int delete(Uri uri, String selection, String[] selectionArgs) { 
     return 0; 
    } 
    /* 
    * update() always returns "no rows affected" (0) 
    */ 
    public int update(
      Uri uri, 
      ContentValues values, 
      String selection, 
      String[] selectionArgs) { 
     return 0; 
    } 
} 

Lớp SyncAdapter

public class SyncAdapter extends AbstractThreadedSyncAdapter { 
    private final AccountManager mAccountManager; 

    public SyncAdapter(Context context, boolean autoInitialize) { 
     super(context, autoInitialize); 
     mAccountManager = AccountManager.get(context); 
    } 

    @Override 
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { 
     Log.d("udinic", "onPerformSync for account[" + account.name + "]"); 
     try { 
      // TODO Updating local tv shows 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Bạn đang cung cấp nhiều mã, nhưng chính xác thì những gì không hoạt động? Vui lòng mô tả những gì bạn đang cố gắng đạt được, kết quả mong đợi là gì và kết quả thực tế là gì. –

+0

nếu 'onPerformSync' đang được gọi, vậy vấn đề của bạn là gì? – pskink

+1

ngớ ngẩn tôi, tôi vừa chỉnh sửa .... 'onPerformSync' KHÔNG được gọi. – Kazmi

Trả lời

0

Bạn có thể chỉ định ACCOUNT_TYPE của bạn trên xml siêu dữ liệu của các bộ chuyển đổi đồng bộ?

discriptor xml của bạn nên được như thế này

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

Và quan trọng nhất là nó cần được khai báo trên AndroidManifest bạn nộp

<service 
     android:name=".sync.ContactSyncService" 
     android:exported="true"> 
     <intent-filter> 
      <action android:name="android.content.SyncAdapter" /> 
     </intent-filter> 
     <meta-data 
      android:name="android.content.SyncAdapter" 
      android:resource="@xml/sync_contact" /> 
    </service> 
24

Bạn có chắc chắn nó không làm việc? Hãy nhớ rằng Sync Adapter được chạy trên một Dịch vụ ràng buộc không có trong cùng một quá trình, vì vậy Log.d() của bạn trong onPerformSync() sẽ không hiển thị trong LogCat theo quy trình chính của ứng dụng của bạn nhưng trong quá trình Bộ điều hợp đồng bộ hóa đang sử dụng.

Thử xóa bộ lọc trong LogCat: thay vì "Chỉ hiển thị ứng dụng đã chọn", chọn "Không có bộ lọc".

+1

Điều này thực sự đã giải quyết được 2 ngày đau đầu cũ của tôi. Cảm ơn :) –

+1

Điều tương tự đã xảy ra với tôi. Cảm ơn rất nhiều: D –

+0

Wow, sau giờ làm việc và giờ gỡ lỗi này là đầu mối vàng. Sau khi chọn "Không có bộ lọc", tôi đã thấy nhật ký và nhận ra rằng tôi đã không triển khai xử lý quyền động. Cảm ơn nhiều! – saltandpepper

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