Download - Session #8 adding magic to your app
Adding magic to your app
#8Android Academy TLV
25/12/2016Yossi Segev
Wifi: Techiteasy
Yossi Segev
Crave
Android Academy
Jonathan Yarkoni
Android Developer & Advocate Ironsource
Android Academy Staff
Yonatan LevinGoogle Developer
Expert & Android @ Gett
Britt BarakAndroid Lead
Figure8
Yossi SegevAndroid Developer
Crave
Announcement!
Shahar AvigezerDesigner & Developer
What Do We Do?
●Android Fundamentals - NOW
● Android Best Practice - 17/1
● Android UI / UX - 29/1 !
● Community Hackathon - 9/3 !!!
●Android Performance
●Mentors Program
Community Mentors
Ilan Peled
Agenda
Notifications - communicate with your users from outside of your app.
Broadcast-Receivers - Listen and react to events.
Services - Perform tasks even without direct user interaction.
SyncAdapter - Sync data between the device to a server like the “big players”.
We’ve got a LOT to cover - take a deep breath :)
Notifications
Notification
A message you can display to the user outside of the application UI.
Notification
Must contain:● Small Notification
icon● Title● Description
Showing a notification
1.Create a new Notification object using NotificationCompat.Builder.
2.Get a reference to the NotificationManager.
3.Show the notification.
1.Create a new Notification object using NotificationCompat.Builder.
2.Get a reference to the NotificationManager.
3.Show the notification.
Showing a notification
NotificationCompat.Builder
Fluent interface to construct Notification object.
Helps maintain backward compatibility.
Creating a basic notificationNotification notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_star_white_24dp) .setContentTitle("Hello world!") .setContentText("Description goes here.") .build();
1.Create a new Notification object using NotificationCompat.Builder.
2.Get a reference to the NotificationManager.
3.Show the notification.
Showing a notification
Notification Manager
One of many system-level services.
Access by calling getSystemService().
https://developer.android.com/reference/android/app/NotificationManager.html
getSystemService()
A way to get a handle to a system-level service, such as:NotificationsAlarmsLocationWifi
Pass the service name (usually, a constant on Context class), and cast the result.
http://developer.android.com/reference/android/content/Context.html#getSystemService(java.lang.String)
Creating a basic notificationNotification notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_star_white_24dp) .setContentTitle("Hello world!") .setContentText("Description goes here.") .build();
NotificationManager notificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
Showing a notification
1.Create a new Notification object using NotificationCompat.Builder.
2.Get a reference to the NotificationManager.
3.Show the notification.
Creating a basic notificationNotification notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_star_white_24dp) .setContentTitle("Hello world!") .setContentText("Description goes here.") .build();
NotificationManager notificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, notification);
Done.
Handling user interaction
Actions
User interact with a notification via:
1.Click on notification.
2.Action buttons. (Android >= 4.1)
Actions
User interact with a notification via:
1.Click on notification.
2.Action buttons. (Android >= 4.1)
Open related Activity
HOW?
Pending Intent
Pending Intent
Specifies an action to take in the future.
Pending Intent
Specifies an action to take in the future.
https://developer.android.com/reference/android/app/PendingIntent.html
● Wraps an Intent.
● Pass a future Intent to another component.
● Granting the right to perform the operation you have specified as if the other application was yourself (with the same permissions and identity).
Pending Intent
PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);
Pending Intent
PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);
Static factory method to get a PendingIntent
Pending Intent
PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);
Context
Pending Intent
PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);
Unique request code as int
Pending Intent
PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);
The “original” Intent object
Pending Intent
PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);
Instructions flag
Pending Intent exampleIntent intent = new Intent(this, LandingPageActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
User interaction #1Intent intent = new Intent(this, LandingPageActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_star_white_24dp) .setContentTitle("Hello world!") .setContentText("Description goes here.") .setContentIntent(pi)
.setAutoCancel(true) // Optional .build();
User interaction #2Notification notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_star_white_24dp) .setContentTitle("Hello world!") .setContentText("Description goes here.")
.setContentIntent(pi) .setAutoCancel(true) .addAction(R.drawable.ic_bookmark_white_24dp,
"BTN-1", pi) .addAction(R.drawable.ic_schedule_white_24dp,
"BTN-2", pi2) .addAction(R.drawable.ic_favorite_white_24dp,
"BTN-3", pi3) .build();
{
Action buttons
DO NOT forget the back-stack!
Not forgetting the back-stack
Activity
A(list)
*Click on item*
Not forgetting the back-stack
Activity
A(list)
Activity
B(Item details)*Back button clicked*
Not forgetting the back-stack
Activity
A(list)
Activity
B(Item details)
TaskStackBuilder demo #1TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);taskStackBuilder.addNextIntent(parentActivityIntent);taskStackBuilder.addNextIntent(intent);
PendingIntent pi = taskStackBuilder.getPendingIntent(REQUEST_CODE, PendingIntent.FLAG_UPDATE_CURRENT);
TaskStackBuilder demo #2Intent intent = new Intent(this, LandingPageActivity.class);
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);taskStackBuilder.addNextIntentWithParentStack(intent);
PendingIntent pi = taskStackBuilder.getPendingIntent(REQUEST_CODE,
PendingIntent.FLAG_UPDATE_CURRENT);
AndroidManifest.xml<activity android:name="com.yossisegev.myapplication.LandingPageActivity" android:parentActivityName="com.yossisegev.myapplication.MyParentActivity">
<!-- pre 4.1 --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.yossisegev.myapplication.MyParentActivity"/>
</activity>
Notification withExpanded layout
Expanded layout
Provide rich notification style. (Android >= 4.1)
Applied by specifying a style with .setStyle()
InboxStyle
InboxStyle notificationNotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();inboxStyle.setBigContentTitle("Shopping list reminder!");inboxStyle.addLine("Milk");inboxStyle.addLine("Bread");inboxStyle.addLine("Frozen pizza");inboxStyle.addLine("Pasta");inboxStyle.addLine("Water pack");inboxStyle.setSummaryText("+ 6 more items.");
Notification notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_star_white_24dp) .setContentTitle("Shopping list reminder!") .setContentText("....") .setContentIntent(pi) .setStyle(inboxStyle) .build();
BigPictureStyle
BigPictureStyle notificationNotificationCompat.BigPictureStyle pictureStyle = new NotificationCompat.BigPictureStyle();pictureStyle.bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.mountains));pictureStyle.setSummaryText("filename.jpeg");
Notification notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_star_white_24dp) .setContentTitle("Photo upload completed.") .setContentText("Click to view in app.") .setContentIntent(pi) .setStyle(pictureStyle) .build();
Not covered
Sound / LED / VibrateGroupingPriorityProgress indicatorCustom layouts
Questions?
Broadcast Receivers
BroadcastReceiver
Implementation of a Pub/Sub pattern.
Enables messaging between app components, Android system, and even other apps.
Pub/Sub
A Sender (broadcaster) sends messages.
Subscriber (receiver) register to receive messages.
Senders do not program which component (if any) receives the message.
Subscribers register to receive specific messages types.
Creating a Receiver
Creating a Receiver
1.Extend BroadcastReceiver.Implement the onReceive() method.
2.Register the receiver with an intent filter.Static or Dynamic registration.
Creating a Receiver
1.Extend BroadcastReceiver.Implement the onReceive() method.
2.Register the receiver with an intent filter.Static or Dynamic registration.
SimpleReceiver.javapublic class SimpleReceiver extends BroadcastReceiver {
public static final String ACTION_TOAST = "yossisegev.action.toast";
@Overridepublic void onReceive(Context context, Intent intent) { String message = "Got a " + intent.getAction(); Toast.makeText(context, message, Toast.LENGTH_SHORT).show();}}
Creating a Receiver
1.Extend BroadcastReceiver.Implement the onReceive() method.
2.Register the receiver with an intent filter.Static or Dynamic registration.
AndroidManifest.xml (Static registration)<receiver android:name="com.yossisegev.myapplication.recivers.SimpleReceiver">
<intent-filter>
<action android:name="yossisegev.action.toast" />
</intent-filter>
</receiver>
Sending the broadcast// Implicit intentIntent i = new Intent(SimpleReceiver.ACTION_TOAST);
sendBroadcast(i);
onReceive() is called.
ReceiverActivity (Dynamic registration)private SimpleReceiver simpleReceiver;
@Overrideprotected void onResume() { super.onResume(); simpleReceiver = new SimpleReceiver();}
@Overrideprotected void onPause() { super.onPause();}
ReceiverActivity (Dynamic registration)private SimpleReceiver simpleReceiver;
@Overrideprotected void onResume() { super.onResume(); simpleReceiver = new SimpleReceiver(); IntentFilter intentFilter = new IntentFilter(SimpleReceiver.ACTION_TOAST);}
@Overrideprotected void onPause() { super.onPause();}
ReceiverActivity (Dynamic registration)private SimpleReceiver simpleReceiver;
@Overrideprotected void onResume() { super.onResume(); simpleReceiver = new SimpleReceiver(); IntentFilter intentFilter = new IntentFilter(SimpleReceiver.ACTION_TOAST); registerReceiver(simpleReceiver, intentFilter);}
@Overrideprotected void onPause() { super.onPause(); unregisterReceiver(simpleReceiver);}
ReceiverActivity (Dynamic registration)private SimpleReceiver simpleReceiver;
@Overrideprotected void onResume() { super.onResume(); simpleReceiver = new SimpleReceiver(); IntentFilter intentFilter = new IntentFilter(SimpleReceiver.ACTION_TOAST); registerReceiver(simpleReceiver, intentFilter); Intent i = new Intent(SimpleReceiver.ACTION_TOAST); // Implicit intent sendBroadcast(i);}
@Overrideprotected void onPause() { super.onPause(); unregisterReceiver(simpleReceiver);}
Not covered
Security
Permissions
Local Broadcasts
Ordered Broadcasts
Intent-Filters in depth
Questions?
Services
Service
Perform long-running operations in the background, does not provide a user interface.
https://developer.android.com/guide/components/services.html
Service
(Usually) Runs as part of its app process.
By default- service code runs on the main thread.
A way for our app to do something even if the user isn’t interacting with it.
Can interact with other components (ex: Activity)
Services has a simpler lifecycle then Activities.
The paths are related to the way the service starts.
Service Lifecycle
Starting / Binding a Service
Context.bindService()
● onBind() callback will fire.
● Alive as long as stuff are bound to it.
Context.startService()
● onStartCommand() callback will fire.
● Alive until stopService() or stopSelf()
Creating a bound Service
Creating a bound Service
1.Create MyService class, extends Service.
2.Create Binder inner class.
3.Implement The ServiceConnection interface.
4.Register our Service in AndroidManifest.xml
5.Bind the Service.
Creating a bound Service
1.Create MyService class, extends Service.
2.Create Binder inner class.
3.Implement The ServiceConnection interface.
4.Register our Service in AndroidManifest.xml
5.Bind the Service.
MyService.javapublic class MyService extends Service {
private String mData = "Service data";
@Override public IBinder onBind(Intent intent) { //todo return our binder return null; }}
Creating a bound Service
1.Create MyService class, extends Service.
2.Create Binder inner class.
3.Implement The ServiceConnection interface.
4.Register our Service in AndroidManifest.xml
5.Bind the Service.
MyService.javapublic class MyService extends Service {
private String mData = "Service data"; private DataBinder mBinder;
// ...
public class DataBinder extends Binder { public String getData() { return mData; } } }
MyService.javapublic class MyService extends Service {
@Override public void onCreate() { super.onCreate(); mBinder = new DataBinder(); }
@Override public IBinder onBind(Intent intent) { return mBinder; } // ...}
Creating a bound Service
1.Create MyService class, extends Service.
2.Create Binder inner class.
3.Implement The ServiceConnection interface.
4.Register our Service in AndroidManifest.xml
5.Bind the Service.
ServiceConnection
Interface for monitoring the connection to a Service.Provides two call backs:
onServiceConnected(ComponentName name, IBinder binder)
onServiceDisconnected(ComponentName name)
ServiceDemoActivitypublic class ServiceDemoActivity extends Activity
implements ServiceConnection {
@Overridepublic void onServiceConnected(ComponentName name, IBinder binder) { MyService.DataBinder dataBinder = (MyService.DataBinder) binder; String serviceData = dataBinder.getData();}
@Overridepublic void onServiceDisconnected(ComponentName name) {
// Called when the Server stops unexpectedly. // NOT on unbind event.}}
Creating a bound Service
1.Create MyService class, extends Service.
2.Create Binder inner class.
3.Implement The ServiceConnection interface.
4.Register our Service in AndroidManifest.xml
5.Bind the Service.
AndroidManifest.xml<service
android:name="com.yossisegev.services.MyService” />
Creating a bound Service
1.Create MyService class, extends Service.
2.Create Binder inner class.
3.Implement The ServiceConnection interface.
4.Register our Service in AndroidManifest.xml
5.Bind the Service.
Binding the Service
bindService(Intent service,
ServiceConnection conn, int
flags);
unbindService(ServiceConnection conn);
ServiceDemoActivity@Overrideprotected void onResume() { super.onResume(); Intent i = new Intent(this, MyService.class); bindService(i, this, Context.BIND_AUTO_CREATE);}
@Overrideprotected void onPause() { super.onPause(); unbindService(this);}
Remember
When calling bindService() - onStartCommand() is skipped.
All Services must override onBind().Started Services can return null.
onCreate() / onDestroy() - always called.
Communicate with a Service
1.Intents passed to onBind() / onStartCommand()
2.Binding.
3.Broadcasts-Receivers.
4.Notifications / Toasts.
IntentService
IntentService
Handles requests on a worker thread , one by one, and stops when it’s out of work.
IntentService
Perfect for “one shot” operations.
Easy to implement.
Creating IntentService
1.Create MyIntentService class, extends IntetService.
2.Implement the constructor.
3.Implement onHandleIntent() method.
MyIntentService.javapublic class MyIntentService extends IntentService {
public MyIntentService() { super("myIntentService"); // This will be the worker thread name }
@Override protected void onHandleIntent(Intent intent) {
// Do some work... }
}
IntentService work queue
startService(Intent i1);
startService(Intent i2);
startService(Intent i3);
onCreate()
onHandleIntent(i1) onHandleIntent(i2) onHandleIntent(i3)
onDestory()
Not covered
Permissions.
Running Service on a different process.
Sticky Service.
Foreground Service.
Questions?
SyncAdapter
SyncAdapter
Handling the synchronization of data between the device and a server.
Why?
Maintaining communication with a server is hard.
When should I sync?
Authentication.
User change credentials on another device
Multiple user accounts
Error recovery.
Spotty network
Invalid credentials
What do we need?
What do we need?
● Account Authenticator Handles user
auth
What do we need?
● Account Authenticator Handles user
auth
● ContentProvider Stores the synced
data
What do we need?
● Account Authenticator Handles user
auth
● ContentProvider Stores the synced
data
● SyncAdapter Actually syncing and applying
logic
General flow
Local data store
Server
SyncAdapter
Account Authenticator
Creating our demo SyncAdapter
General flow
Local data store
Server
SyncAdapter
Account Authenticator
Our demo
Local data store
Server
SyncAdapter
Account Authenticator
FAKE
FAKE
What do we need?
● Account Authenticator Handles user
auth
● ContentProvider Stores the synced
data
● SyncAdapter Actually syncing and applying
logic
Authenticator
1.Extend AbstractAccountAuthenticator.
2.Create a bound service that will serve the authenticator.
3.Add a metadata xml file for the authenticator.
4.Add the service to AndroidManifest.Read more: http://developer.android.com/training/sync-adapters/creating-authenticator.html
Authenticator
1.Extend AbstractAccountAuthenticator.
2.Create a bound service that will serve the authenticator.
3.Add a metadata xml file for the authenticator.
4.Add the service to AndroidManifest.Read more: http://developer.android.com/training/sync-adapters/creating-authenticator.html
FakeAuthenticator.javapublic class FakeAuthenticator extends AbstractAccountAuthenticator {
public FakeAuthenticator(Context context) { super(context); }
// editProperties: throws an UnsupportedOperation Exception // addAccount: returns null // confirmCredentials: returns null // getAuthToken: throws an UnsupportedOperation Exception // getAuthTokenLabel: throws an UnsupportedOperation Exception // updateCredentials: throws an UnsupportedOperation Exception // hasFeatures: throws an UnsupportedOperation Exception // getAuthTokenLabel: throws an UnsupportedOperation Exception}
1.Extend AbstractAccountAuthenticator.
2.Create a bound service that will serve the Authenticator.
3.Add a metadata xml file for the authenticator.
4.Add the service to AndroidManifest.
Authenticator
Read more: http://developer.android.com/training/sync-adapters/creating-authenticator.html
FakeAuthenticatorService.javapublic class FakeAuthenticatorService extends Service {
private FakeAuthenticator mAuthenticator;
@Override public void onCreate() { super.onCreate(); mAuthenticator = new FakeAuthenticator(this); }
@Override public IBinder onBind(Intent intent) { return mAuthenticator.getIBinder(); }}
1.Extend AbstractAccountAuthenticator.
2.Create a bound service that will serve the Authenticator.
3.Add a metadata xml file for the authenticator.
4.Add the service to AndroidManifest.
Authenticator
Read more: http://developer.android.com/training/sync-adapters/creating-authenticator.html
authenticator.xml (in res/xml)<?xml version="1.0" encoding="utf-8"?><account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" android:accountType="com.yossisegev.demo" />
1.Extend AbstractAccountAuthenticator.
2.Create a bound service that will serve the Authenticator.
3.Add a metadata xml file for the authenticator.
4.Add the service to AndroidManifest.
Authenticator
Read more: http://developer.android.com/training/sync-adapters/creating-authenticator.html
AndroidManifest.xml<service android:name=".FakeAuthenticatorService">
<intent-filter> <action android:name="android.accounts.AccountAuthenticator"/> </intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" />
</service>
What do we need?
● Account Authenticator Handles user
auth
● ContentProvider Stores the synced
data
● SyncAdapter Actually syncing and applying
logic
ContentProvider
1.Create our fake ContentProvider class.
2.Create the AndroidManifest.xml entry.
AndroidManifest.xml<provider android:name=".provider.FakeContentProvider" android:authorities="com.yossisegev.demo.app.provider" android:enabled="true" android:exported="false" android:syncable="true" />
What do we need?
● Account Authenticator Handles user
auth
● ContentProvider Stores the synced
data
● SyncAdapter Actually syncing and applying
logic
SyncAdapter
1.Extend AbstractThreadedSyncAdapter.
2.Implement the onPerformSync() method.
3.Create a bound service that will serve the SyncAdapter.
4.Add a metadata xml file for the SyncAdapter.
5.Add the Service to AndroidManifest.Read more: https://developer.android.com/training/sync-adapters/creating-sync-adapter.html
SyncAdapter
1.Extend AbstractThreadedSyncAdapter.
2.Implement the onPerformSync() method.
3.Create a bound service that will serve the SyncAdapter.
4.Add a metadata xml file for the SyncAdapter.
5.Add the service to AndroidManifest.Read more: https://developer.android.com/training/sync-adapters/creating-sync-adapter.html
DemoSyncAdapter.javapublic class DemoSyncAdapter extends AbstractThreadedSyncAdapter {
private static final String TAG = "DemoSyncAdapter";
public DemoSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); } public DemoSyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) {
super(context, autoInitialize, allowParallelSyncs); }
}
SyncAdapter
1.Extend AbstractThreadedSyncAdapter.
2.Implement the onPerformSync() method.
3.Create a bound service that will serve the SyncAdapter.
4.Add a metadata xml file for the SyncAdapter.
5.Add the service to AndroidManifest.Read more: https://developer.android.com/training/sync-adapters/creating-sync-adapter.html
DemoSyncAdapter.javapublic class DemoSyncAdapter extends AbstractThreadedSyncAdapter {
@Overridepublic void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.d(TAG, "**** SYNCING ****");}
}
SyncAdapter
1.Extend AbstractThreadedSyncAdapter.
2.Implement the onPerformSync() method.
3.Create a bound service that will serve the SyncAdapter.
4.Add a metadata xml file for the SyncAdapter.
5.Add the service to AndroidManifest.Read more: https://developer.android.com/training/sync-adapters/creating-sync-adapter.html
DemoSyncService.javapublic class DemoSyncService extends Service {
private DemoSyncAdapter mDemoSyncAdapter;
@Override public void onCreate() { super.onCreate(); // The SyncAdapter instance *should* be created in a thread safe manner. mDemoSyncAdapter = new DemoSyncAdapter(getApplicationContext(), true); }}
DemoSyncService.javapublic class DemoSyncService extends Service {
@Overridepublic IBinder onBind(Intent intent) { return mDemoSyncAdapter.getSyncAdapterBinder();}
}
SyncAdapter
1.Extend AbstractThreadedSyncAdapter.
2.Implement the onPerformSync() method.
3.Create a bound service that will serve the SyncAdapter.
4.Add a metadata xml file for the SyncAdapter.
5.Add the service to AndroidManifest.Read more: https://developer.android.com/training/sync-adapters/creating-sync-adapter.html
syncadapter.xml (/res/xml)
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" android:contentAuthority="com.yossisegev.demo.app.provider" android:accountType="com.yossisegev.demo" android:userVisible="false" android:supportsUploading="false" android:allowParallelSyncs="false" android:isAlwaysSyncable="true" />
SyncAdapter
1.Extend AbstractThreadedSyncAdapter.
2.Implement the onPerformSync() method.
3.Create a bound service that will serve the SyncAdapter.
4.Add a metadata xml file for the SyncAdapter.
5.Add the service to AndroidManifest.Read more: https://developer.android.com/training/sync-adapters/creating-sync-adapter.html
AndroidManifest.xmlservice android:name=".DemoSyncService">
<intent-filter> <action android:name="android.content.SyncAdapter" /> </intent-filter> <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter" />
</service>
Done.
● Account Authenticator Handles user
auth
● ContentProvider Stores the synced
data
● SyncAdapter Actually syncing and applying
logic
Authenticator Service
authenticator.xml
How everything is tied together?
Authenticator
ContentProviderManifest entry
SyncAdapter Service
syncadapter.xml
SyncAdapter
accountType
contentAuthority
Invoking the SyncAdapter
Invoking the SyncAdapter
The ContentResolver (the one we use to access the ContentProvider)
is responsible for registering for the sync.
Syncing on demandContentResolver.requestSync(account, // Account to sync FakeContract.AUTHORITY, // authority bundle); // Sync options
Syncing on demand - bundleBundle bundle = new Bundle();// Forces a manual sync. The sync adapter framework ignores existing settings.bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
// Forces the sync to start immediatelybundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
ContentResolver.requestSync(account, FakeContract.AUTHORITY, bundle);
Not covered
Managing Accounts.
Raising sync errors.
Interval syncing.
Questions?
Thank you