session #8 adding magic to your app

148
Adding magic to your app #8 Android Academy TLV 25/12/2016 Yossi Segev Wifi: Techiteasy

Upload: vitali-pekelis

Post on 14-Apr-2017

72 views

Category:

Software


5 download

TRANSCRIPT

Page 1: Session #8  adding magic to your app

Adding magic to your app

#8Android Academy TLV

25/12/2016Yossi Segev

Wifi: Techiteasy

Page 2: Session #8  adding magic to your app

Yossi Segev

Crave

Android Academy

Page 3: Session #8  adding magic to your app

Jonathan Yarkoni

Android Developer & Advocate Ironsource

Android Academy Staff

Yonatan LevinGoogle Developer

Expert & Android @ Gett

Britt BarakAndroid Lead

Figure8

Yossi SegevAndroid Developer

Crave

Page 4: Session #8  adding magic to your app

Announcement!

Page 5: Session #8  adding magic to your app

Shahar AvigezerDesigner & Developer

Page 6: Session #8  adding magic to your app

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

Page 7: Session #8  adding magic to your app

Community Mentors

Ilan Peled

Page 8: Session #8  adding magic to your app

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”.

Page 9: Session #8  adding magic to your app

We’ve got a LOT to cover - take a deep breath :)

Page 10: Session #8  adding magic to your app

Notifications

Page 11: Session #8  adding magic to your app

Notification

A message you can display to the user outside of the application UI.

Page 12: Session #8  adding magic to your app

Notification

Must contain:● Small Notification

icon● Title● Description

Page 13: Session #8  adding magic to your app

Showing a notification

1.Create a new Notification object using NotificationCompat.Builder.

2.Get a reference to the NotificationManager.

3.Show the notification.

Page 14: Session #8  adding magic to your app

1.Create a new Notification object using NotificationCompat.Builder.

2.Get a reference to the NotificationManager.

3.Show the notification.

Showing a notification

Page 15: Session #8  adding magic to your app

NotificationCompat.Builder

Fluent interface to construct Notification object.

Helps maintain backward compatibility.

Page 16: Session #8  adding magic to your app

Creating a basic notificationNotification notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_star_white_24dp) .setContentTitle("Hello world!") .setContentText("Description goes here.") .build();

Page 17: Session #8  adding magic to your app

1.Create a new Notification object using NotificationCompat.Builder.

2.Get a reference to the NotificationManager.

3.Show the notification.

Showing a notification

Page 18: Session #8  adding magic to your app

Notification Manager

One of many system-level services.

Access by calling getSystemService().

https://developer.android.com/reference/android/app/NotificationManager.html

Page 19: Session #8  adding magic to your app

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)

Page 20: Session #8  adding magic to your app

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

Page 21: Session #8  adding magic to your app

Showing a notification

1.Create a new Notification object using NotificationCompat.Builder.

2.Get a reference to the NotificationManager.

3.Show the notification.

Page 22: Session #8  adding magic to your app

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

Page 23: Session #8  adding magic to your app

Done.

Page 24: Session #8  adding magic to your app

Handling user interaction

Page 25: Session #8  adding magic to your app

Actions

User interact with a notification via:

1.Click on notification.

2.Action buttons. (Android >= 4.1)

Page 26: Session #8  adding magic to your app

Actions

User interact with a notification via:

1.Click on notification.

2.Action buttons. (Android >= 4.1)

Open related Activity

HOW?

Page 27: Session #8  adding magic to your app

Pending Intent

Page 28: Session #8  adding magic to your app

Pending Intent

Specifies an action to take in the future.

Page 29: Session #8  adding magic to your app

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).

Page 30: Session #8  adding magic to your app

Pending Intent

PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);

Page 31: Session #8  adding magic to your app

Pending Intent

PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);

Static factory method to get a PendingIntent

Page 32: Session #8  adding magic to your app

Pending Intent

PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);

Context

Page 33: Session #8  adding magic to your app

Pending Intent

PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);

Unique request code as int

Page 34: Session #8  adding magic to your app

Pending Intent

PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);

The “original” Intent object

Page 35: Session #8  adding magic to your app

Pending Intent

PendingIntent.getActivity(this, REQUEST_CODE, intent, flags);

Instructions flag

Page 36: Session #8  adding magic to your app

Pending Intent exampleIntent intent = new Intent(this, LandingPageActivity.class);

PendingIntent pi = PendingIntent.getActivity(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);

Page 37: Session #8  adding magic to your app

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

Page 38: Session #8  adding magic to your app

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

{

Page 39: Session #8  adding magic to your app

Action buttons

Page 40: Session #8  adding magic to your app

DO NOT forget the back-stack!

Page 41: Session #8  adding magic to your app

Not forgetting the back-stack

Activity

A(list)

*Click on item*

Page 42: Session #8  adding magic to your app

Not forgetting the back-stack

Activity

A(list)

Activity

B(Item details)*Back button clicked*

Page 43: Session #8  adding magic to your app

Not forgetting the back-stack

Activity

A(list)

Activity

B(Item details)

Page 44: Session #8  adding magic to your app

TaskStackBuilder demo #1TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(this);taskStackBuilder.addNextIntent(parentActivityIntent);taskStackBuilder.addNextIntent(intent);

PendingIntent pi = taskStackBuilder.getPendingIntent(REQUEST_CODE, PendingIntent.FLAG_UPDATE_CURRENT);

Page 45: Session #8  adding magic to your app

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

Page 46: Session #8  adding magic to your app

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>

Page 47: Session #8  adding magic to your app

Notification withExpanded layout

Page 48: Session #8  adding magic to your app

Expanded layout

Provide rich notification style. (Android >= 4.1)

Applied by specifying a style with .setStyle()

Page 49: Session #8  adding magic to your app

InboxStyle

Page 50: Session #8  adding magic to your app

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

Page 51: Session #8  adding magic to your app

BigPictureStyle

Page 52: Session #8  adding magic to your app

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

Page 53: Session #8  adding magic to your app

Not covered

Sound / LED / VibrateGroupingPriorityProgress indicatorCustom layouts

Page 54: Session #8  adding magic to your app

Questions?

Page 55: Session #8  adding magic to your app

Broadcast Receivers

Page 56: Session #8  adding magic to your app

BroadcastReceiver

Implementation of a Pub/Sub pattern.

Enables messaging between app components, Android system, and even other apps.

Page 57: Session #8  adding magic to your app

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.

Page 58: Session #8  adding magic to your app

Creating a Receiver

Page 59: Session #8  adding magic to your app

Creating a Receiver

1.Extend BroadcastReceiver.Implement the onReceive() method.

2.Register the receiver with an intent filter.Static or Dynamic registration.

Page 60: Session #8  adding magic to your app

Creating a Receiver

1.Extend BroadcastReceiver.Implement the onReceive() method.

2.Register the receiver with an intent filter.Static or Dynamic registration.

Page 61: Session #8  adding magic to your app

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

Page 62: Session #8  adding magic to your app

Creating a Receiver

1.Extend BroadcastReceiver.Implement the onReceive() method.

2.Register the receiver with an intent filter.Static or Dynamic registration.

Page 63: Session #8  adding magic to your app

AndroidManifest.xml (Static registration)<receiver android:name="com.yossisegev.myapplication.recivers.SimpleReceiver">

<intent-filter>

<action android:name="yossisegev.action.toast" />

</intent-filter>

</receiver>

Page 64: Session #8  adding magic to your app

Sending the broadcast// Implicit intentIntent i = new Intent(SimpleReceiver.ACTION_TOAST);

sendBroadcast(i);

Page 65: Session #8  adding magic to your app

onReceive() is called.

Page 66: Session #8  adding magic to your app

ReceiverActivity (Dynamic registration)private SimpleReceiver simpleReceiver;

@Overrideprotected void onResume() { super.onResume(); simpleReceiver = new SimpleReceiver();}

@Overrideprotected void onPause() { super.onPause();}

Page 67: Session #8  adding magic to your app

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

Page 68: Session #8  adding magic to your app

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

Page 69: Session #8  adding magic to your app

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

Page 70: Session #8  adding magic to your app

Not covered

Security

Permissions

Local Broadcasts

Ordered Broadcasts

Intent-Filters in depth

Page 71: Session #8  adding magic to your app

Questions?

Page 72: Session #8  adding magic to your app

Services

Page 73: Session #8  adding magic to your app

Service

Perform long-running operations in the background, does not provide a user interface.

https://developer.android.com/guide/components/services.html

Page 74: Session #8  adding magic to your app

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)

Page 75: Session #8  adding magic to your app

Services has a simpler lifecycle then Activities.

The paths are related to the way the service starts.

Service Lifecycle

Page 76: Session #8  adding magic to your app

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

Page 77: Session #8  adding magic to your app

Creating a bound Service

Page 78: Session #8  adding magic to your app

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.

Page 79: Session #8  adding magic to your app

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.

Page 80: Session #8  adding magic to your app

MyService.javapublic class MyService extends Service {

private String mData = "Service data";

@Override public IBinder onBind(Intent intent) { //todo return our binder return null; }}

Page 81: Session #8  adding magic to your app

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.

Page 82: Session #8  adding magic to your app

MyService.javapublic class MyService extends Service {

private String mData = "Service data"; private DataBinder mBinder;

// ...

public class DataBinder extends Binder { public String getData() { return mData; } } }

Page 83: Session #8  adding magic to your app

MyService.javapublic class MyService extends Service {

@Override public void onCreate() { super.onCreate(); mBinder = new DataBinder(); }

@Override public IBinder onBind(Intent intent) { return mBinder; } // ...}

Page 84: Session #8  adding magic to your app

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.

Page 85: Session #8  adding magic to your app

ServiceConnection

Interface for monitoring the connection to a Service.Provides two call backs:

onServiceConnected(ComponentName name, IBinder binder)

onServiceDisconnected(ComponentName name)

Page 86: Session #8  adding magic to your app

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.}}

Page 87: Session #8  adding magic to your app

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.

Page 88: Session #8  adding magic to your app

AndroidManifest.xml<service

android:name="com.yossisegev.services.MyService” />

Page 89: Session #8  adding magic to your app

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.

Page 90: Session #8  adding magic to your app

Binding the Service

bindService(Intent service,

ServiceConnection conn, int

flags);

unbindService(ServiceConnection conn);

Page 91: Session #8  adding magic to your app

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

Page 92: Session #8  adding magic to your app

Remember

When calling bindService() - onStartCommand() is skipped.

All Services must override onBind().Started Services can return null.

onCreate() / onDestroy() - always called.

Page 93: Session #8  adding magic to your app

Communicate with a Service

1.Intents passed to onBind() / onStartCommand()

2.Binding.

3.Broadcasts-Receivers.

4.Notifications / Toasts.

Page 94: Session #8  adding magic to your app

IntentService

Page 95: Session #8  adding magic to your app

IntentService

Handles requests on a worker thread , one by one, and stops when it’s out of work.

Page 96: Session #8  adding magic to your app

IntentService

Perfect for “one shot” operations.

Easy to implement.

Page 97: Session #8  adding magic to your app

Creating IntentService

1.Create MyIntentService class, extends IntetService.

2.Implement the constructor.

3.Implement onHandleIntent() method.

Page 98: Session #8  adding magic to your app

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... }

}

Page 99: Session #8  adding magic to your app

IntentService work queue

startService(Intent i1);

startService(Intent i2);

startService(Intent i3);

onCreate()

onHandleIntent(i1) onHandleIntent(i2) onHandleIntent(i3)

onDestory()

Page 100: Session #8  adding magic to your app

Not covered

Permissions.

Running Service on a different process.

Sticky Service.

Foreground Service.

Page 101: Session #8  adding magic to your app

Questions?

Page 102: Session #8  adding magic to your app

SyncAdapter

Page 103: Session #8  adding magic to your app
Page 104: Session #8  adding magic to your app

SyncAdapter

Handling the synchronization of data between the device and a server.

Page 105: Session #8  adding magic to your app

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

Page 106: Session #8  adding magic to your app

What do we need?

Page 107: Session #8  adding magic to your app

What do we need?

● Account Authenticator Handles user

auth

Page 108: Session #8  adding magic to your app

What do we need?

● Account Authenticator Handles user

auth

● ContentProvider Stores the synced

data

Page 109: Session #8  adding magic to your app

What do we need?

● Account Authenticator Handles user

auth

● ContentProvider Stores the synced

data

● SyncAdapter Actually syncing and applying

logic

Page 110: Session #8  adding magic to your app

General flow

Local data store

Server

SyncAdapter

Account Authenticator

Page 111: Session #8  adding magic to your app

Creating our demo SyncAdapter

Page 112: Session #8  adding magic to your app

General flow

Local data store

Server

SyncAdapter

Account Authenticator

Page 113: Session #8  adding magic to your app

Our demo

Local data store

Server

SyncAdapter

Account Authenticator

FAKE

FAKE

Page 114: Session #8  adding magic to your app

What do we need?

● Account Authenticator Handles user

auth

● ContentProvider Stores the synced

data

● SyncAdapter Actually syncing and applying

logic

Page 115: Session #8  adding magic to your app

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

Page 116: Session #8  adding magic to your app

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

Page 117: Session #8  adding magic to your app

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}

Page 118: Session #8  adding magic to your app

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

Page 119: Session #8  adding magic to your app

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

Page 120: Session #8  adding magic to your app

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

Page 121: Session #8  adding magic to your app

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" />

Page 122: Session #8  adding magic to your app

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

Page 123: Session #8  adding magic to your app

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>

Page 124: Session #8  adding magic to your app

What do we need?

● Account Authenticator Handles user

auth

● ContentProvider Stores the synced

data

● SyncAdapter Actually syncing and applying

logic

Page 125: Session #8  adding magic to your app

ContentProvider

1.Create our fake ContentProvider class.

2.Create the AndroidManifest.xml entry.

Page 126: Session #8  adding magic to your app

AndroidManifest.xml<provider android:name=".provider.FakeContentProvider" android:authorities="com.yossisegev.demo.app.provider" android:enabled="true" android:exported="false" android:syncable="true" />

Page 127: Session #8  adding magic to your app

What do we need?

● Account Authenticator Handles user

auth

● ContentProvider Stores the synced

data

● SyncAdapter Actually syncing and applying

logic

Page 128: Session #8  adding magic to your app

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

Page 129: Session #8  adding magic to your app

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

Page 130: Session #8  adding magic to your app

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

}

Page 131: Session #8  adding magic to your app

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

Page 132: Session #8  adding magic to your app

DemoSyncAdapter.javapublic class DemoSyncAdapter extends AbstractThreadedSyncAdapter {

@Overridepublic void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {

Log.d(TAG, "**** SYNCING ****");}

}

Page 133: Session #8  adding magic to your app

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

Page 134: Session #8  adding magic to your app

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

Page 135: Session #8  adding magic to your app

DemoSyncService.javapublic class DemoSyncService extends Service {

@Overridepublic IBinder onBind(Intent intent) { return mDemoSyncAdapter.getSyncAdapterBinder();}

}

Page 136: Session #8  adding magic to your app

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

Page 137: Session #8  adding magic to your app

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" />

Page 138: Session #8  adding magic to your app

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

Page 139: Session #8  adding magic to your app

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>

Page 140: Session #8  adding magic to your app

Done.

● Account Authenticator Handles user

auth

● ContentProvider Stores the synced

data

● SyncAdapter Actually syncing and applying

logic

Page 141: Session #8  adding magic to your app

Authenticator Service

authenticator.xml

How everything is tied together?

Authenticator

ContentProviderManifest entry

SyncAdapter Service

syncadapter.xml

SyncAdapter

accountType

contentAuthority

Page 142: Session #8  adding magic to your app

Invoking the SyncAdapter

Page 143: Session #8  adding magic to your app

Invoking the SyncAdapter

The ContentResolver (the one we use to access the ContentProvider)

is responsible for registering for the sync.

Page 144: Session #8  adding magic to your app

Syncing on demandContentResolver.requestSync(account, // Account to sync FakeContract.AUTHORITY, // authority bundle); // Sync options

Page 145: Session #8  adding magic to your app

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

Page 146: Session #8  adding magic to your app

Not covered

Managing Accounts.

Raising sync errors.

Interval syncing.

Page 147: Session #8  adding magic to your app

Questions?

Page 148: Session #8  adding magic to your app

Thank you