代码之家  ›  专栏  ›  技术社区  ›  mdadil2019

SyncAdapter onPerformSync仅第一次调用

  •  3
  • mdadil2019  · 技术社区  · 7 年前

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

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

    注意:我使用SyncAdapter而不是WorkManager,因为WorkManager(最新版本)在一些中国手机上不起作用,如Oppo Real Me 2 Pro、Real Me 1等。

    编辑:本期主要针对上述设备,如Oppo Real Me 2 Pro,它在其他轮询频率(周期同步)为60秒的设备上运行良好

    我已经创建了StubContentProvider和StubAuthenticator。

    下面是我的代码

    配置同步适配器

    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");
      }
    }
    

    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();
       }
    }
    

    同步适配器管理器

    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);
         }
       }
    
    }
    

    主要活动

    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 回复  |  直到 7 年前