首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ContentResolver.requestSync不叫SyncAdapter

ContentResolver.requestSync不叫SyncAdapter
EN

Stack Overflow用户
提问于 2016-11-03 15:22:28
回答 1查看 602关注 0票数 1

因此,我按照教程创建了一个没有真正的SyncAdapter和帐户的ContentProvider (来自这里),但是遇到了一个我无法解决的问题。

当调用ContentResolver.requestSync()手动强制同步时,我实现的SyncAdapter似乎没有被调用。请注意,我创建了所有存根类(StubAuthenticator、StubProvider、AuthenticatorService)和在上述教程中如何创建的SyncService。如果您需要我以任何方式发布代码,我将编辑这篇文章。

Android Manifest.xml

代码语言:javascript
运行
复制
<application


    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
    <uses-permission android:name="android.permission.READ_SYNC_STATS"/>
    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>

    ...        

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

    <service
        android:name=".datasync.AuthenticatorService">
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator"/>
        </intent-filter>
        <meta-data
            android:name="android.accounts.AccountAuthenticator"
            android:resource="@xml/authenticator"/>
    </service>

    <provider
        android:name=".datasync.StubProvider"
        android:authorities="myexample.com.provider"
        android:enabled="true"
        android:exported="false"
        android:label="DataSyncContentProvider"
        android:syncable="true"/>

</application>

sync_adapter.xml

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
          android:contentAuthority="myexample.com.provider"
          android:accountType="myexample.com.account"
          android:userVisible="false"
          android:allowParallelSyncs="false"
          android:isAlwaysSyncable="true"/>

authenticator.xml

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="myexample.com.account"
    android:label="MyExampleApp"/>

DataSyncAdapter.java

代码语言:javascript
运行
复制
public class DataSyncAdapter extends AbstractThreadedSyncAdapter{

    public DataSyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider,
                          SyncResult syncResult) {
        Log.d(MainActivity.TAG, "onPerformSync: Called");

        //do sync stuff here
    }
}

MainActivity.java

代码语言:javascript
运行
复制
public class MainActivity extends AppCompatActivity{
    /**
     * Tag for own application.
     */
    public static final String TAG = "com.myexample";

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

        //create UI here...

        Bundle syncExtras = new Bundle();
        //add additional sync stuff (internal)
        DataSyncUtil.createSyncRequest(this, syncExtras);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]
        grantResults) {
        switch (requestCode) {
            case PERMISSIONS_GET_ACCOUNTS:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Bundle syncExtras = new Bundle();

                    //add additional sync stuff (internal)

                    DataSyncUtil.createSyncRequest(this, syncExtras);
                } else {
                    //TODO handle permission denied
                }
                return;
        }
    }
}

DataSyncUtil.java

代码语言:javascript
运行
复制
public class DataSyncUtil {

    public static void createSyncRequest(Activity activity, Bundle extras) {
        Log.d(MainActivity.TAG, "createSyncRequest: Called");
        String authority = "myexample.com.provider";
        Account dummy = getDummySyncAccount(activity);
        if (dummy != null) {
            if (ContentResolver.isSyncPending(dummy, authority) ||
                ContentResolver.isSyncActive(dummy, authority)) {
                Log.i(MainActivity.TAG, "SyncPending, canceling");
                ContentResolver.cancelSync(dummy, authority);
            }
            extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
            extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);

            ContentResolver.requestSync(dummy, authority, extras);
        }
    }

    public static Account getDummySyncAccount(Activity activity) {
        String auth_type = "myexample.com.account;
        Account dummy = null;
        AccountManager accountManager = (AccountManager) activity.getSystemService(ACCOUNT_SERVICE);

        if (ContextCompat.checkSelfPermission(activity, Manifest.permission.GET_ACCOUNTS) !=
            PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.GET_ACCOUNTS},
                    MainActivity.PERMISSIONS_GET_ACCOUNTS);
        } else {
            Account[] existing = accountManager.getAccountsByType(auth_type);
            if (existing != null && existing.length > 0) {
                //TODO handle more than one account
                Log.d(MainActivity.TAG, "getDummySyncAccount: Account already exists and is getting returned");
                dummy = existing[0];
            } else {
                Log.d(MainActivity.TAG, "getDummySyncAccount: Account has to be created");
                // Create the account type and default account
                dummy = new Account(ACCOUNT, auth_type);
                // Get an instance of the Android account manager
                /*
                 * Add the account and account type, no password or user data
                 * If successful, return the Account object, otherwise report an error.
                 */
                if (accountManager.addAccountExplicitly(dummy, null, null)) {
                    ContentResolver.setIsSyncable(dummy, "myexample.com.content", 1);
                    ContentResolver.setSyncAutomatically(dummy, "myexample.com.content", true);
                } else {
                /*
                 * The account exists or some other error occurred.Log this, report it,
                 * or handle it internally.
                 */

                }
            }
        }
        Log.d(MainActivity.TAG, "getDummySyncAccount: "+dummy.name);
        return dummy;
    }

}

代码执行良好,直到ContentResolver.requestSync()在DataSyncUtil类中执行,但是DataSyncAdapter从未被调用。

我希望在这方面提供任何帮助:)

FYI:这是我第一个大规模的Android项目,所以我相当缺乏经验。

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40405345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档