Fleshed out syncAdapter. Still needs more work.
This commit is contained in:
parent
0846b90952
commit
81dde7c961
|
@ -3,6 +3,12 @@
|
|||
package="no.nilsnh.uibevents" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<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"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
@ -23,6 +29,29 @@
|
|||
android:name=".data.EventProvider"
|
||||
android:exported="false"
|
||||
android:syncable="true" />
|
||||
|
||||
<!-- SyncAdapter's dummy authentication service -->
|
||||
<service android:name=".sync.UibEventsAuthenticatorService">
|
||||
<intent-filter>
|
||||
<action android:name="android.accounts.AccountAuthenticator" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.accounts.AccountAuthenticator"
|
||||
android:resource="@xml/authenticator" />
|
||||
</service>
|
||||
|
||||
<!-- The SyncAdapter service -->
|
||||
<service
|
||||
android:name=".sync.UibEventsSyncService"
|
||||
android:exported="true"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.content.SyncAdapter"
|
||||
android:resource="@xml/syncadapter" />
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
package no.nilsnh.uibevents;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.StrictMode;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import no.nilsnh.uibevents.data.EventDbHelper;
|
||||
import no.nilsnh.uibevents.sync.UibEventsSyncAdapter;
|
||||
|
||||
|
||||
public class MainActivity extends ActionBarActivity implements EventFragment.Callback {
|
||||
|
@ -45,6 +43,8 @@ public class MainActivity extends ActionBarActivity implements EventFragment.Cal
|
|||
// EventFragment eventFragment = ((EventFragment)getSupportFragmentManager()
|
||||
// .findFragmentById(R.id.fragment_forecast));
|
||||
// eventFragment.setUseTodayLayout(!mTwoPane);
|
||||
|
||||
UibEventsSyncAdapter.initializeSyncAdapter(this);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
package no.nilsnh.uibevents.sync;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.AbstractThreadedSyncAdapter;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.Context;
|
||||
import android.content.SyncResult;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
public class EventSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
|
||||
public final String LOG_TAG = EventSyncAdapter.class.getSimpleName();
|
||||
public static final int SYNC_INTERVAL = 60 * 180;
|
||||
|
||||
public EventSyncAdapter(Context context, boolean autoInitialize) {
|
||||
super(context, autoInitialize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
|
||||
Log.d(LOG_TAG, "Starting sync");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package no.nilsnh.uibevents.sync;
|
||||
|
||||
import android.accounts.AbstractAccountAuthenticator;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountAuthenticatorResponse;
|
||||
import android.accounts.NetworkErrorException;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* Manages "Authentication" to Sunshine's backend service. The SyncAdapter framework
|
||||
* requires an authenticator object, so syncing to a service that doesn't need authentication
|
||||
* typically means creating a stub authenticator like this one.
|
||||
* This code is copied directly, in its entirety, from
|
||||
* http://developer.android.com/training/sync-adapters/creating-authenticator.html
|
||||
* Which is a pretty handy reference when creating your own syncadapters. Just sayin'.
|
||||
*/
|
||||
public class UibEventsAuthenticator extends AbstractAccountAuthenticator {
|
||||
|
||||
public UibEventsAuthenticator(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
// No properties to edit.
|
||||
@Override
|
||||
public Bundle editProperties(
|
||||
AccountAuthenticatorResponse r, String s) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// Because we're not actually adding an account to the device, just return null.
|
||||
@Override
|
||||
public Bundle addAccount(
|
||||
AccountAuthenticatorResponse r,
|
||||
String s,
|
||||
String s2,
|
||||
String[] strings,
|
||||
Bundle bundle) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ignore attempts to confirm credentials
|
||||
@Override
|
||||
public Bundle confirmCredentials(
|
||||
AccountAuthenticatorResponse r,
|
||||
Account account,
|
||||
Bundle bundle) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Getting an authentication token is not supported
|
||||
@Override
|
||||
public Bundle getAuthToken(
|
||||
AccountAuthenticatorResponse r,
|
||||
Account account,
|
||||
String s,
|
||||
Bundle bundle) throws NetworkErrorException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// Getting a label for the auth token is not supported
|
||||
@Override
|
||||
public String getAuthTokenLabel(String s) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// Updating user credentials is not supported
|
||||
@Override
|
||||
public Bundle updateCredentials(
|
||||
AccountAuthenticatorResponse r,
|
||||
Account account,
|
||||
String s, Bundle bundle) throws NetworkErrorException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// Checking features for the account is not supported
|
||||
@Override
|
||||
public Bundle hasFeatures(
|
||||
AccountAuthenticatorResponse r,
|
||||
Account account, String[] strings) throws NetworkErrorException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package no.nilsnh.uibevents.sync;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
/**
|
||||
* The service which allows the sync adapter framework to access the authenticator.
|
||||
*/
|
||||
public class UibEventsAuthenticatorService extends Service {
|
||||
// Instance field that stores the authenticator object
|
||||
private UibEventsAuthenticator mAuthenticator;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
// Create a new authenticator object
|
||||
mAuthenticator = new UibEventsAuthenticator(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* When the system binds to this Service to make the RPC call
|
||||
* return the authenticator's IBinder.
|
||||
*/
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mAuthenticator.getIBinder();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package no.nilsnh.uibevents.sync;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.AbstractThreadedSyncAdapter;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.SyncRequest;
|
||||
import android.content.SyncResult;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import no.nilsnh.uibevents.R;
|
||||
|
||||
public class UibEventsSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
|
||||
public final String LOG_TAG = UibEventsSyncAdapter.class.getSimpleName();
|
||||
public static final int SYNC_INTERVAL = 60 * 180;
|
||||
public static final int SYNC_FLEXTIME = SYNC_INTERVAL/3;
|
||||
|
||||
public UibEventsSyncAdapter(Context context, boolean autoInitialize) {
|
||||
super(context, autoInitialize);
|
||||
}
|
||||
|
||||
//Downloads and enters it into db
|
||||
@Override
|
||||
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
|
||||
Log.d(LOG_TAG, "Starting sync");
|
||||
|
||||
}
|
||||
|
||||
public static void initializeSyncAdapter(Context context) {
|
||||
getSyncAccount(context);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to schedule the sync adapter periodic execution
|
||||
*/
|
||||
public static void configurePeriodicSync(Context context, int syncInterval, int flexTime) {
|
||||
Account account = getSyncAccount(context);
|
||||
String authority = context.getString(R.string.content_authority);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
// we can enable inexact timers in our periodic sync
|
||||
SyncRequest request = new SyncRequest.Builder().
|
||||
syncPeriodic(syncInterval, flexTime).
|
||||
setSyncAdapter(account, authority).
|
||||
setExtras(new Bundle()).build();
|
||||
ContentResolver.requestSync(request);
|
||||
} else {
|
||||
ContentResolver.addPeriodicSync(account,
|
||||
authority, new Bundle(), syncInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to have the sync adapter sync immediately
|
||||
* @param context The context used to access the account service
|
||||
*/
|
||||
public static void syncImmediately(Context context) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
|
||||
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
|
||||
ContentResolver.requestSync(getSyncAccount(context),
|
||||
context.getString(R.string.content_authority), bundle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to get the fake account to be used with SyncAdapter, or make a new one
|
||||
* if the fake account doesn't exist yet. If we make a new account, we call the
|
||||
* onAccountCreated method so we can initialize things.
|
||||
*
|
||||
* @param context The context used to access the account service
|
||||
* @return a fake account.
|
||||
*/
|
||||
public static Account getSyncAccount(Context context) {
|
||||
// Get an instance of the Android account manager
|
||||
AccountManager accountManager =
|
||||
(AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
|
||||
|
||||
// Create the account type and default account
|
||||
Account newAccount = new Account(
|
||||
context.getString(R.string.app_name), context.getString(R.string.sync_account_type));
|
||||
|
||||
// If the password doesn't exist, the account doesn't exist
|
||||
if ( null == accountManager.getPassword(newAccount) ) {
|
||||
|
||||
/*
|
||||
* Add the account and account type, no password or user data
|
||||
* If successful, return the Account object, otherwise report an error.
|
||||
*/
|
||||
if (!accountManager.addAccountExplicitly(newAccount, "", null)) {
|
||||
return null;
|
||||
}
|
||||
/*
|
||||
* If you don't set android:syncable="true" in
|
||||
* in your <provider> element in the manifest,
|
||||
* then call ContentResolver.setIsSyncable(account, AUTHORITY, 1)
|
||||
* here.
|
||||
*/
|
||||
|
||||
onAccountCreated(newAccount, context);
|
||||
}
|
||||
return newAccount;
|
||||
}
|
||||
|
||||
private static void onAccountCreated(Account newAccount, Context context) {
|
||||
/*
|
||||
* Since we've created an account
|
||||
*/
|
||||
UibEventsSyncAdapter.configurePeriodicSync(context, SYNC_INTERVAL, SYNC_FLEXTIME);
|
||||
|
||||
/*
|
||||
* Without calling setSyncAutomatically, our periodic sync will not be enabled.
|
||||
*/
|
||||
ContentResolver.setSyncAutomatically(newAccount, context.getString(R.string.content_authority), true);
|
||||
|
||||
/*
|
||||
* Finally, let's do a sync to get things started
|
||||
*/
|
||||
syncImmediately(context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package no.nilsnh.uibevents.sync;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
public class UibEventsSyncService extends Service {
|
||||
private static final Object sSyncAdapterLock = new Object();
|
||||
private static UibEventsSyncAdapter uibEventsSyncAdapter = null;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Log.d("SunshineSyncService", "onCreate - SunshineSyncService");
|
||||
synchronized (sSyncAdapterLock) {
|
||||
if (uibEventsSyncAdapter == null) {
|
||||
uibEventsSyncAdapter = new UibEventsSyncAdapter(getApplicationContext(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return uibEventsSyncAdapter.getSyncAdapterBinder();
|
||||
}
|
||||
}
|
|
@ -8,4 +8,5 @@
|
|||
<string name="list_item_date_from_textview">18.11.15</string>
|
||||
<string name="list_item_date_to_textview">20.11.15</string>
|
||||
<string name="list_item_title_textview">The Norwegian Constitution \"VI: 1814 - 2014\"</string>
|
||||
<string name="sync_account_type">uibevents.nilsnh.no</string>
|
||||
</resources>
|
||||
|
|
6
app/src/main/res/xml/authenticator.xml
Normal file
6
app/src/main/res/xml/authenticator.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:accountType="@string/sync_account_type"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:smallIcon="@mipmap/ic_launcher" />
|
9
app/src/main/res/xml/syncadapter.xml
Normal file
9
app/src/main/res/xml/syncadapter.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:contentAuthority="@string/content_authority"
|
||||
android:accountType="@string/sync_account_type"
|
||||
android:userVisible="false"
|
||||
android:supportsUploading="false"
|
||||
android:allowParallelSyncs="false"
|
||||
android:isAlwaysSyncable="true" />
|
Loading…
Reference in a new issue