0

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.

Antwort

1

Es scheint, ich ein Rookie Fehler gemacht. onPerformSync() wird tatsächlich aufgerufen. Aber ich hatte den Filter "Zeige nur ausgewählte Anwendung" in meinem Android-Monitor-Set, so dass die Log.d im Hintergrund-Synchronisierungsdienst nicht angezeigt wurde. This Antwort half mir aus.

Verwandte Themen