2015-09-21 60 views
0

这是我第一次创建同步适配器,并且出现问题,我在Android开发人员网站上跟着教程https://developer.android.com/training/sync-adapters/creating-sync-adapter.html,但我似乎无法让我的Sync工作。同步适配器未运行

我知道我做错了什么,但无法自己弄清楚。

SyncAdapter。

public class SyncAdapter extends AbstractThreadedSyncAdapter { 
     // Global variables 
     // Define a variable to contain a content resolver instance 
     ContentResolver mContentResolver; 

     /** 
     * Set up the sync adapter 
     */ 
     public SyncAdapter(Context context, boolean autoInitialize) { 
      super(context, autoInitialize); 
      /* 
      * If your app uses a content resolver, get an instance of it 
      * from the incoming Context 
      */ 
      mContentResolver = context.getContentResolver(); 
     } 

     /** 
     * Set up the sync adapter. This form of the 
     * constructor maintains compatibility with Android 3.0 
     * and later platform versions 
     */ 
     public SyncAdapter(
       Context context, 
       boolean autoInitialize, 
       boolean allowParallelSyncs) { 
      super(context, autoInitialize, allowParallelSyncs); 
      /* 
      * If your app uses a content resolver, get an instance of it 
      * from the incoming Context 
      */ 
      mContentResolver = context.getContentResolver(); 

     } 

     public void onPerformSync(
       Account account, 
       Bundle extras, 
       String authority, 
       ContentProviderClient provider, 
       SyncResult syncResult) { 
     /* 
     * Put the data transfer code here. 
     */ 
      Log.d("Message: ", "Perform Sync Call"); 
      new JSONAsyncTask().execute("http://example.com?category=1"); 



     } 
} 

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

MainActivity

public class MainActivity extends AppCompatActivity{ 

    int id = 0; 
    public static String CONNECTION_STATUS=""; 
    String TAG ="Message: "; 


    /** Sync adapter code **/ 
    // Constants 
    // The authority for the sync adapter's content provider 
    public static final String AUTHORITY = "com.example.tech6.sampleapp.contentprovider"; 
    // An account type, in the form of a domain name 
    public static final String ACCOUNT_TYPE = "com.android.example.sampleapp"; 
    // The account name 
    public static final String ACCOUNT = "dummyaccount"; 
    // Instance fields 
    Account mAccount; 
    ContentResolver mResolver; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_movies); 

     // Set the menu icon instead of the launcher icon. 
     final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 


     ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(getApplicationContext().CONNECTIVITY_SERVICE); 
     NetworkInfo ni = cm.getActiveNetworkInfo(); 
     /** Check if connected, then Sync **/ 
     if (ni != null) { 
     Account mAccount = new Account(
          ACCOUNT, ACCOUNT_TYPE); 
     Bundle extras = new Bundle(); 
     mResolver.setIsSyncable(mAccount, AUTHORITY, 1); 
     mResolver.setSyncAutomatically(mAccount, AUTHORITY, true); 
     mResolver.requestSync(mAccount, AUTHORITY, extras); 
     } 



    } 

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" /> 
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" /> 
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/Base.Theme.DesignDemo" > 
    <activity 
     android:name=".activity.MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

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

    <provider 
     android:name=".contentprovider.CinemalistingContentProvider" 
     android:authorities="com.example.tech6.providersample.contentprovider" > 
    </provider> 

AndroidManifest.xml中

<service 
       android:name=".helpers.SyncService" 
       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> 

XML/sync_adapter.xml

<?xml version="1.0" encoding="utf-8"?> 
<sync-adapter 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:contentAuthority="com.example.tech6.sampleapp.contentprovider" 
android:accountType="com.android.example.sampleapp" 
android:userVisible="true" 
android:supportsUploading="true" 
android:allowParallelSyncs="true" 
android:isAlwaysSyncable="true"/> 

任何帮助表示赞赏,感谢。

+0

您是如何得出结论的:同步不起作用?它不会在断点上停止,因为同步正在不同的进程中运行。另外日志打印在单独的logcat控制台中。您可以在Android监视器的下拉列表中选择进程。 – mixel

+0

为了进行调试,您可以从AndroidManifest.xml中的服务声明中移除android:process =“:sync”'。所以同步将在主进程中运行。 – mixel

回答

0

您必须在AccountManager中添加虚拟帐户才能在框架中注册SyncAdapter。

只需将您的new Account(...)之后,你必须调用以下几点:

// 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(mAccount, 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. 
     */ 
     Bundle extras = new Bundle(); 
     mResolver.setIsSyncable(mAccount, AUTHORITY, 1); 
     mResolver.setSyncAutomatically(mAccount, AUTHORITY, true); 
     mResolver.requestSync(mAccount, AUTHORITY, extras); 
    } else { 
     /* 
     * The account exists or some other error occurred. Log this, report it, 
     * or handle it internally. 
     */ 
    } 

另外,不要忘了申报SyncAdapter在你的清单与同步适配器元数据文件。

希望这会有所帮助。

+0

谢谢,我只是这样做,现在它给了我“调用者的用户名10059是不同于认证者的用户名”异常,我用我的清单文件和xml/sync_adapter.xml更新我的问题 –

+0

您是否为您的应用程序定义了一个Authenticator?如果你没有,你可以在你的清单中注册一个,或者你可以编程设置一个。 – pdegand59

+0

如何快速在我的清单中轻松注册Authenticator?我刚刚检出了这个链接https://developer.android.com/training/sync-adapters/creating-authenticator.html#DeclareAuthenticator,似乎我必须在声明它之前创建一个Authenticator Class,AuthenticatorService,authenticator XML在清单中。 –