{"__v":50,"_id":"56ba6b96984f030d00713aeb","category":{"__v":2,"_id":"563d411de79f670d00a10a5f","pages":["56bad1cbf60d630d006885b3","56bad3e4959bd90d00afb079"],"project":"55f0757d4624ec2d00814345","version":"55f0b2b5f3735d0d00691ffe","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-11-07T00:09:01.516Z","from_sync":false,"order":4,"slug":"android-sdk","title":"Android SDK"},"parentDoc":null,"project":"55f0757d4624ec2d00814345","user":"55f0756a1e63fc37004b8d2b","version":{"__v":9,"_id":"55f0b2b5f3735d0d00691ffe","project":"55f0757d4624ec2d00814345","createdAt":"2015-09-09T22:29:09.118Z","releaseDate":"2015-09-09T22:29:09.118Z","categories":["55f0b2b5f3735d0d00691fff","55f0b2b5f3735d0d00692000","55f0b2b5f3735d0d00692001","55f0bd67d5d8fc0d00ca6f44","55f0cde9d5d8fc0d00ca6f55","563a8a62a8ba320d00106830","563a8ac9a8ba320d00106832","563d410f31f7580d00511e53","563d411de79f670d00a10a5f","563d412a31f7580d00511e54","566a206f74d574170070b640"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.0.0","version":"2"},"updates":["56d6d93947f18a2d0088d668"],"next":{"pages":[],"description":""},"createdAt":"2016-02-09T22:43:34.880Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":0,"body":"The Android SDK is a quick way to integrate secure messaging within a native Android app. This quick start guide will help you get the SDK added to your project.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"We are working to put together a Android demo app but in the meantime, if you have any questions, don't hesitate to [Contact Us](mailto:developersupport:::at:::tigertext.com?Subject=Android%20SDK%20Help).  \\n\\nCheck out the SDK here:\\n<a href=\\\"https://github.com/tigerconnect/android-sdk-release\\\" target=\\\"_blank\\\">https://github.com/tigerconnect/android-sdk-release</a>\",\n  \"title\": \"Do you have a Android demo app?\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Installation\"\n}\n[/block]\nTo setup and initiate the Android SDK, follow the following setup steps.  First, download the latest version TigerConnect Android SDK. The SDK itself is not open source, however we currently host the <a href=\"https://github.com/tigerconnect/android-sdk-release\" target=\"_blank\">AAR here</a>.  We will move to supporting simple imports via gradle and such soon.\n\nIn your project's base directory, create a folder called ttandroid and place the ttandroid.aar inside. Then add a build.gradle file with:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"configurations.create(\\\"default\\\")\\nartifacts.add(\\\"default\\\", file('ttandroid-2.0.0.aar'))\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nYour directory structure should then look something like the following:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"build.gradle\\nsettings.gradle\\n...\\nYOUR_APP/\\n         build.gradle\\n         src/\\n         ...\\nttandroid/\\n          ttandroid.aar\\n          build.gradle\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nNext, add the ttandroid module to your settings.gradle.  Note: you only need to add the *':ttandroid', your settings.gradle should already be including your application module.*\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"include ':app', ':ttandroid'\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nUntil we publish to an artifact repository soon, you will need to manually add the dependencies of the ttandroid.aar since AAR's don't (by default) come with their dependencies bundled.\n\nOpen your app's build.gradle (YOUR_APP/build.gradle in this case) and add these lines, this includes the instruction for compiling the 'ttandroid.aar' as well as the items for multidexing (as it will be necessary).  You will also need some flavor of the support v4 library.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"android {\\n    ...\\n\\n    defaultConfig {\\n        ...\\n        multiDexEnabled true\\n    }\\n    dexOptions {\\n        incremental false\\n        javaMaxHeapSize \\\"4g\\\"\\n    }\\n}\\n\\ndependencies {\\n    ...\\n    compile project(':ttandroid')\\n    compile 'de.greenrobot:eventbus:2.4.0'\\n    compile 'io.netty:netty-all:4.0.25.Final'\\n    compile 'com.parse.bolts:bolts-android:1.1.3'\\n    compile 'com.android.support:multidex:1.0.1'\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nNext will be to add our Content Provider to your AndroidManifest.xml.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<provider\\n    android:name=\\\".ttandroid.provider.TigerTextContentProvider\\\"\\n    android:authorities=\\\"CHOOSE_AN_AUTHORITY_STRING\\\"\\n    android:exported=\\\"false\\\"\\n    android:multiprocess=\\\"false\\\" />\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nYou can use any string for the CHOOSE_AN_AUTHORITY_STRING portion. One suggestion is to use your package name and append .tc to the end (but it's really up to you), example.  Note what is used, as you will need it to initialize the SDK.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"android:authorities=\\\"your.package.name.tc\\\"\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nYour project should now be able to compile with everything set up.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Initialization\"\n}\n[/block]\n##MultiDex\nSince you will likely be needing to turn have multidex on (as described above), the lease pervasive way to get multidex going with your application is to add the code below to your Application class.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class MyApplication extends Application {\\n    @Override\\n    protected void attachBaseContext(Context baseContext) {\\n        super.attachBaseContext(baseContext);\\n        MultiDex.install(baseContext);\\n    }\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nThere are other ways to go about multidex, all of which can be found [here](http://developer.android.com/tools/building/multidex.html).\n\n##Initialize the SDK\n1.  Create an Application class in your project.\n2.  Instantiate TT.java in Application class’s onCreate() method.  The authority is actually the authority for the ContentProvider so, usually is the application package\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class MyApplication extends Application {\\n\\n    @Override\\n    public void onCreate() {\\n        super.onCreate();\\n        TT.init(getApplicationContext(), AUTHORITY_CHOSEN_FOR_CONTENT_PROVIDER);\\n    }\\n\\n     @Override\\n    protected void attachBaseContext(Context baseContext) {\\n        super.attachBaseContext(baseContext);\\n        MultiDex.install(baseContext);\\n    }\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Logging In\"\n}\n[/block]\nOnce the Android SDK is initialized, you will be able to login using the Account Manager object.  Note: Remember not to use the manager directly, but to leverage the instance.  \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"import com.tigertext.ttandroid.User;\\nimport com.tigertext.ttandroid.account.TigerTextAccountManager;\\nimport com.tigertext.ttandroid.account.listener.LoginListener;\\nimport com.tigertext.ttandroid.api.TT;\\n\\n...\\n// get username (String) and password(String) via input\\n...\\n\\npublic void function doLogin(String username, String password) {\\n    TigerTextAccountManager accountManager = TT.getInstance().getAccountManager();\\n        accountManager.login(username, password, new LoginListener() {\\n            @Override\\n            public void onLoggedIn(User user) {\\n                // handle logged in User\\n            }\\n\\n            @Override\\n            public void onLoginError(Throwable throwable) {\\n                // handle log in error\\n            }\\n        });\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nAfter logging in and before interacting further with the SDK, you will want to sync data with the TigerText backend.  Syncing pulls down everything necessary for the account logged in to start interacting fully with the user's organizations, conversations, etc.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"TT.getInstance().sync(new TT.SyncListener() {\\n    @Override\\n    public void onSyncComplete() {\\n        // sync successful, continue using the sdk\\n        // otherwise you will want to prompt the user to try\\n        // and re-sync\\n    }\\n\\n    @Override\\n    public void onSyncFailed(Throwable throwable) {\\n        // handle sync failed\\n    }\\n});\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nGetting realtime pull / push going is pretty straightforward. Simply add TT.onStart() and TT.onStop() calls at the times that your application comes to the foreground (after a user is authenticated of course) and when the application goes into the background. One way to achieve this is via [Activity Lifecycle Callbacks](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html) registered within your Application class.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Logging Out\"\n}\n[/block]\nTo stop receiving messages for a particular user and to cut off the connection with the server, be sure to log out of the Android SDK.  While the platform does a good job of cleaning up open resources, it is always good housekeeping to logout when the client does not want to show incoming messages.  \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"TT.getInstance().getAccountManager().logout();\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Getting Conversations\"\n}\n[/block]\nAfter authenticating, the SDK will fetch all the recent conversations associated with the user and persist them in our local datastore.  Assuming that the SDK has been properly initialized and “synced”, this is the way you load your roster.\n\n1.  The Android SDK leverages Loader objects in order to show relevant data including your roster and conversations.  You will need to first create a Loader for your roster in your Activity.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Setup you listView\\nlistView.setAdapter(mAdapter);\\n\\n// Somewhere in your InboxActivity init the loader\\ngetLoaderManager().initLoader(ROSTER_LOADER_ID, null, this);\\nListView listView = getListView();\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n2.  Implement the RosterLoader - the RosterLoader is a component of the SDK that returns all the information required for an inbox.  There’re some other filtering options that can limit the search to accounts or groups but typically the Inbox usually needs “ROSTERLOADER_ALL\" which includes everything.  \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Implementation of the LoaderCallback\\n@Override\\npublic Loader<Cursor> onCreateLoader(final int id, final Bundle args) {\\n\\t\\n  // RosterLoader is a component that returns all the information required for an inbox\\n\\tif(id == ROSTER_LOADER_ID) {\\n    return new RosterLoader(context, mActivityInteractions.getCurrentOrganizationId(), RosterLoader.ROSTERLOADER_ALL);\\n  }\\n\\n\\t// Your default implementation for loader not found…\\n  return new RosterLoader(context, mActivityInteractions.getCurrentOrganizationId(), RosterLoader.ROSTERLOADER_ALL);\\n}\\n\\n@Override\\npublic void onLoadFinished(Loader<Cursor> loader, Cursor data) {\\n\\t\\n  // Once roster loader finished looking for the information, you can populate your adapter with all the information, Note that at this point you can port the data directly into a ListView with a CursorAdapter\\n  mAdapter.swapCursor(data);\\n}\\n\\n@Override\\npublic void onLoaderReset(Loader<Cursor> loader) {\\n  mAdapter.swapCursor(null);\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n3.  Populate the listView - In your implementation of the CursorLoader you’ll get the chance to populate the listView.  \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class InboxContactsCursorAdapter extends CursorAdapter implements View.OnClickListener {\\n  \\n  public InboxContactsCursorAdapter(Context context) {\\n    super(context, null, false);\\n  }\\n  \\n  @Override\\n  public View newView(final Context context, final Cursor cursor, final ViewGroup parent) {\\n    // TODO: Create your own view…\\n    return view;\\n  }\\n  \\n  @Override\\n  public void bindView(final View view, final Context context, final Cursor cursor) {\\n    // TODO: Populate the view with the information linked to that position\\n\\t\\t// There’s a convenient class that helps you convert the “cursor” data into\\n\\t\\t// a java object with all the info required in the inbox for 1 row\\n\\n\\t\\tRosterEntry entry = RosterEntry.fromCursor(cursor);\\n\\n\\t\\t//At this point you should be able to get all the data available from the entry object as shown below\\n\\t\\tMessage message = entry.getLatestMessage();\\n\\t\\tString messageBody = message.getBody();\\n\\t\\tmessageBodyTextView.setText(messageBody);\\n\\t\\t//Assign message to TextView\\n  }\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n4.  Populating a Conversation:  Very similar to the Roster, there’s a loader for Conversations called “ConversationLoader” which has the same mechanics as described above.  There’s a “Message.fromCursor” method where you can get everything regarding a conversation. You don’t have to worry about populating new messages, the Loaders have observers ready to notify the loaders immediately any changes happening in the database, hence, if there’s a new message you will get a callback in your LoaderCallback.onLoadFinished with the new data.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Sending a Message\"\n}\n[/block]\nThere are several ways to send a message. The following snippet is one way to send a message.  Note: that the mTTL is measured in milliseconds vs. seconds.    \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mConversationManager = TT.getInstance().getConversationManager();\\nMessage message = Message.messageForSend(mOutgoingMessage, mRosterEntry, mTTL, null, null, mDOR);\\nmConversationManager.sendMessage(message);\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]","excerpt":"A quick guide to the TigerConnect Android SDK.","slug":"android-quick-start","type":"basic","title":"Quick Start Guide"}

Quick Start Guide

A quick guide to the TigerConnect Android SDK.

The Android SDK is a quick way to integrate secure messaging within a native Android app. This quick start guide will help you get the SDK added to your project. [block:callout] { "type": "info", "body": "We are working to put together a Android demo app but in the meantime, if you have any questions, don't hesitate to [Contact Us](mailto:developersupport@tigertext.com?Subject=Android%20SDK%20Help). \n\nCheck out the SDK here:\n<a href=\"https://github.com/tigerconnect/android-sdk-release\" target=\"_blank\">https://github.com/tigerconnect/android-sdk-release</a>", "title": "Do you have a Android demo app?" } [/block] [block:api-header] { "type": "basic", "title": "Installation" } [/block] To setup and initiate the Android SDK, follow the following setup steps. First, download the latest version TigerConnect Android SDK. The SDK itself is not open source, however we currently host the <a href="https://github.com/tigerconnect/android-sdk-release" target="_blank">AAR here</a>. We will move to supporting simple imports via gradle and such soon. In your project's base directory, create a folder called ttandroid and place the ttandroid.aar inside. Then add a build.gradle file with: [block:code] { "codes": [ { "code": "configurations.create(\"default\")\nartifacts.add(\"default\", file('ttandroid-2.0.0.aar'))", "language": "java" } ] } [/block] Your directory structure should then look something like the following: [block:code] { "codes": [ { "code": "build.gradle\nsettings.gradle\n...\nYOUR_APP/\n build.gradle\n src/\n ...\nttandroid/\n ttandroid.aar\n build.gradle", "language": "java" } ] } [/block] Next, add the ttandroid module to your settings.gradle. Note: you only need to add the *':ttandroid', your settings.gradle should already be including your application module.* [block:code] { "codes": [ { "code": "include ':app', ':ttandroid'", "language": "java" } ] } [/block] Until we publish to an artifact repository soon, you will need to manually add the dependencies of the ttandroid.aar since AAR's don't (by default) come with their dependencies bundled. Open your app's build.gradle (YOUR_APP/build.gradle in this case) and add these lines, this includes the instruction for compiling the 'ttandroid.aar' as well as the items for multidexing (as it will be necessary). You will also need some flavor of the support v4 library. [block:code] { "codes": [ { "code": "android {\n ...\n\n defaultConfig {\n ...\n multiDexEnabled true\n }\n dexOptions {\n incremental false\n javaMaxHeapSize \"4g\"\n }\n}\n\ndependencies {\n ...\n compile project(':ttandroid')\n compile 'de.greenrobot:eventbus:2.4.0'\n compile 'io.netty:netty-all:4.0.25.Final'\n compile 'com.parse.bolts:bolts-android:1.1.3'\n compile 'com.android.support:multidex:1.0.1'\n}", "language": "java" } ] } [/block] Next will be to add our Content Provider to your AndroidManifest.xml. [block:code] { "codes": [ { "code": "<provider\n android:name=\".ttandroid.provider.TigerTextContentProvider\"\n android:authorities=\"CHOOSE_AN_AUTHORITY_STRING\"\n android:exported=\"false\"\n android:multiprocess=\"false\" />", "language": "java" } ] } [/block] You can use any string for the CHOOSE_AN_AUTHORITY_STRING portion. One suggestion is to use your package name and append .tc to the end (but it's really up to you), example. Note what is used, as you will need it to initialize the SDK. [block:code] { "codes": [ { "code": "android:authorities=\"your.package.name.tc\"", "language": "java" } ] } [/block] Your project should now be able to compile with everything set up. [block:api-header] { "type": "basic", "title": "Initialization" } [/block] ##MultiDex Since you will likely be needing to turn have multidex on (as described above), the lease pervasive way to get multidex going with your application is to add the code below to your Application class. [block:code] { "codes": [ { "code": "public class MyApplication extends Application {\n @Override\n protected void attachBaseContext(Context baseContext) {\n super.attachBaseContext(baseContext);\n MultiDex.install(baseContext);\n }\n}", "language": "java" } ] } [/block] There are other ways to go about multidex, all of which can be found [here](http://developer.android.com/tools/building/multidex.html). ##Initialize the SDK 1. Create an Application class in your project. 2. Instantiate TT.java in Application class’s onCreate() method. The authority is actually the authority for the ContentProvider so, usually is the application package [block:code] { "codes": [ { "code": "public class MyApplication extends Application {\n\n @Override\n public void onCreate() {\n super.onCreate();\n TT.init(getApplicationContext(), AUTHORITY_CHOSEN_FOR_CONTENT_PROVIDER);\n }\n\n @Override\n protected void attachBaseContext(Context baseContext) {\n super.attachBaseContext(baseContext);\n MultiDex.install(baseContext);\n }\n}", "language": "java" } ] } [/block] [block:api-header] { "type": "basic", "title": "Logging In" } [/block] Once the Android SDK is initialized, you will be able to login using the Account Manager object. Note: Remember not to use the manager directly, but to leverage the instance. [block:code] { "codes": [ { "code": "import com.tigertext.ttandroid.User;\nimport com.tigertext.ttandroid.account.TigerTextAccountManager;\nimport com.tigertext.ttandroid.account.listener.LoginListener;\nimport com.tigertext.ttandroid.api.TT;\n\n...\n// get username (String) and password(String) via input\n...\n\npublic void function doLogin(String username, String password) {\n TigerTextAccountManager accountManager = TT.getInstance().getAccountManager();\n accountManager.login(username, password, new LoginListener() {\n @Override\n public void onLoggedIn(User user) {\n // handle logged in User\n }\n\n @Override\n public void onLoginError(Throwable throwable) {\n // handle log in error\n }\n });\n}", "language": "java" } ] } [/block] After logging in and before interacting further with the SDK, you will want to sync data with the TigerText backend. Syncing pulls down everything necessary for the account logged in to start interacting fully with the user's organizations, conversations, etc. [block:code] { "codes": [ { "code": "TT.getInstance().sync(new TT.SyncListener() {\n @Override\n public void onSyncComplete() {\n // sync successful, continue using the sdk\n // otherwise you will want to prompt the user to try\n // and re-sync\n }\n\n @Override\n public void onSyncFailed(Throwable throwable) {\n // handle sync failed\n }\n});", "language": "java" } ] } [/block] Getting realtime pull / push going is pretty straightforward. Simply add TT.onStart() and TT.onStop() calls at the times that your application comes to the foreground (after a user is authenticated of course) and when the application goes into the background. One way to achieve this is via [Activity Lifecycle Callbacks](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html) registered within your Application class. [block:api-header] { "type": "basic", "title": "Logging Out" } [/block] To stop receiving messages for a particular user and to cut off the connection with the server, be sure to log out of the Android SDK. While the platform does a good job of cleaning up open resources, it is always good housekeeping to logout when the client does not want to show incoming messages. [block:code] { "codes": [ { "code": "TT.getInstance().getAccountManager().logout();", "language": "java" } ] } [/block] [block:api-header] { "type": "basic", "title": "Getting Conversations" } [/block] After authenticating, the SDK will fetch all the recent conversations associated with the user and persist them in our local datastore. Assuming that the SDK has been properly initialized and “synced”, this is the way you load your roster. 1. The Android SDK leverages Loader objects in order to show relevant data including your roster and conversations. You will need to first create a Loader for your roster in your Activity. [block:code] { "codes": [ { "code": "// Setup you listView\nlistView.setAdapter(mAdapter);\n\n// Somewhere in your InboxActivity init the loader\ngetLoaderManager().initLoader(ROSTER_LOADER_ID, null, this);\nListView listView = getListView();", "language": "java" } ] } [/block] 2. Implement the RosterLoader - the RosterLoader is a component of the SDK that returns all the information required for an inbox. There’re some other filtering options that can limit the search to accounts or groups but typically the Inbox usually needs “ROSTERLOADER_ALL" which includes everything. [block:code] { "codes": [ { "code": "// Implementation of the LoaderCallback\n@Override\npublic Loader<Cursor> onCreateLoader(final int id, final Bundle args) {\n\t\n // RosterLoader is a component that returns all the information required for an inbox\n\tif(id == ROSTER_LOADER_ID) {\n return new RosterLoader(context, mActivityInteractions.getCurrentOrganizationId(), RosterLoader.ROSTERLOADER_ALL);\n }\n\n\t// Your default implementation for loader not found…\n return new RosterLoader(context, mActivityInteractions.getCurrentOrganizationId(), RosterLoader.ROSTERLOADER_ALL);\n}\n\n@Override\npublic void onLoadFinished(Loader<Cursor> loader, Cursor data) {\n\t\n // Once roster loader finished looking for the information, you can populate your adapter with all the information, Note that at this point you can port the data directly into a ListView with a CursorAdapter\n mAdapter.swapCursor(data);\n}\n\n@Override\npublic void onLoaderReset(Loader<Cursor> loader) {\n mAdapter.swapCursor(null);\n}", "language": "java" } ] } [/block] 3. Populate the listView - In your implementation of the CursorLoader you’ll get the chance to populate the listView. [block:code] { "codes": [ { "code": "public class InboxContactsCursorAdapter extends CursorAdapter implements View.OnClickListener {\n \n public InboxContactsCursorAdapter(Context context) {\n super(context, null, false);\n }\n \n @Override\n public View newView(final Context context, final Cursor cursor, final ViewGroup parent) {\n // TODO: Create your own view…\n return view;\n }\n \n @Override\n public void bindView(final View view, final Context context, final Cursor cursor) {\n // TODO: Populate the view with the information linked to that position\n\t\t// There’s a convenient class that helps you convert the “cursor” data into\n\t\t// a java object with all the info required in the inbox for 1 row\n\n\t\tRosterEntry entry = RosterEntry.fromCursor(cursor);\n\n\t\t//At this point you should be able to get all the data available from the entry object as shown below\n\t\tMessage message = entry.getLatestMessage();\n\t\tString messageBody = message.getBody();\n\t\tmessageBodyTextView.setText(messageBody);\n\t\t//Assign message to TextView\n }\n}", "language": "java" } ] } [/block] 4. Populating a Conversation: Very similar to the Roster, there’s a loader for Conversations called “ConversationLoader” which has the same mechanics as described above. There’s a “Message.fromCursor” method where you can get everything regarding a conversation. You don’t have to worry about populating new messages, the Loaders have observers ready to notify the loaders immediately any changes happening in the database, hence, if there’s a new message you will get a callback in your LoaderCallback.onLoadFinished with the new data. [block:api-header] { "type": "basic", "title": "Sending a Message" } [/block] There are several ways to send a message. The following snippet is one way to send a message. Note: that the mTTL is measured in milliseconds vs. seconds. [block:code] { "codes": [ { "code": "mConversationManager = TT.getInstance().getConversationManager();\nMessage message = Message.messageForSend(mOutgoingMessage, mRosterEntry, mTTL, null, null, mDOR);\nmConversationManager.sendMessage(message);", "language": "java" } ] } [/block]