SyncAdapter onPerformSync仅第一次调用

时间:2019-01-30 10:31:56

标签: android android-syncadapter

我正在为我的应用程序构建一个同步适配器,我希望在每隔1小时查询一次数据库中的更改后向用户显示通知,即使应用程序将被终止。

我已经成功创建了同步适配器,但是onPermformSync()仅是第一次调用,并向我显示通知,然后在特定时间间隔(1小时)后它不会被调用,即使该应用程序仍在屏幕上显示(前景)

注意:我使用的是SyncAdapter而不是WorkManager,因为WorkManager(最新版本)在某些中国手机(例如Oppo Real Me 2 Pro,Real Me 1等)中无法正常工作。

编辑:此问题主要与上述设备(如Oppo Real Me 2 Pro)有关,并且在轮询频率(定期同步)为60秒的其他设备中也可以正常工作

我已经创建了StubContentProvider和StubAuthenticator。

下面是我的代码

ConfigurationSyncAdapter

public class ConfigurationSyncAdapter extends AbstractThreadedSyncAdapter {
public ConfigurationSyncAdapter(Context context, boolean autoInitialize) {
    super(context, autoInitialize);
}

@Override
public void onPerformSync(Account account, Bundle bundle, String s, ContentProviderClient contentProviderClient, SyncResult syncResult) {
    Log.e("sync","onPerformSync is called");
    showNotification(getContext(),"The query","let'see");
}

private void showNotification(Context context, String title, String message){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        CharSequence name = "RandomName";
        String description = "RandomDescription";
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel channel =
                new NotificationChannel("ID1", name, importance);
        channel.setDescription(description);
        // Add the channel
        NotificationManager notificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(channel);
        }
    }
    // Create the notification
    NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "ID1")
            //used notification icon for testing purpose
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setStyle(new NotificationCompat.BigTextStyle().bigText(message))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setVibrate(new long[0]);


    // Show the notification
    NotificationManagerCompat.from(context).notify(1, builder.build());
    Log.e("WorkManager","Notification shown");
  }
}

ConfigurationSyncAdapterService

public class ConfigurationSyncAdapterService extends Service {

private ConfigurationSyncAdapter syncAdapter = null;
private static final Object syncAdapterLock = new Object();

@Override
public void onCreate() {
    super.onCreate();
    synchronized (syncAdapterLock){
        if(syncAdapter == null)
            syncAdapter = new ConfigurationSyncAdapter(getApplicationContext(),true);
    }
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return syncAdapter.getSyncAdapterBinder();
   }
}

SyncAdapterManager

class SyncAdapterManager {

private static final String TAG = SyncAdapterManager.class.getSimpleName();
private final String authority;
private final String type;

private Account account;
private Context context;

SyncAdapterManager(final Context context) {
    this.context = context;

    type = context.getString(R.string.account_type);
    authority = context.getString(R.string.authority);
    account = new Account(context.getString(R.string.app_name), type);
}

@SuppressWarnings ("MissingPermission")
void beginPeriodicSync(final long updateConfigInterval) {
    Log.d(TAG, "beginPeriodicSync() called with: updateConfigInterval = [" +
            updateConfigInterval + "]");
    final AccountManager accountManager = (AccountManager) context
            .getSystemService(ACCOUNT_SERVICE);

    if (!accountManager.addAccountExplicitly(account, null, null)) {
        account = accountManager.getAccountsByType(type)[0];
    }

    setAccountSyncable();

    ContentResolver.addPeriodicSync(account, context.getString(R.string.authority),
            Bundle.EMPTY, updateConfigInterval);


    ContentResolver.setSyncAutomatically(account, authority, true);
}

void syncImmediately() {
    Bundle settingsBundle = new Bundle();
    settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
    settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);

    ContentResolver.requestSync(account, authority, settingsBundle);

}

private void setAccountSyncable() {
    if (ContentResolver.getIsSyncable(account, authority) == 0) {
        ContentResolver.setIsSyncable(account, authority, 1);
     }
   }

}

MainActivity

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    SyncAdapterManager syncAdapterManager = new SyncAdapterManager(this);
    syncAdapterManager.beginPeriodicSync(60*60);
    Log.e("sync","onCreate of Main Activity");

   }
 }

syncadapter.xml

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

</sync-adapter>

authenticator.xml

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

AndroidManifest.xml

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

<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.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    <service android:name=".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:authorities="@string/authority"
        android:name=".StubContentProvider"
        android:exported="false"
        android:syncable="true"/>

    <service android:name=".ConfigurationSyncAdapterService"
        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/syncadapter" />
    </service>
</application>

</manifest>

0 个答案:

没有答案