Android Twitter and C2DM Explained

4,262 views
4,117 views

Published on

Presentation given on TechGig for Android Twitter Reference App and C2DM.

Published in: Education, Technology, Design
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,262
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
57
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Android Twitter and C2DM Explained

  1. 1. Android Twitter App and C2DM By Rohit Ghatol Architect @ QuickOffice
  2. 2. Speaker Introduction
  3. 3. Speaker Introduction• Rohit Ghatol• Architect @ QuickOffice• Proj Mgr @ Synerzip• Founder TechNext• Author “Beginning PhoneGap” @Apress• Technical Speaker and Corporate Trainer
  4. 4. Why Twitter App and C2DM in the same talk?
  5. 5. Poll Vs Push
  6. 6. Twitter App Demohttp://code.google.com/p/DroidTwitt
  7. 7. Youtube Video Demo• http://www.youtube.com/user/rohitssghatol# p/u/13/XhCZpxWDtx0
  8. 8. Twitter Requirements
  9. 9. Revisit Android Building Blocks in Short
  10. 10. Activity LifeCycleonCreate() onStart() onResume() Complete Visible Foreground Visible LifeCycle LifeCycle LifeCycle onPause() onStop()onDestroy()
  11. 11. Calling Service Activity Activity bindService(i foo(); startService(i ntent) bar(); ntent) Service Service void foo(){void onStartCommand }(Intent intent,…){ int bar(){} }
  12. 12. NetworkChange Broadcast Receivers Battery Custom Low App 1 Event 1 Custom Event 2 App 2 Android OS Interested in any of these Events. Roaming Your AppCall
  13. 13. Overall Architecture
  14. 14. OAuth Authentication
  15. 15. First Time Launch
  16. 16. Asking Service To Fetch Tweets
  17. 17. Triggering Service every n minutes
  18. 18. Phone Boot Event
  19. 19. Battery Low Event
  20. 20. OAuthShort Introduction to OAuth
  21. 21. http://fotofast.com http://fotofast.com Welcome Rohitusername Picasa Flickrpassword Login Cancel Print Photo
  22. 22. http://fotofast.com If I go to a restaurant, do Welcome Rohit I give my ATM Card and Enter Credentials for Pin to the waiter to pay Picasa my bills?usernamepassword Then Why should I give my Picasa Credentials to Login Cancel fotofast.com?
  23. 23. Take 2, Action
  24. 24. http://fotofast.com http://fotofast.com Welcome Rohitusername Picasa Flickrpassword Login Cancel Print Photo
  25. 25. http://picasa.com http://picasa.com Welcome to Picasa 1 2 3usernamepassword 4 5 6 Login Cancel Choose Album to Share with FotoFast Look Ma its Picasa itself asking for password!
  26. 26. http://fotofast.com Welcome Rohit Picasa Albums Look Ma! I am able to print picasa photos from FotoFast Choose photo to Print Photo
  27. 27. Twitter OAuth in Android
  28. 28. About OAuth• The way OAuth works for Web is Browser redirects between the 2 sites• Browser first shows FotoFast, which redirects you to Picasa to authenticate and approve sharing data with FotoFast• On proper Authentication and Approval, Browser takes you back to FotoFast.com
  29. 29. How does the same work for Android Applications?
  30. 30. Steps of Twitter OAuth
  31. 31. Step 1 : Register with Twitter for OAuth Token
  32. 32. Step 2: Register your Activity to handle url “DroidTwit://twitt”
  33. 33. <activity android:name=".OAuthLogin" android:label="@string/app_name” android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.VIEW"></action> <category android:name="android.intent.category.DEFAULT"></category> <category android:name="android.intent.category.BROWSABLE"></category> <data android:scheme="DroidTwit" android:host="twitt"></data> </intent-filter></activity>
  34. 34. Step 3: Create a OAuth URL and ask browser to show it OAuth URL also contains CallBack URL you URL can redirect back to your activity
  35. 35. public static final String CALLBACK_URL ="DroidTwitt://twitt";public void buttonClick(){ OAuthSignpostClient client = new OAuthSignpostClient (TWITTER_KEY, TWITTER_SECRET,CALLBACK_URL); final URI twitterUrl = client.authorizeUrl(); //Start Browser startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(twitterUrl.toString())));}
  36. 36. Step 4: Handle Response from Browser after OAuth
  37. 37. @Overrideprotected void onNewIntent(final Intent intent) { super.onNewIntent(intent); final Uri uri = intent.getData(); if ((uri != null) && uri.toString().startsWith(CALLBACK_URL)) { verifier = uri.getQueryParameter("oauth_verifier"); client.setAuthorizationCode(verifier); accessTokenAndSecret = client.getAccessToken(); Log.e("NewIntent", "Access token: " + accessTokenAndSecret[0]); Log.e("NewIntent", "Token secret: " + accessTokenAndSecret[1]); }}
  38. 38. For more details on Oauth in Android readhttp://blog.copyninja.info/2010/09/android-oauth-authentication-with.html
  39. 39. Fetching From Twitter API
  40. 40. Guidelines• Make the fetch module Synchronous List<Tweets> getLatestTweets();• Either call directly or through Services• Use AsyncTask on UI to avoid ANR
  41. 41. ListView Showing Tweets Lets see a some code for this.http://code.google.com/p/droidtwit/wiki/AndroidListActivityAsyncTaskTutorial
  42. 42. Need for List AdapterList View functionality is same Data that can vary 1 List<Tweet> 2 Adapter Layer Tweets 3 Something else 4 Layout can vary Entry 1
  43. 43. public class MyAdapter extends BaseAdapter{ public int getCount(){ } public Object getItem(int position){ } public long getItemId(int position){ } public View getView(int position,Convert view,..){ }}
  44. 44. Plank List View Explained 1 Plank No. 1 Entry 1 2 Entry 2 3 Entry 3 4 Entry 4
  45. 45. List View Explained 1 Entry 1 1 Plank No. 2 Entry 2 3 Plank 1 ReusedScroll Entry 3 when it pops out the top while 4 scrolling Entry 4 1 Entry 5
  46. 46. Thumbnails in ListViewCommon Problem and How to solve it
  47. 47. Why is thumbnail is such a problem in ListView? 1 Entry 1 Thread 1 Threads to fetch image asynchronously 2 Entry 2 Thread 2 3 Entry 3 Thread 3 4 Entry 4 Thread 4
  48. 48. Why is thumbnail is such a problem in ListView? Thread 5 1 Now Thread 1 returns Entry 5 Thread 1 image one and sets it on Plank 1, but Plank 1 should 2 show image from Entry 5. Entry 6 3 Wrong images are shown Entry 7 for Entry 5, till Thread 5 returns. 4 Entry 8 And for each scroll, again images are fetched
  49. 49. While Scrolling, we add Solutionentries in BlockingQueue 1 Entry 1 Thread 1 2 Thread reads from Blocking Entry 2 Queue, checks the Image 3 Cache, if Image not Entry 3 there, fetches it dumps in Image Cache and gives it to 4 the Image View (If position Entry 4 Blocking Queue is valid) Local Image Cache
  50. 50. Class Diagram<<ImageLoader>> <<ImageCache>>void queue(String url, ImageView void cache(String url, Bitmap bitmap);imageView); BitMap get(String url); PhotoToLoadUses BlockingQueue<PhotoToLoad> and private String url;has a thread which keeps running on the private ImageView imageView; BlockingQueue, to either fetch image from cache or from internet
  51. 51. Complete Example• The complete example of the QueuedImageLoader can be found http://code.google.com/p/feedreader/source/ browse/trunk/FifaLatestNews/src/com/latestn ews/cache/QueuedImageLoader.java
  52. 52. Using Services Lets see Code Demos for thisComplete Detailed Video of this is available onhttp://code.google.com/p/droidtwit/wiki/AndroidServiceTutorial
  53. 53. Using Alarm Manager Lets see Code Demo
  54. 54. Listener Battery Event Lets see Code Demo
  55. 55. C2DM
  56. 56. What is C2DM?Cloud To Device Messaging
  57. 57. What is C2DM?• Messages send from Server to Device via Google• Small Messages only meant to tell the client, that server has new information• Optimized and uses same channel as Gmail, Calendar and other google apps
  58. 58. Why C2DM?
  59. 59. Drawbacks of DroidTwitt
  60. 60. Battery Drain• Application launching every 5/10/15 mins• Not sure if we will get new information, blindly trying• Way to optimize is using AlarmManager.setInExactRepeating(), but that only helps so much
  61. 61. Data Usage• Polling means more use of Data• If Server is not optimized, then it always sends a chunk of stale data, more bandwidth• Ways to optimize is ask server to send data on top of what the client already has (say use the timestamp), but that only helps so much
  62. 62. Lag• Notification using Polling will always have a Lag• It ends up being a balancing act between Saving Battery and Freshness of the data
  63. 63. Traffic (Server Side)• Every device, Every n minutes bombarding the Server• Businesses won’t mind traffic as long it is adding real value. But is this real value?
  64. 64. Load (Server Side)• Hitting Database blindly when getting traffic• Servers need to optimized to know whether the polling requests will repeat very n minutes and they only hit database if they have change.
  65. 65. C2DM Players
  66. 66. Google Cloud Application ServerBut Remember a User can havemore than one Device!
  67. 67. C2DM Flow of Events
  68. 68. Google Cloud Security Token AppServer123Step 1: App Server goesAuthentication with GoogleC2DM Cloud and gets asecurity token Application Server
  69. 69. Google Cloud Security Token AppServer123Step 2: Device 1 Registersitself to Google C2DMCloud, gets an RegistrationId Application Server
  70. 70. Google Cloud Security Token AppServer123Step 3: Device 1 tells AppServer that its C2DM Reg Idis XYZ Application Server Device Info Reg Id Rohit’s Phone XYZ XYZ
  71. 71. Google Cloud Security Token AppServer123Step 4: App Server sendsmessage to C2DM intendedfor Device with Reg Id XYZ Application Server Device Info Reg Id Rohit’s Phone XYZ
  72. 72. Google Cloud Security Token AppServer123Step 6: Google C2DM CloudService sends Intent toDevice with Reg id XYZ Application Server Device Info Reg Id Rohit’s Phone XYZ
  73. 73. Google Cloud Security Token AppServer123Step 7: Device fetches datafrom App Server to process Application Server Device Info Reg Id Rohit’s Phone XYZ
  74. 74. C2DM DemoLets see the Demo
  75. 75. Steps for C2DM
  76. 76. Step 1: Create AVD for Emulator• Create a AVD With Google API 8 (not Android API 8)
  77. 77. Step 1: Create AVD for Emulator• Go to Settings and Add a Google Account
  78. 78. Step 2: Server Side Authentication Server Side//Create URL for Google Authentication for C2DM CodeStringBuilder builder = new StringBuilder();//Has to be C2DM Registered Email Address One Timebuilder.append("Email=").append(email);builder.append("&Passwd=").append(password);builder.append("&accountType=GOOGLE");builder.append("&source=MyLittleExample");builder.append("&service=ac2dm");byte[] data = builder.toString().getBytes();
  79. 79. Step 2: Server Side Authentication Server Side// Setup the Http Post CodeURL url = new URL("https://www.google.com/accounts/ClientLogin");HttpURLConnection con = (HttpURLConnection) url.openConnection(); Time One……con.setRequestMethod("POST");con.setRequestProperty("Content-Type”, "application/x-www-form-urlencoded");con.setRequestProperty("Content-Length", Integer.toString(data.length));
  80. 80. Step 2: Server Side Authentication Server Side// Issue the HTTP POST request CodeOutputStream output = con.getOutputStream();output.write(data); One Timeoutput.close();//Read Auth Token ResponseBufferedReader reader = new BufferedReader(new InputStreamReader( con.getInputStream()));String line = null, auth_key = null;while ((line = reader.readLine()) != null) { if (line.startsWith("Auth=")) { auth_key = line.substring(5); }}
  81. 81. Step 3: Android Manifest Android<manifest xmlns:android="http://schemas.android.com/apk/res/android" Code package="com.sparklytix.factoreal" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <permission android:name="com.sparklytix.factoreal.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.sparklytix.factoreal.permission.C2D_MESSAGE" /> <uses-permissionandroid:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="android.permission.INTERNET" />
  82. 82. Step 3: Android Manifest Android<receiver android:name=".receivers.C2DMBroadCastReceiver” Code android:permission="com.google.android.c2dm.permission.SEND"> <!-- Receive the actual message --> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="com.sparklytix.factoreal" /> </intent-filter> <!-- Receive the registration id --> <intent-filter> <action android:name="com.google.android.c2dm.intent.REGISTRATION"/> <category android:name="com.sparklytix.factoreal" /> </intent-filter></receiver>
  83. 83. Step 4: Send C2DM Device Reg Req Androidpublic void register(Context context, String sender) { Code Intent intent = new Intent ("com.google.android.c2dm.intent.REGISTER"); //app is this application itself intent.putExtra("app", PendingIntent.getBroadcast(context, 0, new Intent(), 0)); //sender is typical gmail account on the device intent.putExtra("sender”,sender); context.startService(intent); }
  84. 84. Step 5: Get Device Reg Id Androidpublic void onReceive(Context context, Intent intent) { Code if(“com.google.android.c2dm.intent.REGISTRATION”.equals(intent.getAction()){ final String registrationId = intent.getStringExtra("registration_id"); String error = intent.getStringExtra("error"); if (intent.getStringExtra("error") != null) { // Registration failed, should try again later. } else if (intent.getStringExtra("unregistered") != null) { //Remove Reg Id from Our Application Server } else if (registrationId != null) { //Send Reg Id to Our Application Server Broadcast } Receiver }}
  85. 85. Step 6: Send Message from Server Server SideStringBuilder postDataBuilder = new StringBuilder(); CodepostDataBuilder.append(“registration_id”).append("=”).append (registrationId);postDataBuilder.append("&").append(“collapse_key”).append("=") .append("0");postDataBuilder.append("&").append("data.payload").append("=") .append(URLEncoder.encode(message, UTF8));byte[] postData = postDataBuilder.toString().getBytes(UTF8);
  86. 86. Step 6: Send Message from Server Server Side CodeURL url = new URL("https://android.clients.google.com/c2dm/send");HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();....conn.setRequestMethod("POST");conn.setRequestProperty("Content-Type“,"application/x-www-form-urlencoded;charset=UTF-8");conn.setRequestProperty("Content-Length",Integer.toString(postData.length));conn.setRequestProperty("Authorization", "GoogleLogin auth=" + auth_token);OutputStream out = conn.getOutputStream();out.write(postData);out.close();
  87. 87. Step 7: Receive Message at Android Androidpublic void onReceive(Context context, Intent intent) { Code if(“com.google.android.c2dm.intent.RECEIVE”.equals(intent.getAction()){ String payload = intent.getStringExtra("payload"); //Create a Notification and fire it }} Broadcast Receiver
  88. 88. Conclusion• C2DM is an excellent way to – Reduce Data Usage and Save Battery on the Device – And also reduce load and network contingency on the Server – Also when device goes offline, Our App Server does not have to queue, Google C2DM queues itself• Definitely a better option than Polling
  89. 89. Detailed Tutorial• http://www.vogella.de/articles/AndroidCloudT oDeviceMessaging/article.html• http://code.google.com/p/android-c2dm- reference-impl/
  90. 90. Code Projects referred• Droid Twitt Project - http://code.google.com/p/droidtwitt• Android Code Examples – http://code.google.com/p/droidtwitt• Listing Thumbnails in ListView - http://code.google.com/p/feedreader/• C2DM Server and Android App - http://code.google.com/p/android-c2dm- reference-impl/
  91. 91. Q&A
  92. 92. More about Me• Twitter - http://twitter.com/#!/rohitghatol• TechGig - http://www.techgig.com/rohitghatol• LinkedIn - http://www.linkedin.com/in/rohitghatol• Presentations - www.slideshare.net/rohitsghatol/• YouTube Tutorials - http://www.youtube.com/user/rohitssghatol

×