• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Android chat in the cloud
 

Android chat in the cloud

on

  • 7,378 views

Android chat in the cloud

Android chat in the cloud

Alfredo Morresi - Mobile & Embedded - 12 febbraio 2014 GDG Firenze

Statistics

Views

Total Views
7,378
Views on SlideShare
7,022
Embed Views
356

Actions

Likes
0
Downloads
16
Comments
0

3 Embeds 356

http://mj89sp3sau2k7lj1eg3k40hkeppguj6j-a-sites-opensocial.googleusercontent.com 354
http://plus.url.google.com 1
http://www.slideee.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Android chat in the cloud Android chat in the cloud Presentation Transcript

    • Android chat in the cloud RESTful APIs, authentication, push notifications and some additional goodies Alfredo Morresi Developer Relations @ Google
    • Who I am Alfredo Morresi ROLE Developer Relations Program Manager COUNTRY Italy PASSIONS Community, Development, Snowboarding, Tiramisu' REACH ME alfredomorresi@google.com plus.google.com/+AlfredoMorresi @rainbowbreeze
    • Let’s start with the chat demo app Download from https://play.google.com/store/apps/details?id=org.alexismp.cloud.backend
    • In less than 40 minutes?
    • Forget about the backend!
    • 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.
    • Create your backend https://developers.google.com/cloud/samples/mbs
    • Create your backend
    • Create your backend
    • Create your backend
    • Download Android app source code http://goo.gl/0FLRPp
    • Set some values in the source and you’ve done! Change ● ● ● PROJECT_ID PROJECT_NUMBER WEB_CLIENT_ID
    • Step 1 Accessing to the APIs
    • Google Cloud Endpoints: generate APIs from annotations https://developers.google.com/appengine/docs/java/endpoints/
    • Explore the backend APIs Explore the APIs: http://<YOUR_PROJECT_ID>.appspot.com/_ah/api/explorer
    • Set Open authentication in the backend
    • Access to RESTful APIs, no authentication Set the Consts.IS_AUTH_ENABLED to false Set the Consts.PROJECT_ID to
    • It was easy!
    • Access to RESTful APIs, no authentication 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 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);
    • Step 2 Accessing to the APIs with authentication
    • Authenticated access to the APIs 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
    • Generate Android Client ID
    • Generate Android Client ID
    • Generate Web Client ID
    • Generate Web Client ID
    • Set Android and Web Client IDs in the backend
    • Authenticated access to the APIs Set the Consts.IS_AUTH_ENABLED to true Set the Consts.WEB_CLIENT_ID to Web Client ID
    • The Android client provides credentials! 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_aut henticated_calls
    • Authenticated access to the APIs Inject the credential in the backend manager class // check if credential has account name final GoogleAccountCredential gac = credential == null || credential.getSelectedAccountName() == null ? null : mCredential; // create HttpRequestInitializer HttpRequestInitializer httpRequestInitializer = new HttpRequestInitializer() { @Override public void initialize(HttpRequest request) throws IOException { if (gac != null) { gac.initialize(request); } } };
    • Authenticated access to the APIs 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.
    • Step 3 Add push notifications
    • Google Cloud Messaging for Android http://developer.android.com/google/gcm/index.html
    • Enable GCM in the project
    • Generate a Server API Key
    • Generate a Server API Key
    • Enable GCM in the backend
    • Enable GCM in the client Set the Consts.PROJECT_NUMBER to
    • A look into GCM client code 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); }
    • Create a BroadcastReceiver to receive push messages @Override public 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); }
    • Handle the message with a Service 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); }
    • And remember to... App registration is a network operation
    • Bonus Step App internal architecture
    • Because API calls are slow... EntityDto resultEntityDto = backend.endpointV1() .insert(post.getKindName(), post.getEntityDto()).execute();
    • Never forget!
    • CloudBackendASync extends CloudBackend // create a response handler that will receive the result or an error CloudCallbackHandler<List<CloudEntity>> handler = new CloudCallbackHandler<List<CloudEntity>>() { @Override public void onComplete(List<CloudEntity> results) { ... } @Override public void onError(IOException exception) { ... }
    • CloudBackendASync extends CloudBackend // execute the query with the handler mProcessingFragment.getCloudBackend().listByKind( "Guestbook", CloudEntity.PROP_CREATED_AT, Order.DESC, 50, Scope.FUTURE_AND_PAST, handler);
    • Why these two classes? Separate the logic (CloudBackend) from the sync management (CloudBackendAsync) makes the code more testable!
    • Activity lifecycle (you can do better!) // Check to see if we have retained the fragment which handles asynchronous backend calls mProcessingFragment = (CloudBackendFragment) mFragmentManager. findFragmentByTag(PROCESSING_FRAGMENT_TAG); // If not retained (or first time running), create a new one if (mProcessingFragment == null) { mProcessingFragment = new CloudBackendFragment(); mProcessingFragment.setRetainInstance(true); fragmentTransaction.add(mProcessingFragment, PROCESSING_FRAGMENT_TAG); } … // execute the insertion with the handler mProcessingFragment.getCloudBackend().insert(newPost, handler); mMessageTxt.setEnabled(false); mSendBtn.setEnabled(false);
    • Extends the data 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);
    • Curious about Google dev initiatives and event in Italy? https://developersitalia.blogspot.com
    • Thank you! http://developers.google.com Alfredo Morresi plus.google.com/+AlfredoMorresi @rainbowbreeze