Top Banner
57

Android chat in the cloud

May 10, 2015

Download

Technology

firenze-gtug

Android chat in the cloud

Alfredo Morresi - Mobile & Embedded - 12 febbraio 2014 GDG Firenze
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Android chat in the cloud
Page 2: Android chat in the cloud

Alfredo MorresiDeveloper Relations @ Google

Android chat in the cloudRESTful APIs, authentication, push notifications and some additional goodies

Page 3: Android chat in the cloud

ROLE

Developer Relations Program Manager

COUNTRY

Italy

PASSIONS

Community, Development, Snowboarding, Tiramisu'

REACH ME

[email protected]/+AlfredoMorresi@rainbowbreeze

Alfredo Morresi

Who I am

Page 4: Android chat in the cloud

Download from https://play.google.com/store/apps/details?id=org.alexismp.cloud.backend

Let’s start with the chat demo app

Page 5: Android chat in the cloud

In less than 40 minutes?

Page 6: Android chat in the cloud

Forget about the backend!

Page 7: Android chat in the cloud

Use Google Cloud Platform + Mobile Backend Starter

Optional server-side coding: Control your cloud service using Android and iOS client libraries.

Cloud Datastore: Store millions of objects in the cloud and manage them from your app.

Push Notifications: Send and broadcast objects as messages via Apple Push Notifications and Google Cloud Messaging.

Event Driven Programming: Create real-time interactive user experiences using Continuous Queries.

User authentication: Authenticate users using Google Accounts and control access on private data.

Built to scale: Mobile backend runs on App Engine infrastructure to scale to millions of users within hours.

Page 8: Android chat in the cloud

https://developers.google.com/cloud/samples/mbs

Create your backend

Page 9: Android chat in the cloud

Create your backend

Page 10: Android chat in the cloud

Create your backend

Page 11: Android chat in the cloud

Create your backend

Page 12: Android chat in the cloud

http://goo.gl/0FLRPp

Download Android app source code

Page 13: Android chat in the cloud

Change● PROJECT_ID● PROJECT_NUMBER● WEB_CLIENT_ID

Set some values in the source and you’ve done!

Page 14: Android chat in the cloud
Page 15: Android chat in the cloud

Step 1Accessing to the APIs

Page 16: Android chat in the cloud

Google Cloud Endpoints: generate APIs from annotations

https://developers.google.com/appengine/docs/java/endpoints/

Page 17: Android chat in the cloud

Explore the APIs:http://<YOUR_PROJECT_ID>.appspot.com/_ah/api/explorer

Explore the backend APIs

Page 18: Android chat in the cloud

Set Open authentication in the backend

Page 19: Android chat in the cloud

Set the Consts.IS_AUTH_ENABLED to false

Set the Consts.PROJECT_ID to

Access to RESTful APIs, no authentication

Page 20: Android chat in the cloud

It was easy!

Page 21: Android chat in the cloud

Google Cloud Endpoints automatically generates the Android code required to access the backend APIs

Mobilebackend.Builder builder = new Mobilebackend.Builder( AndroidHttp.newCompatibleTransport(), new GsonFactory(), null);

Mobilebackend backend = builder.setRootUrl(Consts.ENDPOINT_ROOT_URL).build();

Access to RESTful APIs, no authentication

Page 22: Android chat in the cloud

Insert a new CloudEntity in the backend

CloudEntity post = new CloudEntity("Guestbook");post.put("message", "Your message here...");

EntityDto resultEntityDto = backend.endpointV1() .insert(post.getKindName(), post.getEntityDto()).execute();

CloudEntity resultCo = CloudEntity.createCloudEntityFromEntityDto(resultEntityDto);

Log.i(Consts.TAG, "insert: inserted: " + resultCo);

Access to RESTful APIs, no authentication

Page 23: Android chat in the cloud

Step 2Accessing to the APIs with authentication

Page 24: Android chat in the cloud

Restrict the API access only to your application(s).

ANDROID Client_ID: identifies your app in unique way (package name + SHA1 of signing key of the app)

WEB Client_ID: establishes that the client and the server are from the same developer so the standard OAuth2 prompt is avoided (no 3rd party app). It’s a shared token.

https://developers.google.com/appengine/docs/java/endpoints/auth

Authenticated access to the APIs

Page 25: Android chat in the cloud

Generate Android Client ID

Page 26: Android chat in the cloud

Generate Android Client ID

Page 27: Android chat in the cloud

Generate Web Client ID

Page 28: Android chat in the cloud

Generate Web Client ID

Page 29: Android chat in the cloud

Set Android and Web Client IDs in the backend

Page 30: Android chat in the cloud

Set the Consts.IS_AUTH_ENABLED to true

Set the Consts.WEB_CLIENT_ID to Web Client ID

Authenticated access to the APIs

Page 31: Android chat in the cloud
Page 32: Android chat in the cloud

GoogleAccountCredential credential = GoogleAccountCredential.usingAudience( getActivity(), Consts.AUTH_AUDIENCE);

if (credential.getSelectedAccountName() == null) { startActivityForResult( credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);

String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);credential.setSelectedAccountName(accountName);

https://developers.google.com/appengine/docs/java/endpoints/consume_android#Java_Making_authenticated_calls

The Android client provides credentials!

Page 33: Android chat in the cloud

Inject the credential in the backend manager class

// check if credential has account namefinal GoogleAccountCredential gac = credential == null || credential.getSelectedAccountName() == null ? null : mCredential;

// create HttpRequestInitializerHttpRequestInitializer httpRequestInitializer = new HttpRequestInitializer() { @Override public void initialize(HttpRequest request) throws IOException { if (gac != null) { gac.initialize(request); } }};

Authenticated access to the APIs

Page 34: Android chat in the cloud

Mobilebackend.Builder builder = new Mobilebackend.Builder( AndroidHttp.newCompatibleTransport(), new GsonFactory(), httpRequestInitializer);

Mobilebackend backend = builder.setRootUrl(Consts.ENDPOINT_ROOT_URL).build();

… Now the API backend framework automatically authenticates the user and enforces the authorized clientIds whitelist, ultimately by supplying a valid User to the API parameters.

Authenticated access to the APIs

Page 35: Android chat in the cloud

Step 3Add push notifications

Page 36: Android chat in the cloud
Page 37: Android chat in the cloud

Google Cloud Messaging for Android

http://developer.android.com/google/gcm/index.html

Page 38: Android chat in the cloud

Enable GCM in the project

Page 39: Android chat in the cloud

Generate a Server API Key

Page 40: Android chat in the cloud

Generate a Server API Key

Page 41: Android chat in the cloud

Enable GCM in the backend

Page 42: Android chat in the cloud

Set the Consts.PROJECT_NUMBER to

Enable GCM in the client

Page 43: Android chat in the cloud
Page 44: Android chat in the cloud

http://developer.android.com/google/gcm/client.html

Register your app and store registration ID

String regId = getRegIdFromPref();if (registrationId.isEmpty()) { regid = GoogleCloudMessaging.getInstance(context) .register(PROJECT_ID); storeRegIdToPref(regId);}

A look into GCM client code

Page 45: Android chat in the cloud

@Overridepublic void onReceive(Context context, Intent intent) { // Explicitly specify that GcmIntentService will handle the intent ComponentName comp = new ComponentName( context.getPackageName(), GCMIntentService.class.getName()); // Start service, keeping the device awake while it is launching startWakefulService(context, (intent.setComponent(comp))); setResultCode(Activity.RESULT_OK);}

Create a BroadcastReceiver to receive push messages

Page 46: Android chat in the cloud

protected void onHandleIntent(Intent intent) { Bundle extras = intent.getExtras(); GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); String msgType = gcm.getMessageType(intent);

if (extras.isEmpty()) { // has effect of unparcelling Bundle … } if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { … } // Release the wake lock provided by the WakefulBroadcastReceiver. GCMBroadcastReceiver.completeWakefulIntent(intent);}

Handle the message with a Service

Page 47: Android chat in the cloud

And remember to...

App registration is a network operation

Page 48: Android chat in the cloud

Bonus StepApp internal architecture

Page 49: Android chat in the cloud

EntityDto resultEntityDto = backend.endpointV1() .insert(post.getKindName(), post.getEntityDto()).execute();

Because API calls are slow...

Page 50: Android chat in the cloud

Never forget!

Page 51: Android chat in the cloud

// create a response handler that will receive the result or an errorCloudCallbackHandler<List<CloudEntity>> handler = new CloudCallbackHandler<List<CloudEntity>>() { @Override public void onComplete(List<CloudEntity> results) { ... }

@Override public void onError(IOException exception) { ... }

CloudBackendASync extends CloudBackend

Page 52: Android chat in the cloud

// execute the query with the handlermProcessingFragment.getCloudBackend().listByKind( "Guestbook", CloudEntity.PROP_CREATED_AT, Order.DESC, 50, Scope.FUTURE_AND_PAST, handler);

CloudBackendASync extends CloudBackend

Page 53: Android chat in the cloud

Why these two classes?

Separate the logic (CloudBackend) from the sync management (CloudBackendAsync) makes the code more testable!

Page 54: Android chat in the cloud

// Check to see if we have retained the fragment which handles asynchronous backend callsmProcessingFragment = (CloudBackendFragment) mFragmentManager. findFragmentByTag(PROCESSING_FRAGMENT_TAG);// If not retained (or first time running), create a new oneif (mProcessingFragment == null) { mProcessingFragment = new CloudBackendFragment(); mProcessingFragment.setRetainInstance(true); fragmentTransaction.add(mProcessingFragment, PROCESSING_FRAGMENT_TAG);}…// execute the insertion with the handlermProcessingFragment.getCloudBackend().insert(newPost, handler);mMessageTxt.setEnabled(false);mSendBtn.setEnabled(false);

Activity lifecycle (you can do better!)

Page 55: Android chat in the cloud

CloudEntity post = new CloudEntity("Guestbook");post.put("message", "Your message here...");post.put("alf_property", "Custom property value here...");

EntityDto resultEntityDto = backend.endpointV1() .insert(post.getKindName(), post.getEntityDto()).execute();

CloudEntity resultCo = CloudEntity.createCloudEntityFromEntityDto(resultEntityDto);

Extends the data

Page 56: Android chat in the cloud

https://developersitalia.blogspot.com

Curious about Google dev initiatives and event in Italy?

Page 57: Android chat in the cloud

Thank you!http://developers.google.com

Alfredo Morresiplus.google.com/+AlfredoMorresi@rainbowbreeze