Also folgte ich dem Tutorial zum Erstellen eines SyncAdapter ohne einen echten ContentProvider und ein Konto (von here), stieß aber auf ein Problem, das ich einfach nicht beheben kann.ContentResolver.requestSync ruft SyncAdapter nicht an
Wenn ContentResolver.requestSync() aufrufen erzwingen manuell eine Synchronisierung, so scheint es, dass die SyncAdapter ich funktioniert einfach nicht umgesetzt genannt. Bitte beachten Sie, dass ich all Stub-Klassen erstellt (StubAuthenticator, StubProvider, AuthenticatorService) und die SyncService genau, wie sie in dem genannten Tutorial erstellt wurden. Wenn Sie mich brauchen, um den Code in beide Richtungen zu veröffentlichen, werde ich diesen Beitrag bearbeiten.
Android Manifest.xml
<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
<?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
<?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
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
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
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;
}
}
Der Code, bis ContentResolver.requestSync gerade fein up führt() in die DataSyncUtil-Klasse, aber die DataSy ncAdapter wird nie aufgerufen.
würde ich jede Hilfe dankbar auf diese
:) FYI: Das ist mein erstes Android-Projekt großen Maßstab ist, also bin ich ziemlich unerfahren.