Android: ContentResolver.requestSync() не запускается onPerformSync()

Я создаю приложение для Android, которое предоставляет пользователю кнопку для обновления базы данных, чтобы локальные данные и данные на сервере оставались синхронизированными.

Я создал Аутентификатор учетной записи, Поставщик контента и привязал их через службу. ContentResolver.requestSync() не вызывает onPerformSync().

Вот что у меня есть для кода:

public void refreshButton(View view) {
    Log.v("aye", "reached here");
    Bundle settings = new Bundle();
    settings.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL,true);
    settings.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
    Account dummyAccount = createDummyAccount(this);

    ContentResolver.requestSync(dummyAccount,MyContract.AUTHORITY,settings);
}

private Account createDummyAccount(Context context) {

    Account dummyAccount = new Account("dummyaccount","com.example.sid.fetchdata");
    AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE);
    try {
        accountManager.addAccountExplicitly(dummyAccount, null, null);
    } catch (Exception e) {
        e.printStackTrace();
    }
    ContentResolver.setSyncAutomatically(dummyAccount, MyContract.AUTHORITY, true);
    ContentResolver.setIsSyncable(dummyAccount,MyContract.AUTHORITY,1);
    return dummyAccount;
}

Я использую фиктивную учетную запись и создал аутентификатор учетной записи-заглушки в соответствии с Руководством для разработчиков Android.

Вот как выглядит мой класс SyncAdapter:

public class MySyncAdapter extends AbstractThreadedSyncAdapter {

private ContentResolver contentResolver;

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

public MySyncAdapter(Context context,boolean autoInitialize,boolean allowParallelSyncs) {
    super(context,autoInitialize,allowParallelSyncs);
    contentResolver = context.getContentResolver();
}
@Override
public void onPerformSync(Account account,Bundle extras,String authority,ContentProviderClient providerClient,SyncResult syncResult) {
    // android.os.Debug.waitForDebugger();
    // Log.e("first","Sync Started");
    GetData getData = new GetData(getContext());
    ContentValues[] questionsContentValues = getData.getAndParseDataContentValues();

    try {
        Log.d("inside","Inside");
        int deletedRows = providerClient.delete(MyContract.CONTENT_URI, null, null);
        // int addedRows = contentResolver.bulkInsert(MyContract.CONTENT_URI,questionsContentValues);
        // providerClient.insert(MyContract.CONTENT_URI,questionsContentValues[0]);
        // Log.v("third1","" + addedRows);
        contentResolver.notifyChange(MyContract.CONTENT_URI,null);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

Вот как устроен мой AndroidManfiest.xml:

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

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />



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

    <service
        android:name=".RetrieveService"
        android:exported="false" />

    <activity
        android:name=".FetchActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".ListActivity"
        android:label="@string/title_activity_list"
        android:parentActivityName=".FetchActivity"
        android:theme="@style/AppTheme.NoActionBar">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.sid.fetchdata.FetchActivity" />
    </activity>
    <activity
        android:name=".SwipeActivity"
        android:label="@string/title_activity_swipe"
        android:parentActivityName=".ListActivity"
        android:theme="@style/AppTheme.NoActionBar">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.sid.fetchdata.ListActivity" />
    </activity>

    <provider
        android:name=".MyContentProvider"
        android:syncable="true"
        android:exported="true"
        android:authorities="com.example.sid.fetchdata.provider" />

    <service
        android:name=".MyService"
        android:enabled="true"
        android:exported="true" >
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator"/>
        </intent-filter>

        <meta-data
            android:name="android.accounts.AccountAuthenticator"
            android:resource="@xml/account_authenticator" />
    </service>

    <service
        android:name=".SyncService"
        android:process=":sync"
        android:exported="true">
        <intent-filter>
            <action android:name="android.content.SyncAdapter"/>
        </intent-filter>

        <meta-data
            android:name="android.content.SyncAdapter"
            android:resource="@xml/my_sync_adapter" />
    </service>
</application>

The corresponding classes are, MyService is bound to the MyStubAuthenticator and SyncService is bound to SyncAdapter.

XML-файлы для MyStubAuthentica или:

<?xml version="1.0" encoding="utf-8"?>
<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:icon="@mipmap/ic_launcher"
android:smallIcon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:accountType="com.example.sid.fetchdata" />

XML-файл для SyncAdapter:

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

Класс контракта для провайдера следующий:

public class MyContract {

public static final String AUTHORITY = "com.example.sid.fetchdata.provider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + QuestionDataBaseHelper.TABLE_QUESTIONS);

public static final int QUESTIONS = 1;
public static final int QUESTIONS_ID = 2;

public static final String SINGLE_RECORD_MIME_TYPE = "vnd.android.cursor.item/vnd.com.example.sid.fetchdata.provider.questions";
public static final String MULTIPLE_RECORDS_MIME_TYPE = "vnd.android.cursor.dir/vnd.com.example.sid.fetchdata.provider.questions";

}

Я проверил, что ContentProvider работает, используя его в отдельном потоке. Учетная запись отображается в разделе «Учетные записи» в настройках телефона. Синхронизация застряла на Синхронизация сейчас...


person padfoot27    schedule 30.01.2016    source источник


Ответы (1)


Наконец устранил проблему. Проблема была с функцией onPerformSync(). Функция запускалась requestSync(), но

contentResolver.notifyChange(MyContract.CONTENT_URI,null);

была проблема. Функция, указанная в Docs сообщает, что последний аргумент syncToNetwork определяет, синхронизируются ли изменения с сетью. Поскольку я не передал его как ложное, был запущен бесконечный цикл, и, следовательно, для завершения синхронизации требовалось бесконечное время.

Таким образом, правильный вызов будет,

contentResolver.notifyChange(MyContract.CONTENT_URI,null,false);
person padfoot27    schedule 30.01.2016