2015-11-10 19 views
5

「StubProvider」と「StubAuthenticator」で同期アダプタを作成しようとしていますが、私は公式のガイドラインに従っていますが、コードはエラーなしで実行されていますが、 'onPerformSync呼び出されていない、私はすべてを試みたが使用していない。同期アダプタのContentResolver.requestSyncがAndroidで動作していません

クラス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(); 

    } 

} 

スタブ認証

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(); 
    } 
} 

クラスAuthenticatorServiceのクラス:

私の完全なプロジェクトはここhttps://www.dropbox.com/s/48bgj3wweehaieu/MyApplication.zip?dl=0

からダウンロードすることができますが、私が使用していたクラスがあります

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(); 
    } 
} 

クラス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(); 
    } 
} 

クラス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; 
    } 
} 

クラス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

多くのコードを提供していますが、正確には機能しないものはありますか?達成しようとしていること、期待される結果、実際の結果が何であるかをご記入ください。 'onPerformSync'が呼び出されている場合は –

+0

なので、あなたの問題は何ですか? – pskink

+1

愚かな私、私はちょうど編集.... 'onPerformSync'は呼び出されていません。 – Kazmi

答えて

0

あなたは同期アダプタのメタデータをXMLであなたのACCOUNT_TYPEを指定しましたか?

あなたのxml discriptorはこの

<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"/> 

ようにする必要がありますそして、最も重要なことは、

<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

あなたAndroidManifestファイルで宣言する必要がありますあなたはそれが動作していないですか?

同期アダプタは同じプロセスではないバインドサービス上で実行されるため、onPerformSync()のLog.d()はアプリケーションメインプロセスのLogCatに表示されず、同期アダプタが使用しています。

LogCatでフィルタを削除してみます。[選択したアプリケーションのみ表示]ではなく、[フィルタなし]を選択します。

+1

これは本当に私の2日の頭痛を解決しました。ありがとう:) –

+1

同じことが私に起こった。ありがとうたくさん:D –

+0

うわー、これは数時間と数時間のデバッグの後、これは黄金の手がかりでした。 「フィルタなし」を選択した後、ログを見て、動的なアクセス処理を実装していないことを認識しました。どうもありがとうございました! – saltandpepper

関連する問題