From d9f4956fa50266008116ee10acba27c5e3a636f5 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Thu, 25 Oct 2018 16:58:31 +0300 Subject: [PATCH 01/24] Update README.md --- README.md | 356 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 295 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 8ed31dc..247b9e3 100755 --- a/README.md +++ b/README.md @@ -6,10 +6,56 @@ This SDK simplifies the integration of Africa's Talking APIs into your Android a the SDK is split into two components: A **server** module that stores API keys, SIP credentials and other secrets. And a **client** module that runs in your app. This client module gets secrets from the server component (via RPC), and uses them to interact with the various APIs. -For instance, to send an SMS, the client with request a token from the server; The server will use it's API key to request a token from Africa's Talking on behalf of the client. It will then forward the token to the client which will use it to request the SMS API to send a text. All in a split second! +For instance, to send an SMS, the client will request a token from the server; The server will use it's API key to request a token from Africa's Talking on behalf of the client. It will then forward the token to the client which will use it to request the SMS API to send a text. All in a split second! -### Usage +## Usage + +### 1. Server +You can code your server using android studio, eclipse or any other IDE you may deem fit. + +Whichever IDE you choose to work with, the following need to be done. + +#### a. Download dependencies + +If you are using android studio (with gradle dependencies), add the following code snippet in your build.gradle file (Module: your_server's_module_name) + +```groovy +repositories { + maven { + url "http://dl.bintray.com/africastalking/java" + } +} +dependencies{ + compile 'com.africastalking:server:VERSION' +} +``` +If you are using Eclipse IDE, or you use Maven dependencies instead, add this code snipppet in your Maven dependencies. + +Maven (from `http://dl.bintray.com/africastalking/java`) + +```xml + + com.africastalking + server + VERSION + +``` + +#### b. Add server side code + +First, import the following library classes in the class you've created to run the server. + +```Java + + import com.africastalking.AfricasTalking; + import com.africastalking.Server; + + import java.io.IOException; + +``` + +Now put this Java code in the class you've created to run your server. Your server application could be something like this: @@ -20,6 +66,16 @@ import com.africastalking.*; public class SomeJavaApplication { + //Save your credentials in static final variables + private static final String USERNAME = "your_username"; //Use "sandbox" if you are testing + + //You can generate this for testing in your Africa's Talking account. + //go to https://account.africastalking.com/apps/sandbox/settings/key + private static final String API_KEY = "your_API_KEY"; + + //Optional + private static final int port = "your_server's_port_number"; + public static void main(String[] args) { // Initialize the SDK @@ -32,81 +88,47 @@ public class SomeJavaApplication { server.addSipCredentials(SIP_USERNAME, SIP_PASSWORD, SIP_HOST); // Start the server - server.start(); + try{ + server.startInsecure(); + + //Use this if you have provided a port + server.startInsecure(port); + + //Please see the Advanced section for a list of other functions you can use to start your server + } catch (IOException e){ + + //Do something if server doesn't start + } } } ``` -And your Android app: +You may need to add the following code snippet just after **server.startInsecure()**, to ensure your server stays alive until you terminate it (Only add this if you run the above code and the server stops prematurely). For a server set to serve a production application, this may not be necessary. -```java -/* On The Client (Android) */ -public class SomeActivity extends Activity { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(args); - setContentView(R.layout.some_activity); - - // Init SDK - AfricasTalking.initialize(SERVER_HOSTNAME); - - // Get Service - AirtimeService airtime = AfricasTalking.getAirtimeService(); - - // Use Service - airtime.send("+25467675655", "KES", 100, new Callback() { - @Override - void onSuccess(AirtimeResponses responses) { - //... - } - - @Override - void onError(Throwable throwable) { - //... - } - }); - } -} +``` +//A loop to help us keep our server online until we terminate it + System.out.println("Press ENTER to exit"); + System.in.read(); ``` -See the [example](./example) for complete sample apps (Android, Web Java+Node) +**NOTE** You are not restricted to use Java to code your server. You can instead use Node.js, PHP, C/C++, C#, and all languages supported by gRPC. -### Download +Visit this link to get the Africa's Talking Node.js and PHP SDKs to see a template of how your server should look like in Node.js or PHP. -#### Server +https://github.com/AfricasTalkingLtd/africastalking-node.js -**Node** +https://github.com/AfricasTalkingLtd/africastalking-php -```shell -npm install --save africastalking -``` +This is enough to run your simple server. Now to the android app. -**Java** - -```groovy -repositories { - maven { - url "http://dl.bintray.com/africastalking/java" - } -} -dependencies{ - compile 'com.africastalking:server:VERSION' -} -``` +### 2. Android App -Or Maven (from `http://dl.bintray.com/africastalking/java`) +In your android app, you need to add the following dependencies, and structure your code as shown below. -```xml - - com.africastalking - server - VERSION - -``` +#### a. Add dependencies +Go to the build.gradle file (Module: app [or the name of the module your app's code is in]) and add the following code snippet. -#### Client (Android) ```groovy android { @@ -117,24 +139,236 @@ android { // ... + //ADD THIS ndk { abiFilters "armeabi", "x86" } } } +//ADD THIS repositories { maven { url "http://dl.bintray.com/africastalking/android" } } dependencies{ + + //ADD THIS compile 'com.africastalking:client:VERSION' // or compile 'com.africastalking:client-ui:VERSION' // with checkout UI for payment } ``` +#### b. Add Africa's Talking SDK Code + +First, import the following library classes. + +```Java + + import com.africastalking.AfricasTalking; + + import java.io.IOException; +``` + +Adding the following code snippet in, preferrably, MainActivity (or whatever activity your app launches to). + +```java +/* On The Client (Android) */ +public class SomeActivity extends Activity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(Bundle savedInstanceState); + setContentView(R.layout.some_activity); + + // Initialize SDK + //Use this method below if you had not specified a port for your server above + try{ + + AfricasTalking.initialize(SERVER_HOSTNAME); + + //Use this if you specified a port for your server + AfricasTalking.initialize(SERVER_HOSTNAME, port, true); + + //The SERVER_HOSTNAME can be the ip address of your server on the network or a domain name that can be resolved + + }catch (IOException e){ + + //Do something + + } + + // + } +} +``` + +The code snippet above initializes the SDK. Now, you can use the various Africa's Talking API services as follows: + +#### b.1 Airtime Service + +Add this code snippet in whatever method or activity you would want to invoke before using the Airtime service. + +Import the following library classes + +```Java + + import com.africastalking.services.AirtimeService; + import com.africastalking.AfricasTalking; + import com.africastalking.models.airtime.AirtimeResponse; + + import java.io.IOException; + +``` + +Write the java code. It may look like this. + +```Java +// Get Service + + try{ + + AirtimeService airtime = AfricasTalking.getAirtimeService(); + + // Use Service + airtime.send("+25467675655", "KES", 100, new Callback() { + @Override + void onSuccess(AirtimeResponses responses) { + //... + } + + @Override + void onError(Throwable throwable) { + //... + } + }); + + } catch (IOException e){ + + //Do something + + } +``` + +#### b.2 SMS Service + +Add this code snippet in whatever method or activity you would want to invoke before using the SMS service. + +Import the following library classes + +```Java + + import com.africastalking.services.SmsService; + import com.africastalking.AfricasTalking; + import com.africastalking.models.sms.Recipient + + import java.io.IOException; + +``` + +Write the Java code. It may look like this. + +```java + +//Get service + + try{ + + SmsService sms = AfricasTalking.getSmsService(); + + //Will send "Hello" to number "+254...". Note that the String is an array, so you can add more numbers to do a bulk + //sms + sms.send("Hello", new String[]{"+254...."}, new Callback>() { + @Override + public void onSuccess(List data) { + + //Do something + } + + @Override + public void onFailure(Throwable throwable) { + + //Do something + } + }); + + } catch (IOException e) { + + //Do something + + } + +``` + +#### b.3 Payment Service + +Add this code snippet in whatever method or activity you would want to invoke before using the Payment service. + +Import the following library classes + +```Java + + import com.africastalking.services.PaymentService; + import com.africastalking.AfricasTalking; + import com.africastalking.models.payment.checkout.MobileCheckoutRequest; + import com.africastalking.models.payment.checkout.CheckoutResponse; + + import java.io.IOException; + +``` + +Write the Java code. It may look like this. + +```Java + +//Get service + + try{ + + //get the service + PaymentService payment = AfricasTalking.getPaymentService(); + + //Create the checkout request. You can create a product for testing by visiting + // https://account.africastalking.com/apps/sandbox/payments/products + MobileCheckoutRequest request = new MobileCheckoutRequest("your_product_name", "KES amount",phoneNumber); + + //Checkout + request.checkout(checkoutRequest, new Callback() { + @Override + public void onSuccess(CheckoutResponse data) { + + //Do something + } + + @Override + public void onFailure(Throwable throwable) { + + //Do something + } + }); + + } catch (IOException e) { + + //Do something + + } + +``` + +#### b.4 Voice Service + +Please find this code provided in the Advanced section + +**NOTE** +See the [example](./example) for complete sample apps (Android, Web Java+Node) + +The code snippets above will allow you to write + + +## Advanced + ## Initialization From 697c1f25d3e55c15c38120d79ee9817b13ea4bb5 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Thu, 25 Oct 2018 17:07:07 +0300 Subject: [PATCH 02/24] Update README.md --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 247b9e3..17fd83b 100755 --- a/README.md +++ b/README.md @@ -14,6 +14,13 @@ For instance, to send an SMS, the client will request a token from the server; T ### 1. Server You can code your server using android studio, eclipse or any other IDE you may deem fit. +**NOTE** You are not restricted to use Java to code your server. You can instead use Node.js, PHP, C/C++, C#, and all languages supported by gRPC. Visit this link to get the Africa's Talking Node.js and PHP SDKs to see a template of how your server should look like in Node.js or PHP. + +https://github.com/AfricasTalkingLtd/africastalking-node.js + +https://github.com/AfricasTalkingLtd/africastalking-php + + Whichever IDE you choose to work with, the following need to be done. #### a. Download dependencies @@ -92,7 +99,7 @@ public class SomeJavaApplication { server.startInsecure(); //Use this if you have provided a port - server.startInsecure(port); + //server.startInsecure(port); //Please see the Advanced section for a list of other functions you can use to start your server } catch (IOException e){ @@ -111,14 +118,6 @@ You may need to add the following code snippet just after **server.startInsecure System.in.read(); ``` -**NOTE** You are not restricted to use Java to code your server. You can instead use Node.js, PHP, C/C++, C#, and all languages supported by gRPC. - -Visit this link to get the Africa's Talking Node.js and PHP SDKs to see a template of how your server should look like in Node.js or PHP. - -https://github.com/AfricasTalkingLtd/africastalking-node.js - -https://github.com/AfricasTalkingLtd/africastalking-php - This is enough to run your simple server. Now to the android app. ### 2. Android App @@ -190,7 +189,7 @@ public class SomeActivity extends Activity { AfricasTalking.initialize(SERVER_HOSTNAME); //Use this if you specified a port for your server - AfricasTalking.initialize(SERVER_HOSTNAME, port, true); + //AfricasTalking.initialize(SERVER_HOSTNAME, port, true); //The SERVER_HOSTNAME can be the ip address of your server on the network or a domain name that can be resolved From 8b40aa687129392ddc27c931fb44ad670522899e Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Thu, 25 Oct 2018 17:08:18 +0300 Subject: [PATCH 03/24] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 17fd83b..8fc689a 100755 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ https://github.com/AfricasTalkingLtd/africastalking-node.js https://github.com/AfricasTalkingLtd/africastalking-php +**If you are using Java for your server** Whichever IDE you choose to work with, the following need to be done. From f948b4b4a4e8ed61854d568c565c935c8311585a Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Thu, 25 Oct 2018 17:09:06 +0300 Subject: [PATCH 04/24] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fc689a..e210f88 100755 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ https://github.com/AfricasTalkingLtd/africastalking-node.js https://github.com/AfricasTalkingLtd/africastalking-php -**If you are using Java for your server** +**If you are using Java for your server...** Whichever IDE you choose to work with, the following need to be done. From 58feed6355c245d1d41fcbc69c8298e7e01eba48 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Thu, 25 Oct 2018 17:10:34 +0300 Subject: [PATCH 05/24] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e210f88..61a8601 100755 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ repositories { } } dependencies{ - compile 'com.africastalking:server:VERSION' + implementation 'com.africastalking:server:VERSION' } ``` If you are using Eclipse IDE, or you use Maven dependencies instead, add this code snipppet in your Maven dependencies. @@ -155,9 +155,9 @@ repositories { dependencies{ //ADD THIS - compile 'com.africastalking:client:VERSION' + implementation 'com.africastalking:client:VERSION' // or - compile 'com.africastalking:client-ui:VERSION' // with checkout UI for payment + implementation 'com.africastalking:client-ui:VERSION' // with checkout UI for payment } ``` From 33459c2b95fe23d9a9e4503fb59a31a8c1357ff2 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Thu, 25 Oct 2018 17:12:20 +0300 Subject: [PATCH 06/24] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 61a8601..2d95429 100755 --- a/README.md +++ b/README.md @@ -233,7 +233,8 @@ Write the java code. It may look like this. AirtimeService airtime = AfricasTalking.getAirtimeService(); // Use Service - airtime.send("+25467675655", "KES", 100, new Callback() { + //Will send +254... 100KES airtime + airtime.send("+254...", "KES", 100, new Callback() { @Override void onSuccess(AirtimeResponses responses) { //... From 9fc841690eea53154f03cd7da1e195d49176817e Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Fri, 26 Oct 2018 11:30:09 +0300 Subject: [PATCH 07/24] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2d95429..e6296fc 100755 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ For instance, to send an SMS, the client will request a token from the server; T ### 1. Server You can code your server using android studio, eclipse or any other IDE you may deem fit. -**NOTE** You are not restricted to use Java to code your server. You can instead use Node.js, PHP, C/C++, C#, and all languages supported by gRPC. Visit this link to get the Africa's Talking Node.js and PHP SDKs to see a template of how your server should look like in Node.js or PHP. +**NOTE** You are not restricted to use Java to code your server. You can instead use Node.js, PHP, C/C++, C#, and all languages supported by gRPC. Visit these links to get the Africa's Talking Node.js and PHP SDKs to see a template of how your server should look like in Node.js or PHP. https://github.com/AfricasTalkingLtd/africastalking-node.js From 94ea25bca898e9050479c8a86857cc492211962f Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Fri, 26 Oct 2018 11:34:29 +0300 Subject: [PATCH 08/24] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e6296fc..10e75ea 100755 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ For instance, to send an SMS, the client will request a token from the server; T ## Usage +**NOTE** The code samples seen here are for running a simple server and doing simple API requests. See the advanced section for the list of all methods you can use within the SDK to access the various services. + ### 1. Server You can code your server using android studio, eclipse or any other IDE you may deem fit. From 27d34a86ea03b84aeefdbafbf2ca518cdb1a185f Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Mon, 29 Oct 2018 13:28:30 +0300 Subject: [PATCH 09/24] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10e75ea..9ba24f2 100755 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This SDK simplifies the integration of Africa's Talking APIs into your Android a the SDK is split into two components: A **server** module that stores API keys, SIP credentials and other secrets. And a **client** module that runs in your app. This client module gets secrets from the server component (via RPC), and uses them to interact with the various APIs. -For instance, to send an SMS, the client will request a token from the server; The server will use it's API key to request a token from Africa's Talking on behalf of the client. It will then forward the token to the client which will use it to request the SMS API to send a text. All in a split second! +For instance, to send an SMS, the client will request a token from the server; The server will use it's API key to request a token from Africa's Talking on behalf of the client. It will then forward the token to the client which will use it to request, say, the SMS API to send a text. All in a split second! ## Usage From bcb9203734cdd060f6347733013aee7d4a923344 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Mon, 29 Oct 2018 13:29:55 +0300 Subject: [PATCH 10/24] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 9ba24f2..14b0355 100755 --- a/README.md +++ b/README.md @@ -16,11 +16,10 @@ For instance, to send an SMS, the client will request a token from the server; T ### 1. Server You can code your server using android studio, eclipse or any other IDE you may deem fit. -**NOTE** You are not restricted to use Java to code your server. You can instead use Node.js, PHP, C/C++, C#, and all languages supported by gRPC. Visit these links to get the Africa's Talking Node.js and PHP SDKs to see a template of how your server should look like in Node.js or PHP. +**NOTE** You are not restricted to use Java to code your server. You can instead use Node.js, PHP, C/C++, C#, and all languages supported by gRPC. Visit these links to get the Africa's Talking Node.js SDK to see a template of how your server should look like in Node.js. https://github.com/AfricasTalkingLtd/africastalking-node.js -https://github.com/AfricasTalkingLtd/africastalking-php **If you are using Java for your server...** From 4010f1582c137b3e6f108a01ee99af49cd47cc46 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Mon, 29 Oct 2018 19:21:04 +0300 Subject: [PATCH 11/24] Update README.md --- README.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 14b0355..e21045b 100755 --- a/README.md +++ b/README.md @@ -11,7 +11,9 @@ For instance, to send an SMS, the client will request a token from the server; T ## Usage -**NOTE** The code samples seen here are for running a simple server and doing simple API requests. See the advanced section for the list of all methods you can use within the SDK to access the various services. +**NOTE:** **a)** The code samples seen here are for running a simple server and doing simple API requests. See the advanced section for the list of all methods you can use within the SDK to access the various services. + + **b)** If you plan on integrating the SDK to your android app, please avoid cloning this whole repo. Instead, just follow as instructed in this ReadMe. ### 1. Server You can code your server using android studio, eclipse or any other IDE you may deem fit. @@ -371,47 +373,127 @@ The code snippets above will allow you to write ## Advanced +This section holds the set of all overloaded functions that can be used to perform various tasks in the Android SDK. + +### 1. Server + +#### a. Initialization +The following static method is available on the `AfricasTalking` class to initialize the library, server side. + +- `initialize(String username, String apiKey)`: Initialize the library, passing in the username and apiKey. + +#### b. Start Server +The following methods are available to start your server. + +- `startInsecure()`: Start the server insecurely. + +- `startInsecure(int port)`: Start the server insecurely, providing a port for the server. + +- `start(File certChainFile, File privateKeyFile)`: Start the server securely, providing the certificate and private key. + +- `start(File certChainFile, File privateKeyFile, int port)`: Same as method shown before, but pass in the port to start the server. +#### c. Add Sip Credentials (Voice Only) -## Initialization +- `addSipCredentials(String username, String password, String host)`: Add sip credentials. The actual values for the arguments will be provided by Africa's Talking on request of a SIP phone. + +- `addSipCredentials(String username, String password, String host, int port, String transport)`: Add sip credentials, this +time passing in a port, and transport value. The value for transport will be provided by Africa's Talking on request of a SIP phone. + +#### d. Stop server + +- `stop()`: Stop the server. + +### 2. Android + +#### a. Initialization The following static methods are available on the `AfricasTalking` class to initialize the library: -- `initialize(String host, int port, bool disableTLS)`: Initialize the library. +- `initialize(String host)`: Initialize the library, only passing in the server hostname. + +- `initialize(String host, int port)`: Initialize the library, passing in the server hostname and port only. + +- `initialize(String host, int port, bool disableTLS)`: Initialize the library, passing the server hostname, port, and disableTLS boolean option. + +#### b. Services + +##### b.1 Get a service + - `getXXXService()`: Get an instance to a given `XXX` service. e.g. `AfricasTalking.getSmsService()`, `AfricasTalking.getPaymentService()`, etc. +**NOTE** +All methods for all services are synchronous (i.e. will block current thread) but provide asynchronous variants that take a `Callback` as the last argument. -## Services +Synchronous variants return a service reponse, asynchronous variants return void. -All methods are synchronous (i.e. will block current thread) but provide asynchronous variants that take a `Callback` as the last argument. +If you use the synchronous variants, then make sure you run them in a separate thread from the main UI thread to prevent your app from crashing, and ensuring that you confirm to Android's programming standards (since we are making network calls). -### `Account` +##### b.2 Account Service - `getUser()`: Get user information. -### `Airtime` +- `getUser(Callback callback)`: Get user information with a callback. + +##### b.3 Airtime Service -- `send(String phone, String currencyCode, float amount)`: Send airtime to a phone number. +- `send(String phone, String currency, float amount)`: Send airtime to a single phone number. - `send(HashMap recipients)`: Send airtime to a bunch of phone numbers. The keys in the `recipients` map are phone numbers while the values are airtime amounts ( e.g. `KES 678`). +- `send(String phone, String currency, float amount, Callback callback)`: Send airtime to a single phone number, with a callback. + +- `send(HashMap recipients, Callback callback)`: Send airtime to a bunch of phone numbers. The keys in the `recipients` map are phone numbers while the values are airtime amounts ( e.g. `KES 678`). + For more information about status notification, please read [http://docs.africastalking.com/airtime/callback](http://docs.africastalking.com/airtime/callback) -### `Token` +###### b.4 Token Service - `createCheckoutToken(String phoneNumber)`: Create a checkout token. -### `SMS` +- `createCheckoutToken(String phoneNumber, Callback callback)`: Create a checkout token with a callback response. + +###### b.5 SMS Service + +###### Send an sms to one or more numbers - `send(String message, String[] recipients)`: Send a message +- `send(String message, String[] recipients, Callback> callback)`: Send a message + +- `send(String message, String from, String[] recipients)`: Send a message, passing in the number the message is from. + +- `send(String message, String from, String[] recipients, Callback> callback)`: Send a message, passing in the number the message is from, with a callback. + +/* ***delete all sendBulk instances, update in SDK first before final push, with edit*** + - `sendBulk(String message, String[] recipients)`: Send a message in bulk +###### Send premium sms + - `sendPremium(String message, String keyword, String linkId, String[] recipients)`: Send a premium SMS +- `sendPremium(String message, String from, String keyword, String linkId, String[] recipients)`: Send a premium SMS, passing in the number the message is from + +- `sendPremium(String message, String keyword, String linkId, long retryDurationInHours, String[] recipients)`: Send a premium SMS, passing in the retry duration + +- `sendPremium(String message, String from, String keyword, String linkId, long retryDurationInHours, String[] recipients)`: Send a premium SMS, passing in the retry duration + +- `sendPremium(String message, String keyword, String linkId, String[] recipients, Callback> callback)`: Send a premium SMS, with a callback + +- `sendPremium(String message, String from, String keyword, String linkId, String[] recipients, Callback> callback)`: Send a premium SMS, passing in the number the message is from and a callback + +- `sendPremium(String message, String keyword, String linkId, long retryDurationInHours, String[] recipients, Callback> callback)`: Send a premium SMS, passing in the retry duration and callback. + +- `sendPremium(String message, String from, String keyword, String linkId, long retryDurationInHours, String[] recipients, Callback> callback)`: Send a premium SMS,passing in the number the message is from, retry duration, and a callback + +###### Create premium sms subscription + +- `createSubscription(String ) + - `fetchMessage()`: Fetch your messages - `fetchSubscription(String shortCode, String keyword)`: Fetch your premium subscription data -- `createSubscription(String shortCode, String keyword, String phoneNumber)`: Create a premium subscription +- `createSubscription(String shortCode, String keyword, String phoneNumber, String checkoutToken)`: Create a premium subscription For more information on: From e82d9e1c87d385febfc90fd04e4141c3ea0f74af Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Tue, 30 Oct 2018 18:25:29 +0300 Subject: [PATCH 12/24] Update README.md --- README.md | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e21045b..e0272ec 100755 --- a/README.md +++ b/README.md @@ -443,7 +443,7 @@ If you use the synchronous variants, then make sure you run them in a separate t - `send(HashMap recipients, Callback callback)`: Send airtime to a bunch of phone numbers. The keys in the `recipients` map are phone numbers while the values are airtime amounts ( e.g. `KES 678`). -For more information about status notification, please read [http://docs.africastalking.com/airtime/callback](http://docs.africastalking.com/airtime/callback) +For more information about status notification, please read [http://docs.africastalking.com/airtime/callback](http://docs.africastalking.com/airtime/callback) ###### b.4 Token Service @@ -487,14 +487,10 @@ For more information about status notification, please read [http://docs.africas ###### Create premium sms subscription -- `createSubscription(String ) - -- `fetchMessage()`: Fetch your messages - -- `fetchSubscription(String shortCode, String keyword)`: Fetch your premium subscription data - - `createSubscription(String shortCode, String keyword, String phoneNumber, String checkoutToken)`: Create a premium subscription +- `createSubscription(String shortCode, String keyword, String phoneNumber, String checkoutToken, Callback callback)`: create a premium sms subscription, with a callback passed in for handling the response. + For more information on: - How to receive SMS: [http://docs.africastalking.com/sms/callback](http://docs.africastalking.com/sms/callback) @@ -503,19 +499,47 @@ For more information on: - How to listen for subscription notifications: [http://docs.africastalking.com/subscriptions/callback](http://docs.africastalking.com/subscriptions/callback) -### `Payment` +###### Fetch messages + +- `fetchMessage()`: Fetch your messages + +- `fetchMessage(Callback> callback)`: Fetch your messages, with a callback. + +- `fetchMessage(String lastReceivedId)`: Fetch the last received message + +- `fetchMessage(String lastReceivedId, Callback> callback)`: Fetch the last received message + +- `fetchSubscription(String shortCode, String keyword)`: Fetch your premium subscription data + +- `fetchSubscription(String shortCode, String keyword, String lastReceivedId)`: Fetch your premium subscription data, for last received message + +- `fetchSubscription(String shortCode, String keyword, Callback> callback)`: Fetch your premium subscription data + +- `fetchSubscription(String shortCode, String keyword, String lastReceivedId)`: Fetch your premium subscription data, for last received message + +###### b.6 Payment - `checkout(CheckoutRequest request)`: Initiate checkout(mobile, card or bank). +- `checkout(CheckoutRequest request, Callback callback)`: Initiate checkout(mobile, card or bank). + - `validateCheckout(CheckoutValidateRequest request)`: Validate checkout (card or bank). +- `validateCheckout(CheckoutValidateRequest request, Callback callback)`: Validate checkout (card or bank). + - `mobileB2C(String productName, List recipients)`: Send money to consumer. +- `mobileB2C(String productName, List recipients, Callback callback)`: Send money to consumer. + - `mobileB2B(String productName, Business recipient)`: Send money to business. +- `mobileB2B(String productName, Business recipient, Callback callback)`: Send money to business. + - `bankTransfer(String productName, List recipients)`: Move money form payment wallet to bank account. -### Voice +- `bankTransfer(String productName, List recipients, Callback callback)`: Move money form payment wallet to bank account. + +###### b.7 Voice Unlike other services, voice is initialized as follows: From 99840d02d98854a176a8b86a5b002ca4381f9825 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Wed, 31 Oct 2018 14:10:06 +0300 Subject: [PATCH 13/24] Update README.md --- README.md | 155 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 143 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e0272ec..08e489b 100755 --- a/README.md +++ b/README.md @@ -541,28 +541,159 @@ For more information on: ###### b.7 Voice +To use the voice service, you'll need to import the following libraries. + +```java + + import com.africastalking.AfricasTalking; + import com.africastalking.AfricasTalkingException; //handling exceptions + import com.africastalking.utils.Callback; + import com.africastalking.utils.Logger; //Used for logging + + import com.africastalking.services.VoiceService; + import com.africastalking.utils.voice.CallInfo; + import com.africastalking.utils.voice.CallListener; + import com.africastalking.utils.voice.RegistrationListener; + +``` + Unlike other services, voice is initialized as follows: ```java -AfricasTalking.initializeVoiceService(Context cxt, RegistrationListener listener, new Callback() { - @Override - public void onSuccess(VoiceService service) { - // keep a reference to the 'service' - } +try{ + + AfricasTalking.initializeVoiceService(Context cxt, RegistrationListener listener, new Callback() { + @Override + public void onSuccess(VoiceService service) { + // keep a reference to the 'service' + mService = service; + } + + @Override + public void onFailure(Throwable throwable) { + // something blew up + } + }); + + } catch (Exception ex){ + //failed to initialize + } +``` + +The following listeners are needed: + +**i. Registration listener** + +```java + + RegistrationListener listener = new RegistrationListener() { + @Override + public void onError(Throwable error) { + + //handle error in registering to the SIP server + } + + @Override + public void onStarting() { + + //registration starting + } + + @Override + public void onComplete() { + + //register call listener + mService.registerCallListener(mCallListener); + + //register logger + mService.registerLogger(mLogger); + + //mCallListener is an instance of CallListener. It's instantiated below + } + }; - @Override - public void onFailure(Throwable throwable) { - // something blew up - } -}); ``` +**ii. Call Listener** + +```java + + private CallListener mCallListener = new CallListener() { + @Override + public void onCallBusy(CallInfo call) { + Timber.w("Callee Busy: " + call.getDisplayName()); + } + + @Override + public void onError(CallInfo call, final int errorCode, final String errorMessage) { + + Timber.e("Call Error(" + errorCode + "): " + errorMessage); + + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(VoiceActivity.this, errorMessage + "(" + errorCode + ")", Toast.LENGTH_LONG).show(); + } + }); + } + + @Override + public void onRinging(final CallInfo callInfo) { + Timber.i("Ringing: " + callInfo.getDisplayName()); + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(VoiceActivity.this, "Ringing " + callInfo.getDisplayName(), Toast.LENGTH_LONG).show(); + } + }); + } + + @Override + public void onRingingBack(final CallInfo call) { + Timber.i("Ring Back: " + call.getDisplayName()); + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(VoiceActivity.this, "Ringing Back " + call.getDisplayName(), Toast.LENGTH_LONG).show(); + } + }); + } + + @Override + public void onCallEstablished(CallInfo call) { + Timber.i("Starting call: " + call.getDisplayName()); + + mService.startAudio(); + mService.setSpeakerMode(VoiceActivity.this, false); + + // show in-call ui + Intent i = new Intent(VoiceActivity.this, InCallActivity.class); + i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(i); + } + + @Override + public void onCallEnded(CallInfo call) { + Timber.w("Call Ended: " + call.getDisplayName()); + } + + @Override + public void onIncomingCall(CallInfo callInfo) { + Timber.i("onIncomingCall: " + callInfo.getDisplayName()); + Intent i = new Intent(VoiceActivity.this, InCallActivity.class); + i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(i); + } + }; + + +``` -- `registerCallListener(CallListener listener)`: +- `registerCallListener(CallListener listener)`: register the call listener - `makeCall(String phoneNumber)`: -- `picCall()`: +- `pickCall()`: - `holdCall()`: From 4562559d200725d55bcc36e38853c0272b84123d Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Tue, 13 Nov 2018 15:54:34 +0300 Subject: [PATCH 14/24] Update README.md --- README.md | 98 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 08e489b..d77fa07 100755 --- a/README.md +++ b/README.md @@ -621,102 +621,116 @@ The following listeners are needed: private CallListener mCallListener = new CallListener() { @Override public void onCallBusy(CallInfo call) { - Timber.w("Callee Busy: " + call.getDisplayName()); + + //Do something } @Override public void onError(CallInfo call, final int errorCode, final String errorMessage) { - Timber.e("Call Error(" + errorCode + "): " + errorMessage); - - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(VoiceActivity.this, errorMessage + "(" + errorCode + ")", Toast.LENGTH_LONG).show(); - } - }); + //Do something based on error } @Override public void onRinging(final CallInfo callInfo) { - Timber.i("Ringing: " + callInfo.getDisplayName()); - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(VoiceActivity.this, "Ringing " + callInfo.getDisplayName(), Toast.LENGTH_LONG).show(); - } - }); + + //Do something } @Override public void onRingingBack(final CallInfo call) { - Timber.i("Ring Back: " + call.getDisplayName()); - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(VoiceActivity.this, "Ringing Back " + call.getDisplayName(), Toast.LENGTH_LONG).show(); - } - }); + + //Do something } @Override public void onCallEstablished(CallInfo call) { - Timber.i("Starting call: " + call.getDisplayName()); - + + //The call has been established. So, start audio mService.startAudio(); mService.setSpeakerMode(VoiceActivity.this, false); // show in-call ui - Intent i = new Intent(VoiceActivity.this, InCallActivity.class); - i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(i); + //Probably set up an activity or fragment to do this } @Override public void onCallEnded(CallInfo call) { - Timber.w("Call Ended: " + call.getDisplayName()); + + //Handle the end of the call } @Override public void onIncomingCall(CallInfo callInfo) { - Timber.i("onIncomingCall: " + callInfo.getDisplayName()); - Intent i = new Intent(VoiceActivity.this, InCallActivity.class); - i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(i); + + //Do something. + //You can show in-call UI here, } }; ``` +You can optionally set up a logger as follows: + +```Java + + private Logger logger = new Logger() { + @Override + public void log(String message, Object... args) { + //Log the messages + Timber.d(message, args); + } + }; + +``` + +The following methods may be of use in using the Voice Service in the SDK. They belong to the VoiceService class. + - `registerCallListener(CallListener listener)`: register the call listener -- `makeCall(String phoneNumber)`: +- `unregisterCallListener(CallListener listener)`: unregister the call listener -- `pickCall()`: +- `registerLogger(Logger logger)`: register the logger -- `holdCall()`: +- `unregisterLogger(Logger logger)`: unregister the logger -- `resumeCall()`: +- `makeCall(String phoneNumber)`: make a phone call -- `endCall()`: +- `pickCall()`: pick a call + +- `holdCall()`: hold a call + +- `resumeCall()`: resume a held call + +- `endCall()`: end a call - `sendDtmf(char character)`: - `startAudio()`: -- `toggleMute()`: +- `toggleMute()`: mute or unmute a call -- `setSpeakerMode(Context context, boolean loudSpeaker)`: +- `setSpeakerMode(Context context, boolean loudSpeaker)`: toggle between using the loudspeaker and not -- `isCallInProgress()`: +- `isCallInProgress()`: returns a boolean indicating whether a call is in progress or not -- `getCallInfo()` +- `getCallInfo()`: get an instance of CallInfo - `queueStatus(String phoneNumbers)`: +- `queueStatus(String phoneNumbers, Callback callback)`: + - `mediaUpload(String url)`: +- `mediaUpload(String url, Callback callback)`: + +- `destroyService()`: destroy the voice service + +You can get an instance of the voice service using the following static method of the Africa's Talking class + +- `getVoiceService()`: get an instance of the voice service + ## Requirements From d6c958357db1abf715eebd1e5a5b5ae0d3a1577d Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Tue, 13 Nov 2018 15:58:58 +0300 Subject: [PATCH 15/24] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d77fa07..dd87b08 100755 --- a/README.md +++ b/README.md @@ -368,7 +368,7 @@ Please find this code provided in the Advanced section **NOTE** See the [example](./example) for complete sample apps (Android, Web Java+Node) -The code snippets above will allow you to write +The code snippets above will allow for simple use of the Android SDK to use Africa's Talking API services. For a full list and description of the methods, classes and functionalities of the android SDK, see the Advanced section below. ## Advanced From b18747d17ecc7fd11bcd9b545e74f80eae2c521e Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Wed, 14 Nov 2018 10:49:45 +0300 Subject: [PATCH 16/24] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dd87b08..5e82ead 100755 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ For instance, to send an SMS, the client will request a token from the server; T ## Usage -**NOTE:** **a)** The code samples seen here are for running a simple server and doing simple API requests. See the advanced section for the list of all methods you can use within the SDK to access the various services. +**NOTE:** +**a)** The code samples seen here are for running a simple server and doing simple API requests. See the advanced section for the list of all methods you can use within the SDK to access the various services. **b)** If you plan on integrating the SDK to your android app, please avoid cloning this whole repo. Instead, just follow as instructed in this ReadMe. From 171623ddab254ad17e5ee5c1efe3ba1bb8a75440 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Wed, 14 Nov 2018 10:51:50 +0300 Subject: [PATCH 17/24] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e82ead..f563f61 100755 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ For instance, to send an SMS, the client will request a token from the server; T ## Usage **NOTE:** -**a)** The code samples seen here are for running a simple server and doing simple API requests. See the advanced section for the list of all methods you can use within the SDK to access the various services. + + **a)** The code samples seen here are for running a simple server and doing simple API requests. See the advanced section for the list of all methods you can use within the SDK to access the various services. **b)** If you plan on integrating the SDK to your android app, please avoid cloning this whole repo. Instead, just follow as instructed in this ReadMe. From 1f7c7a7b64a3c3d2cd6c2ec8e9d7fd3894f7f1ce Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Wed, 14 Nov 2018 11:50:18 +0300 Subject: [PATCH 18/24] Update README.md --- README.md | 79 ++++++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index f563f61..11f981a 100755 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Whichever IDE you choose to work with, the following need to be done. #### a. Download dependencies -If you are using android studio (with gradle dependencies), add the following code snippet in your build.gradle file (Module: your_server's_module_name) +If you are using android studio (or gradle dependencies), add the following code snippet in your build.gradle file (Module: your_server's_module_name) ```groovy repositories { @@ -73,7 +73,7 @@ Now put this Java code in the class you've created to run your server. Your server application could be something like this: ```java -/* On The Server (Java, Node.js, PHP, C/C++, C# and all languages supported by gRPC.) */ +/* On The Server (Java) */ import com.africastalking.*; @@ -189,12 +189,11 @@ public class SomeActivity extends Activity { setContentView(R.layout.some_activity); // Initialize SDK - //Use this method below if you had not specified a port for your server above try{ AfricasTalking.initialize(SERVER_HOSTNAME); - //Use this if you specified a port for your server + //Use this instead if you specified a port for your server //AfricasTalking.initialize(SERVER_HOSTNAME, port, true); //The SERVER_HOSTNAME can be the ip address of your server on the network or a domain name that can be resolved @@ -214,7 +213,7 @@ The code snippet above initializes the SDK. Now, you can use the various Africa' #### b.1 Airtime Service -Add this code snippet in whatever method or activity you would want to invoke before using the Airtime service. +Add this code snippet in whatever method or activity you would want to invoke for using the Airtime service. Import the following library classes @@ -238,7 +237,7 @@ Write the java code. It may look like this. AirtimeService airtime = AfricasTalking.getAirtimeService(); // Use Service - //Will send +254... 100KES airtime + //Will send ksh 100 airtime to +254... airtime.send("+254...", "KES", 100, new Callback() { @Override void onSuccess(AirtimeResponses responses) { @@ -260,7 +259,7 @@ Write the java code. It may look like this. #### b.2 SMS Service -Add this code snippet in whatever method or activity you would want to invoke before using the SMS service. +Add this code snippet in whatever method or activity you would want to invoke for using the SMS service. Import the following library classes @@ -284,7 +283,7 @@ Write the Java code. It may look like this. SmsService sms = AfricasTalking.getSmsService(); - //Will send "Hello" to number "+254...". Note that the String is an array, so you can add more numbers to do a bulk + //Will send "Hello" to "+254...". Note that the String is an array, so you can add more numbers to do a bulk //sms sms.send("Hello", new String[]{"+254...."}, new Callback>() { @Override @@ -310,7 +309,7 @@ Write the Java code. It may look like this. #### b.3 Payment Service -Add this code snippet in whatever method or activity you would want to invoke before using the Payment service. +Add this code snippet in whatever method or activity you would want to invoke for using the Payment service. Import the following library classes @@ -338,10 +337,10 @@ Write the Java code. It may look like this. //Create the checkout request. You can create a product for testing by visiting // https://account.africastalking.com/apps/sandbox/payments/products - MobileCheckoutRequest request = new MobileCheckoutRequest("your_product_name", "KES amount",phoneNumber); + MobileCheckoutRequest checkoutRequest = new MobileCheckoutRequest("your_product_name", "KES 500",phoneNumber); //Checkout - request.checkout(checkoutRequest, new Callback() { + payment.checkout(checkoutRequest, new Callback() { @Override public void onSuccess(CheckoutResponse data) { @@ -375,7 +374,7 @@ The code snippets above will allow for simple use of the Android SDK to use Afri ## Advanced -This section holds the set of all overloaded functions that can be used to perform various tasks in the Android SDK. +This section holds the set of all functions that can be used to perform various tasks in the Android SDK. ### 1. Server @@ -419,7 +418,7 @@ The following static methods are available on the `AfricasTalking` class to init #### b. Services -##### b.1 Get a service +##### Get a service - `getXXXService()`: Get an instance to a given `XXX` service. e.g. `AfricasTalking.getSmsService()`, `AfricasTalking.getPaymentService()`, etc. @@ -428,14 +427,14 @@ All methods for all services are synchronous (i.e. will block current thread) bu Synchronous variants return a service reponse, asynchronous variants return void. -If you use the synchronous variants, then make sure you run them in a separate thread from the main UI thread to prevent your app from crashing, and ensuring that you confirm to Android's programming standards (since we are making network calls). +If you use the synchronous variants, then make sure you run them in a separate thread from the main UI thread to prevent your app from crashing, and ensuring that you conform to Android's programming standards (since we are making network calls). -##### b.2 Account Service +##### b.1 Account Service - `getUser()`: Get user information. -- `getUser(Callback callback)`: Get user information with a callback. +- `getUser(Callback callback)`: asynchronous variant of getUser(). -##### b.3 Airtime Service +##### b.2 Airtime Service - `send(String phone, String currency, float amount)`: Send airtime to a single phone number. @@ -443,23 +442,23 @@ If you use the synchronous variants, then make sure you run them in a separate t - `send(String phone, String currency, float amount, Callback callback)`: Send airtime to a single phone number, with a callback. -- `send(HashMap recipients, Callback callback)`: Send airtime to a bunch of phone numbers. The keys in the `recipients` map are phone numbers while the values are airtime amounts ( e.g. `KES 678`). +- `send(HashMap recipients, Callback callback)`: Send airtime to a bunch of phone numbers, with a callback. For more information about status notification, please read [http://docs.africastalking.com/airtime/callback](http://docs.africastalking.com/airtime/callback) -###### b.4 Token Service +###### b.3 Token Service - `createCheckoutToken(String phoneNumber)`: Create a checkout token. - `createCheckoutToken(String phoneNumber, Callback callback)`: Create a checkout token with a callback response. -###### b.5 SMS Service +###### b.4 SMS Service ###### Send an sms to one or more numbers - `send(String message, String[] recipients)`: Send a message -- `send(String message, String[] recipients, Callback> callback)`: Send a message +- `send(String message, String[] recipients, Callback> callback)`: Send a message, with a callback - `send(String message, String from, String[] recipients)`: Send a message, passing in the number the message is from. @@ -477,7 +476,7 @@ For more information about status notification, please read [http://docs.africas - `sendPremium(String message, String keyword, String linkId, long retryDurationInHours, String[] recipients)`: Send a premium SMS, passing in the retry duration -- `sendPremium(String message, String from, String keyword, String linkId, long retryDurationInHours, String[] recipients)`: Send a premium SMS, passing in the retry duration +- `sendPremium(String message, String from, String keyword, String linkId, long retryDurationInHours, String[] recipients)`: Send a premium SMS, passing in the retry duration and the number the message is from - `sendPremium(String message, String keyword, String linkId, String[] recipients, Callback> callback)`: Send a premium SMS, with a callback @@ -491,7 +490,7 @@ For more information about status notification, please read [http://docs.africas - `createSubscription(String shortCode, String keyword, String phoneNumber, String checkoutToken)`: Create a premium subscription -- `createSubscription(String shortCode, String keyword, String phoneNumber, String checkoutToken, Callback callback)`: create a premium sms subscription, with a callback passed in for handling the response. +- `createSubscription(String shortCode, String keyword, String phoneNumber, String checkoutToken, Callback callback)`: create a premium sms subscription, with a callback. For more information on: @@ -509,39 +508,39 @@ For more information on: - `fetchMessage(String lastReceivedId)`: Fetch the last received message -- `fetchMessage(String lastReceivedId, Callback> callback)`: Fetch the last received message +- `fetchMessage(String lastReceivedId, Callback> callback)`: Fetch the last received message with a callback - `fetchSubscription(String shortCode, String keyword)`: Fetch your premium subscription data - `fetchSubscription(String shortCode, String keyword, String lastReceivedId)`: Fetch your premium subscription data, for last received message -- `fetchSubscription(String shortCode, String keyword, Callback> callback)`: Fetch your premium subscription data +- `fetchSubscription(String shortCode, String keyword, Callback> callback)`: Fetch your premium subscription data, with a callback -- `fetchSubscription(String shortCode, String keyword, String lastReceivedId)`: Fetch your premium subscription data, for last received message +- `fetchSubscription(String shortCode, String keyword, String lastReceivedId)`: Fetch your premium subscription data, for last received message, with a callback -###### b.6 Payment +###### b.5 Payment - `checkout(CheckoutRequest request)`: Initiate checkout(mobile, card or bank). -- `checkout(CheckoutRequest request, Callback callback)`: Initiate checkout(mobile, card or bank). +- `checkout(CheckoutRequest request, Callback callback)`: Initiate checkout(mobile, card or bank), with a callback. - `validateCheckout(CheckoutValidateRequest request)`: Validate checkout (card or bank). -- `validateCheckout(CheckoutValidateRequest request, Callback callback)`: Validate checkout (card or bank). +- `validateCheckout(CheckoutValidateRequest request, Callback callback)`: Validate checkout (card or bank), with a callback. - `mobileB2C(String productName, List recipients)`: Send money to consumer. -- `mobileB2C(String productName, List recipients, Callback callback)`: Send money to consumer. +- `mobileB2C(String productName, List recipients, Callback callback)`: Send money to consumer, with a callback. - `mobileB2B(String productName, Business recipient)`: Send money to business. -- `mobileB2B(String productName, Business recipient, Callback callback)`: Send money to business. +- `mobileB2B(String productName, Business recipient, Callback callback)`: Send money to business, with a callback. -- `bankTransfer(String productName, List recipients)`: Move money form payment wallet to bank account. +- `bankTransfer(String productName, List recipients)`: Move money from payment wallet to bank account. -- `bankTransfer(String productName, List recipients, Callback callback)`: Move money form payment wallet to bank account. +- `bankTransfer(String productName, List recipients, Callback callback)`: Move money from payment wallet to bank account, with a callback. -###### b.7 Voice +###### b.6 Voice To use the voice service, you'll need to import the following libraries. @@ -707,9 +706,9 @@ The following methods may be of use in using the Voice Service in the SDK. They - `endCall()`: end a call -- `sendDtmf(char character)`: +- `sendDtmf(char character)`: send the dialpad character the user has pressed -- `startAudio()`: +- `startAudio()`: initiate the phone speaker to start audio - `toggleMute()`: mute or unmute a call @@ -719,14 +718,6 @@ The following methods may be of use in using the Voice Service in the SDK. They - `getCallInfo()`: get an instance of CallInfo -- `queueStatus(String phoneNumbers)`: - -- `queueStatus(String phoneNumbers, Callback callback)`: - -- `mediaUpload(String url)`: - -- `mediaUpload(String url, Callback callback)`: - - `destroyService()`: destroy the voice service You can get an instance of the voice service using the following static method of the Africa's Talking class From 5e2eb5e30e51934105209582928d8fd15f9689fc Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Fri, 16 Nov 2018 16:15:08 +0300 Subject: [PATCH 19/24] Update README.md --- README.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 11f981a..0ac8cfd 100755 --- a/README.md +++ b/README.md @@ -285,7 +285,7 @@ Write the Java code. It may look like this. //Will send "Hello" to "+254...". Note that the String is an array, so you can add more numbers to do a bulk //sms - sms.send("Hello", new String[]{"+254...."}, new Callback>() { + sms.send("Hello", new String[]{"+254...."}, false, new Callback>() { @Override public void onSuccess(List data) { @@ -429,7 +429,7 @@ Synchronous variants return a service reponse, asynchronous variants return void If you use the synchronous variants, then make sure you run them in a separate thread from the main UI thread to prevent your app from crashing, and ensuring that you conform to Android's programming standards (since we are making network calls). -##### b.1 Account Service +##### b.1 Application Service (For getting user account information - `getUser()`: Get user information. - `getUser(Callback callback)`: asynchronous variant of getUser(). @@ -456,17 +456,15 @@ For more information about status notification, please read [http://docs.africas ###### Send an sms to one or more numbers -- `send(String message, String[] recipients)`: Send a message +**NOTE:** Setting enqueue to false means that the message will be sent and you will receive the response immediately. Setting it to true means that the response will be sent later after the message was sent. -- `send(String message, String[] recipients, Callback> callback)`: Send a message, with a callback +- `send(String message, String[] recipients, boolean enqueue)`: Send a message -- `send(String message, String from, String[] recipients)`: Send a message, passing in the number the message is from. +- `send(String message, String[] recipients, boolean enqueue, Callback> callback)`: Send a message, with a callback -- `send(String message, String from, String[] recipients, Callback> callback)`: Send a message, passing in the number the message is from, with a callback. +- `send(String message, String from, String[] recipients, boolean enqueue)`: Send a message, passing in the number the message is from. -/* ***delete all sendBulk instances, update in SDK first before final push, with edit*** - -- `sendBulk(String message, String[] recipients)`: Send a message in bulk +- `send(String message, String from, String[] recipients, boolean enqueue, Callback> callback)`: Send a message, passing in the number the message is from, with a callback. ###### Send premium sms From b83ad19a3bcd4f7def1d5990d48880a4de696290 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Fri, 16 Nov 2018 16:17:03 +0300 Subject: [PATCH 20/24] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ac8cfd..ec179e7 100755 --- a/README.md +++ b/README.md @@ -456,7 +456,7 @@ For more information about status notification, please read [http://docs.africas ###### Send an sms to one or more numbers -**NOTE:** Setting enqueue to false means that the message will be sent and you will receive the response immediately. Setting it to true means that the response will be sent later after the message was sent. +**NOTE:** Setting enqueue to false means that the message will be sent and you will receive the response immediately. Setting it to true means that the response will be received later after the message was sent. - `send(String message, String[] recipients, boolean enqueue)`: Send a message From acbef004de2ac04719acec38e02b3799b45510c1 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius Date: Tue, 20 Nov 2018 16:39:41 +0300 Subject: [PATCH 21/24] Updated SDK --- README.md | 43 +++--- build.gradle | 2 +- client-ui/build.gradle | 16 ++- client/build.gradle | 28 ++-- .../com/africastalking/AfricasTalking.java | 13 +- ...Response.java => ApplicationResponse.java} | 2 +- .../services/AccountServiceInterface.java | 4 +- ...ntService.java => ApplicationService.java} | 22 +-- .../services/ApplicationServiceInterface.java | 15 ++ .../com/africastalking/services/Service.java | 8 +- .../africastalking/services/SmsService.java | 135 ++---------------- .../services/SmsServiceInterface.java | 5 - example/android/build.gradle | 5 +- .../android/ui/MainActivity.java | 25 ++-- .../android/ui/airtime/AirtimeActivity.java | 1 + .../android/ui/payment/PaymentActivity.java | 4 +- .../android/ui/sms/SmsActivity.java | 4 +- .../android/ui/voice/InCallActivity.java | 1 + example/web/java/build.gradle | 12 +- gradle/wrapper/gradle-wrapper.properties | 5 +- luhn/build.gradle | 14 +- 21 files changed, 134 insertions(+), 230 deletions(-) rename client/src/main/java/com/africastalking/models/account/{AccountResponse.java => ApplicationResponse.java} (85%) rename client/src/main/java/com/africastalking/services/{AccountService.java => ApplicationService.java} (69%) mode change 100755 => 100644 create mode 100644 client/src/main/java/com/africastalking/services/ApplicationServiceInterface.java diff --git a/README.md b/README.md index cc345f8..44ba727 100755 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This SDK simplifies the integration of Africa's Talking APIs into your Android a the SDK is split into two components: A **server** module that stores API keys, SIP credentials and other secrets. And a **client** module that runs in your app. This client module gets secrets from the server component (via RPC), and uses them to interact with the various APIs. -For instance, to send an SMS, the client with request a token from the server; The server will use it's API key to request a token from Africa's Talking on behalf of the client. It will then forward the token to the client which will use it to request the SMS API to send a text. All in a split second! +For instance, to send an SMS, the client with (**will**) request a token from the server; The server will use it's API key to request a token from Africa's Talking on behalf of the client. It will then forward the token to the client which will use it to request the SMS API to send a text. All in a split second! ### Usage @@ -48,29 +48,24 @@ public class SomeActivity extends Activity { super.onCreate(args); setContentView(R.layout.some_activity); - try { - // Init SDK - AfricasTalking.initialize(SERVER_HOSTNAME); - - // Get Service - AirtimeService airtime = AfricasTalking.getAirtimeService(); - - // Use Service - airtime.send("+25467675655", "KES", 100, new Callback() { - @Override - void onSuccess(AirtimeResponses responses) { - //... - } - - @Override - void onError(Throwable throwable) { - //... - } - }); - - } catch (IOException ex) { - // grrr - } + // Init SDK + AfricasTalking.initialize(SERVER_HOSTNAME); + + // Get Service + AirtimeService airtime = AfricasTalking.getAirtimeService(); + + // Use Service + airtime.send("+25467675655", "KES", 100, new Callback() { + @Override + void onSuccess(AirtimeResponses responses) { + //... + } + + @Override + void onError(Throwable throwable) { + //... + } + }); } } ``` diff --git a/build.gradle b/build.gradle index cf30bc6..ded21ed 100755 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:3.1.0-alpha05' + classpath 'com.android.tools.build:gradle:3.1.4' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.2' classpath 'gradle.plugin.de.fuerstenau:BuildConfigPlugin:1.1.8' diff --git a/client-ui/build.gradle b/client-ui/build.gradle index 75fdbd4..83b28c6 100644 --- a/client-ui/build.gradle +++ b/client-ui/build.gradle @@ -10,7 +10,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.1.0-alpha05' + classpath 'com.android.tools.build:gradle:3.1.4' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' } } @@ -23,7 +23,7 @@ version properties.getProperty("bintray.version") android { compileSdkVersion 27 - buildToolsVersion "27.0.1" + buildToolsVersion '27.0.3' defaultConfig { minSdkVersion 16 @@ -51,13 +51,17 @@ repositories { dependencies { // Client - compile project(':client') + implementation project(':client') // Cards UI - compile project(':luhn') + implementation project(':luhn') - testCompile 'junit:junit:4.12' - testCompile 'com.squareup.okhttp3:mockwebserver:3.8.1' + implementation ('io.card:android-sdk:5.5.1'){ + exclude group: "com.android.support" + } + + testImplementation 'junit:junit:4.12' + testImplementation 'com.squareup.okhttp3:mockwebserver:3.8.1' } task sourcesJar(type: Jar) { diff --git a/client/build.gradle b/client/build.gradle index 50f9929..5a45443 100755 --- a/client/build.gradle +++ b/client/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.1.0-alpha05' + classpath 'com.android.tools.build:gradle:3.1.4' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' } } @@ -25,7 +25,7 @@ version properties.getProperty("bintray.version") android { compileSdkVersion 27 - buildToolsVersion "27.0.1" + buildToolsVersion '27.0.3' defaultConfig { minSdkVersion 16 @@ -88,26 +88,26 @@ repositories { dependencies { // annotations - compile 'javax.annotation:javax.annotation-api:1.2' + implementation 'javax.annotation:javax.annotation-api:1.2' // compile 'com.android.support:support-annotations:25.3.1' - compile 'com.squareup.retrofit2:retrofit:2.3.0' - compile 'com.squareup.retrofit2:converter-scalars:2.3.0' - compile 'com.squareup.retrofit2:converter-gson:2.3.0' - compile 'com.squareup.okhttp3:logging-interceptor:3.8.1' + implementation 'com.squareup.retrofit2:retrofit:2.3.0' + implementation 'com.squareup.retrofit2:converter-scalars:2.3.0' + implementation 'com.squareup.retrofit2:converter-gson:2.3.0' + implementation 'com.squareup.okhttp3:logging-interceptor:3.8.1' // permissions - compile 'com.karumi:dexter:4.1.0' + implementation 'com.karumi:dexter:4.1.0' // grpc - compile 'io.grpc:grpc-stub:1.5.0' - compile 'io.grpc:grpc-okhttp:1.5.0' - compile 'io.grpc:grpc-protobuf-lite:1.5.0' + implementation 'io.grpc:grpc-stub:1.5.0' + implementation 'io.grpc:grpc-okhttp:1.5.0' + implementation 'io.grpc:grpc-protobuf-lite:1.5.0' - compile 'com.birbit:android-priority-jobqueue:2.0.1' + implementation 'com.birbit:android-priority-jobqueue:2.0.1' - testCompile 'junit:junit:4.12' - testCompile 'com.squareup.okhttp3:mockwebserver:3.8.1' + testImplementation 'junit:junit:4.12' + testImplementation 'com.squareup.okhttp3:mockwebserver:3.8.1' } task sourcesJar(type: Jar) { diff --git a/client/src/main/java/com/africastalking/AfricasTalking.java b/client/src/main/java/com/africastalking/AfricasTalking.java index e4d6c37..f62a7e0 100755 --- a/client/src/main/java/com/africastalking/AfricasTalking.java +++ b/client/src/main/java/com/africastalking/AfricasTalking.java @@ -4,7 +4,7 @@ import android.app.Activity; import android.text.TextUtils; -import com.africastalking.services.AccountService; +import com.africastalking.services.ApplicationService; import com.africastalking.services.AirtimeService; import com.africastalking.services.PaymentService; import com.africastalking.services.Service; @@ -44,17 +44,17 @@ public final class AfricasTalking { ); - public static void initialize(String host, int port, boolean disableTLS) throws IOException { + public static void initialize(String host, int port, boolean disableTLS) { Service.HOST = host; Service.PORT = port; Service.DISABLE_TLS = disableTLS; } - public static void initialize(String host, int port) throws IOException { + public static void initialize(String host, int port) { initialize(host, port, false); } - public static void initialize(String host) throws IOException { + public static void initialize(String host) { initialize(host, Service.PORT, false); } @@ -89,8 +89,13 @@ public static PaymentService getPaymentService() throws IOException { return Service.newInstance("payment"); } + /* public static AccountService getAccountService() throws IOException { return Service.newInstance("account"); + } */ + + public static ApplicationService getApplicationService() throws IOException { + return Service.newInstance("application"); } public static TokenService getTokenService() throws IOException { diff --git a/client/src/main/java/com/africastalking/models/account/AccountResponse.java b/client/src/main/java/com/africastalking/models/account/ApplicationResponse.java similarity index 85% rename from client/src/main/java/com/africastalking/models/account/AccountResponse.java rename to client/src/main/java/com/africastalking/models/account/ApplicationResponse.java index 9266512..44df268 100644 --- a/client/src/main/java/com/africastalking/models/account/AccountResponse.java +++ b/client/src/main/java/com/africastalking/models/account/ApplicationResponse.java @@ -2,7 +2,7 @@ import com.google.gson.annotations.SerializedName; -public final class AccountResponse { +public final class ApplicationResponse { @SerializedName("UserData") public UserData userData; diff --git a/client/src/main/java/com/africastalking/services/AccountServiceInterface.java b/client/src/main/java/com/africastalking/services/AccountServiceInterface.java index ba08ae2..752ae08 100755 --- a/client/src/main/java/com/africastalking/services/AccountServiceInterface.java +++ b/client/src/main/java/com/africastalking/services/AccountServiceInterface.java @@ -1,6 +1,6 @@ package com.africastalking.services; -import com.africastalking.models.account.AccountResponse; +import com.africastalking.models.account.ApplicationResponse; import retrofit2.Call; import retrofit2.http.GET; @@ -11,5 +11,5 @@ */ public interface AccountServiceInterface { @GET("user") - Call getUser(@Query("username") String username); + Call getUser(@Query("username") String username); } diff --git a/client/src/main/java/com/africastalking/services/AccountService.java b/client/src/main/java/com/africastalking/services/ApplicationService.java old mode 100755 new mode 100644 similarity index 69% rename from client/src/main/java/com/africastalking/services/AccountService.java rename to client/src/main/java/com/africastalking/services/ApplicationService.java index 27c5edb..eb92731 --- a/client/src/main/java/com/africastalking/services/AccountService.java +++ b/client/src/main/java/com/africastalking/services/ApplicationService.java @@ -2,7 +2,7 @@ import com.africastalking.utils.Callback; -import com.africastalking.models.account.AccountResponse; +import com.africastalking.models.account.ApplicationResponse; import retrofit2.Response; import retrofit2.Retrofit; @@ -12,20 +12,20 @@ /** * Account service. Retrieve user account info */ -public class AccountService extends Service { +public class ApplicationService extends Service { - static AccountService sInstance; - private AccountServiceInterface service; + static ApplicationService sInstance; + private ApplicationServiceInterface service; - AccountService() throws IOException { + ApplicationService() throws IOException { super(); } @Override - protected AccountService getInstance() throws IOException { + protected ApplicationService getInstance() throws IOException { if (sInstance == null) { - sInstance = new AccountService(); + sInstance = new ApplicationService(); } return sInstance; @@ -39,7 +39,7 @@ protected void initService() { .baseUrl(url) .build(); - service = retrofit.create(AccountServiceInterface.class); + service = retrofit.create(ApplicationServiceInterface.class); } @Override @@ -65,8 +65,8 @@ protected void destroyService() { * @return String in specified format, xml or json * @throws IOException */ - public AccountResponse getUser() throws IOException { - Response resp = service.getUser(username).execute(); + public ApplicationResponse getUser() throws IOException { + Response resp = service.getUser(username).execute(); if (!resp.isSuccessful()) { throw new IOException(resp.errorBody().string()); } @@ -81,7 +81,7 @@ public AccountResponse getUser() throws IOException { *

* @param callback */ - public void getUser(final Callback callback) { + public void getUser(final Callback callback) { service.getUser(username).enqueue(makeCallback(callback)); } } diff --git a/client/src/main/java/com/africastalking/services/ApplicationServiceInterface.java b/client/src/main/java/com/africastalking/services/ApplicationServiceInterface.java new file mode 100644 index 0000000..7adb23e --- /dev/null +++ b/client/src/main/java/com/africastalking/services/ApplicationServiceInterface.java @@ -0,0 +1,15 @@ +package com.africastalking.services; + +import com.africastalking.models.account.ApplicationResponse; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +/** + * Account Endpoints + */ +public interface ApplicationServiceInterface { + @GET("user") + Call getUser(@Query("username") String username); +} diff --git a/client/src/main/java/com/africastalking/services/Service.java b/client/src/main/java/com/africastalking/services/Service.java index 3f5f6c4..12790dd 100755 --- a/client/src/main/java/com/africastalking/services/Service.java +++ b/client/src/main/java/com/africastalking/services/Service.java @@ -160,11 +160,11 @@ protected ClientTokenResponse fetchToken(String host, int port) throws IOExcepti public static T newInstance(String service) throws IOException { - if (service.contentEquals("account")) { - if (AccountService.sInstance == null) { - AccountService.sInstance = new AccountService(); + if (service.contentEquals("application")) { + if (ApplicationService.sInstance == null) { + ApplicationService.sInstance = new ApplicationService(); } - return (T) AccountService.sInstance; + return (T) ApplicationService.sInstance; } diff --git a/client/src/main/java/com/africastalking/services/SmsService.java b/client/src/main/java/com/africastalking/services/SmsService.java index 1fe08fc..3934253 100755 --- a/client/src/main/java/com/africastalking/services/SmsService.java +++ b/client/src/main/java/com/africastalking/services/SmsService.java @@ -77,8 +77,8 @@ private String formatRecipients(String[] recipients) { * Synchronously send the request and return its response. *

*/ - public List send(String message, String from, String[] recipients) throws IOException { - Response resp = sms.send(username, formatRecipients(recipients), from, message).execute(); + public List send(String message, String from, String[] recipients, boolean enqueue) throws IOException { + Response resp = sms.send(username, formatRecipients(recipients), from, message, 1, enqueue ? "1" : null).execute(); if (!resp.isSuccessful()) { throw new IOException(resp.errorBody().string()); } @@ -98,8 +98,8 @@ public List send(String message, String from, String[] recipients) th * occurred *

*/ - public void send(String message, String from, String[] recipients, final Callback> callback) { - sms.send(username, formatRecipients(recipients), from, message).enqueue(makeCallback(new Callback() { + public void send(String message, String from, String[] recipients, boolean enqueue, final Callback> callback) { + sms.send(username, formatRecipients(recipients), from, message, 1, enqueue ? "1" : null).enqueue(makeCallback(new Callback() { @Override public void onSuccess(SendMessageResponse data) { if (data != null) { @@ -122,8 +122,8 @@ public void onFailure(Throwable throwable) { * Synchronously send the request and return its response. *

*/ - public List send(String message, String[] recipients) throws IOException { - return send(message, null, recipients); + public List send(String message, String[] recipients, boolean enqueue) throws IOException { + return send(message, null, recipients,enqueue); } @@ -134,132 +134,17 @@ public List send(String message, String[] recipients) throws IOExcept * occurred *

*/ - public void send(String message, String[] recipients, Callback> callback) { - send(message, null, recipients, callback); + public void send(String message, String[] recipients, boolean enqueue, Callback> callback) { + send(message, null, recipients, enqueue, callback); } // -> Bulk /** - * Send a message in bulk - *

- * Synchronously send the request and return its response. - *

- */ - public List sendBulk(String message, String from, boolean enqueue, String[] recipients) throws IOException { - Response resp = sms.sendBulk( - username, - formatRecipients(recipients), - from, - message, - 1, - enqueue ? "1" : null).execute(); - - if (!resp.isSuccessful()) { - throw new IOException(resp.errorBody().string()); - } - - try { - return resp.body().data.recipients; - } catch (NullPointerException npe) { - throw new IOException("Invali API response"); - } - } - - /** - * Send a message in bulk - *

- * Asynchronously send the request and notify {@code callback} of its response or if an error - * occurred - *

- */ - public void sendBulk(String message, String from, boolean enqueue, String[] recipients, final Callback> callback) { - sms.sendBulk(username, - formatRecipients(recipients), - from, - message, - 1, - enqueue ? "1" : null).enqueue(makeCallback(new Callback() { - - @Override - public void onSuccess(SendMessageResponse data) { - if (data != null) { - callback.onSuccess(data.data.recipients); - } else { - callback.onFailure(new Exception("Invalid API response")); - } - } - - @Override - public void onFailure(Throwable throwable) { - callback.onFailure(throwable); - } - })); - } - - /** - * Send a message in bulk - *

- * Synchronously send the request and return its response. - *

+ * sendBulk() + * Deprecated */ - public List sendBulk(String message, String from, String[] recipients) throws IOException { - return sendBulk(message, from, false, recipients); - } - - /** - * Send a message in bulk - *

- * Asynchronously send the request and notify {@code callback} of its response or if an error - * occurred - *

- */ - public void sendBulk(String message, String from, String[] recipients, Callback> callback) { - sendBulk(message, from, false, recipients, callback); - } - - /** - * Send a message in bulk - *

- * Synchronously send the request and return its response. - *

- */ - public List sendBulk(String message, boolean enqueue, String[] recipients) throws IOException { - return sendBulk(message, null, enqueue, recipients); - } - - /** - * Send a message in bulk - *

- * Asynchronously send the request and notify {@code callback} of its response or if an error - * occurred - *

- */ - public void sendBulk(String message, boolean enqueue, String[] recipients, Callback> callback) { - sendBulk(message, null, enqueue, recipients, callback); - } - - /** - * Send a message in bulk - *

- * Synchronously send the request and return its response. - *

- */ - public List sendBulk(String message, String[] recipients) throws IOException { - return sendBulk(message, null, false, recipients); - } - - /** - * Send a message in bulk - *

- * Asynchronously send the request and notify {@code callback} of its response or if an error - * occurred - *

- */ - public void sendBulk(String message, String[] recipients, Callback> callback) { - sendBulk(message, null, false, recipients, callback); - } // -> Premium diff --git a/client/src/main/java/com/africastalking/services/SmsServiceInterface.java b/client/src/main/java/com/africastalking/services/SmsServiceInterface.java index 959e17f..db4bf6a 100755 --- a/client/src/main/java/com/africastalking/services/SmsServiceInterface.java +++ b/client/src/main/java/com/africastalking/services/SmsServiceInterface.java @@ -17,11 +17,6 @@ public interface SmsServiceInterface { @FormUrlEncoded @POST("messaging") Call send(@Field("username") String username, @Field("to") String to, - @Field("from") String from, @Field("message") String message); - - @FormUrlEncoded - @POST("messaging") - Call sendBulk(@Field("username") String username, @Field("to") String to, @Field("from") String from, @Field("message") String message, @Field("bulkSMSMode") int bulkMode, @Field("enqueue") String enqueue); @FormUrlEncoded diff --git a/example/android/build.gradle b/example/android/build.gradle index a52ec81..ad71053 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -2,11 +2,11 @@ apply plugin: 'com.android.application' Properties properties = new Properties() -properties.load(project.rootProject.file('local.properties').newDataInputStream()) +properties.load(project.rootProject.file('local.properties').newDataInputStream()) //Initializing properties??? android { compileSdkVersion 27 - buildToolsVersion "27.0.1" + buildToolsVersion '27.0.3' defaultConfig { applicationId "com.africastalking.android" @@ -50,6 +50,7 @@ dependencies { implementation 'com.jakewharton:butterknife:8.7.0' implementation 'com.jraska:console:0.4.3' implementation 'com.jraska:console-timber-tree:0.4.3' + implementation project(':client') implementation project(':client-ui') testImplementation 'junit:junit:4.12' annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0' diff --git a/example/android/src/main/java/com/africastalking/android/ui/MainActivity.java b/example/android/src/main/java/com/africastalking/android/ui/MainActivity.java index 2a0b97e..d1bc8f1 100644 --- a/example/android/src/main/java/com/africastalking/android/ui/MainActivity.java +++ b/example/android/src/main/java/com/africastalking/android/ui/MainActivity.java @@ -51,20 +51,17 @@ public void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); ButterKnife.bind(this); - try { - Timber.i("Initializing SDK..."); - AfricasTalking.initialize( - BuildConfig.RPC_HOST, - BuildConfig.RPC_PORT, true); - AfricasTalking.setLogger(new Logger() { - @Override - public void log(String message, Object... args) { - Timber.d(message, args); - } - }); - } catch (IOException ex) { - Timber.e(ex.getMessage()); - } + //Initialize the SDK + Timber.i("Initializing SDK..."); + AfricasTalking.initialize( + BuildConfig.RPC_HOST, + BuildConfig.RPC_PORT, true); + AfricasTalking.setLogger(new Logger() { + @Override + public void log(String message, Object... args) { + Timber.d(message, args); + } + }); } @OnClick(R.id.airtime_layout) diff --git a/example/android/src/main/java/com/africastalking/android/ui/airtime/AirtimeActivity.java b/example/android/src/main/java/com/africastalking/android/ui/airtime/AirtimeActivity.java index 026654c..475966e 100644 --- a/example/android/src/main/java/com/africastalking/android/ui/airtime/AirtimeActivity.java +++ b/example/android/src/main/java/com/africastalking/android/ui/airtime/AirtimeActivity.java @@ -7,6 +7,7 @@ import com.africastalking.AfricasTalking; import com.africastalking.android.R; import com.africastalking.android.ui.BaseActivity; +import com.africastalking.models.account.ApplicationResponse; import com.africastalking.models.airtime.AirtimeResponse; import com.africastalking.services.AirtimeService; diff --git a/example/android/src/main/java/com/africastalking/android/ui/payment/PaymentActivity.java b/example/android/src/main/java/com/africastalking/android/ui/payment/PaymentActivity.java index 5ccf7a9..9c50995 100644 --- a/example/android/src/main/java/com/africastalking/android/ui/payment/PaymentActivity.java +++ b/example/android/src/main/java/com/africastalking/android/ui/payment/PaymentActivity.java @@ -3,6 +3,7 @@ import android.annotation.SuppressLint; import android.os.AsyncTask; import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -20,7 +21,6 @@ import com.africastalking.ui.Checkout; import com.africastalking.utils.Callback; import com.africastalking.android.R; -import com.africastalking.android.ui.BaseActivity; import com.africastalking.models.payment.checkout.CheckoutResponse; import com.africastalking.services.PaymentService; @@ -30,7 +30,7 @@ import timber.log.Timber; -public class PaymentActivity extends BaseActivity { +public class PaymentActivity extends AppCompatActivity { PaymentService payment; diff --git a/example/android/src/main/java/com/africastalking/android/ui/sms/SmsActivity.java b/example/android/src/main/java/com/africastalking/android/ui/sms/SmsActivity.java index 30b4ae9..541a358 100644 --- a/example/android/src/main/java/com/africastalking/android/ui/sms/SmsActivity.java +++ b/example/android/src/main/java/com/africastalking/android/ui/sms/SmsActivity.java @@ -10,7 +10,9 @@ import com.africastalking.models.sms.Recipient; import com.africastalking.models.sms.SendMessageResponse; import com.africastalking.services.SmsService; +import com.africastalking.utils.Callback; +import java.io.IOException; import java.util.List; import timber.log.Timber; @@ -33,7 +35,7 @@ protected Void doInBackground(Void... params) { SmsService sms = AfricasTalking.getSmsService(); Timber.i("Sending hello to 0718769882"); - List res = sms.send("hello", new String[]{"0718769882"}); + List res = sms.send("hello", new String[]{"0718769882"},false); Timber.i(res.get(0).messageId); Timber.i(res.get(0).status); diff --git a/example/android/src/main/java/com/africastalking/android/ui/voice/InCallActivity.java b/example/android/src/main/java/com/africastalking/android/ui/voice/InCallActivity.java index 3eb32b6..838e0ab 100644 --- a/example/android/src/main/java/com/africastalking/android/ui/voice/InCallActivity.java +++ b/example/android/src/main/java/com/africastalking/android/ui/voice/InCallActivity.java @@ -179,5 +179,6 @@ protected void onDestroy() { mService.unregisterCallListener(mCallListener); } super.onDestroy(); + } } diff --git a/example/web/java/build.gradle b/example/web/java/build.gradle index e531efe..b1b8dc3 100644 --- a/example/web/java/build.gradle +++ b/example/web/java/build.gradle @@ -39,12 +39,12 @@ repositories { } dependencies { - compile 'org.slf4j:slf4j-simple:1.7.25' - compile 'com.sparkjava:spark-core:2.6.0' - compile 'com.sparkjava:spark-template-handlebars:2.3' - compile 'com.google.code.gson:gson:2.8.2' - compile 'com.africastalking:server:3.0.6' - testCompile 'junit:junit:4.12' + implementation 'org.slf4j:slf4j-simple:1.7.25' + implementation 'com.sparkjava:spark-core:2.6.0' + implementation 'com.sparkjava:spark-template-handlebars:2.3' + implementation 'com.google.code.gson:gson:2.8.2' + implementation 'com.africastalking:server:3.0.6' + testImplementation 'junit:junit:4.12' } task runWebApp(type: JavaExec, dependsOn: classes){ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ef64545..d77d92b 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-4.4-20171031235950+0000-all.zip +#distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-4.4-20171031235950+0000-all.zip +#Note that the above URL caused a gradle sync failure. The web response was that the key doesn't exist. Changed to the URL below. + +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/luhn/build.gradle b/luhn/build.gradle index bd62be5..dc73b2a 100755 --- a/luhn/build.gradle +++ b/luhn/build.gradle @@ -10,7 +10,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.1.0-alpha05' + classpath 'com.android.tools.build:gradle:3.1.4' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' } } @@ -23,7 +23,7 @@ version properties.getProperty("bintray.version") android { compileSdkVersion 27 - buildToolsVersion "27.0.1" + buildToolsVersion '27.0.3' defaultConfig { @@ -48,13 +48,13 @@ android { } dependencies { - compile 'com.android.support:design:27.0.1' - compile 'com.android.support:appcompat-v7:27.0.1' - compile 'com.android.support:support-compat:27.0.1' - compile ('io.card:android-sdk:5.5.1'){ + implementation 'com.android.support:design:27.0.1' + implementation 'com.android.support:appcompat-v7:27.0.1' + implementation 'com.android.support:support-compat:27.0.1' + implementation ('io.card:android-sdk:5.5.1'){ exclude group: "com.android.support" } - compile ('uk.co.chrisjenx:calligraphy:2.3.0'){ + implementation ('uk.co.chrisjenx:calligraphy:2.3.0'){ exclude group: "com.android.support" } } From 4fbc0359062e0029b45d113ee3c9d43873522f1a Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Tue, 20 Nov 2018 16:48:37 +0300 Subject: [PATCH 22/24] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ec179e7..15378cd 100755 --- a/README.md +++ b/README.md @@ -466,6 +466,8 @@ For more information about status notification, please read [http://docs.africas - `send(String message, String from, String[] recipients, boolean enqueue, Callback> callback)`: Send a message, passing in the number the message is from, with a callback. +**Note** "from" is your sms shortcode or alphanumeric name created from your Africa's Talking account. You can create one for testing from: https://account.africastalking.com/apps/sandbox/sms/shortcodes/create + ###### Send premium sms - `sendPremium(String message, String keyword, String linkId, String[] recipients)`: Send a premium SMS From 863f7d1b243c2d6e601d2f4a53fbdd9bcef687d2 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Tue, 20 Nov 2018 16:56:33 +0300 Subject: [PATCH 23/24] Update README.md --- README.md | 698 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 589 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 44ba727..15378cd 100755 --- a/README.md +++ b/README.md @@ -6,20 +6,89 @@ This SDK simplifies the integration of Africa's Talking APIs into your Android a the SDK is split into two components: A **server** module that stores API keys, SIP credentials and other secrets. And a **client** module that runs in your app. This client module gets secrets from the server component (via RPC), and uses them to interact with the various APIs. -For instance, to send an SMS, the client with (**will**) request a token from the server; The server will use it's API key to request a token from Africa's Talking on behalf of the client. It will then forward the token to the client which will use it to request the SMS API to send a text. All in a split second! +For instance, to send an SMS, the client will request a token from the server; The server will use it's API key to request a token from Africa's Talking on behalf of the client. It will then forward the token to the client which will use it to request, say, the SMS API to send a text. All in a split second! -### Usage +## Usage + +**NOTE:** + + **a)** The code samples seen here are for running a simple server and doing simple API requests. See the advanced section for the list of all methods you can use within the SDK to access the various services. + + **b)** If you plan on integrating the SDK to your android app, please avoid cloning this whole repo. Instead, just follow as instructed in this ReadMe. + +### 1. Server +You can code your server using android studio, eclipse or any other IDE you may deem fit. + +**NOTE** You are not restricted to use Java to code your server. You can instead use Node.js, PHP, C/C++, C#, and all languages supported by gRPC. Visit these links to get the Africa's Talking Node.js SDK to see a template of how your server should look like in Node.js. + +https://github.com/AfricasTalkingLtd/africastalking-node.js + + +**If you are using Java for your server...** + +Whichever IDE you choose to work with, the following need to be done. + +#### a. Download dependencies + +If you are using android studio (or gradle dependencies), add the following code snippet in your build.gradle file (Module: your_server's_module_name) + +```groovy +repositories { + maven { + url "http://dl.bintray.com/africastalking/java" + } +} +dependencies{ + implementation 'com.africastalking:server:VERSION' +} +``` +If you are using Eclipse IDE, or you use Maven dependencies instead, add this code snipppet in your Maven dependencies. + +Maven (from `http://dl.bintray.com/africastalking/java`) + +```xml + + com.africastalking + server + VERSION + +``` + +#### b. Add server side code + +First, import the following library classes in the class you've created to run the server. + +```Java + + import com.africastalking.AfricasTalking; + import com.africastalking.Server; + + import java.io.IOException; + +``` + +Now put this Java code in the class you've created to run your server. Your server application could be something like this: ```java -/* On The Server (Java, Node.js, PHP, C/C++, C# and all languages supported by gRPC.) */ +/* On The Server (Java) */ import com.africastalking.*; public class SomeJavaApplication { + //Save your credentials in static final variables + private static final String USERNAME = "your_username"; //Use "sandbox" if you are testing + + //You can generate this for testing in your Africa's Talking account. + //go to https://account.africastalking.com/apps/sandbox/settings/key + private static final String API_KEY = "your_API_KEY"; + + //Optional + private static final int port = "your_server's_port_number"; + public static void main(String[] args) { // Initialize the SDK @@ -32,81 +101,39 @@ public class SomeJavaApplication { server.addSipCredentials(SIP_USERNAME, SIP_PASSWORD, SIP_HOST); // Start the server - server.start(); - } -} -``` - -And your Android app: - -```java -/* On The Client (Android) */ -public class SomeActivity extends Activity { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(args); - setContentView(R.layout.some_activity); + try{ + server.startInsecure(); + + //Use this if you have provided a port + //server.startInsecure(port); + + //Please see the Advanced section for a list of other functions you can use to start your server + } catch (IOException e){ - // Init SDK - AfricasTalking.initialize(SERVER_HOSTNAME); - - // Get Service - AirtimeService airtime = AfricasTalking.getAirtimeService(); - - // Use Service - airtime.send("+25467675655", "KES", 100, new Callback() { - @Override - void onSuccess(AirtimeResponses responses) { - //... - } - - @Override - void onError(Throwable throwable) { - //... - } - }); + //Do something if server doesn't start + } } } ``` -See the [example](./example) for complete sample apps (Android, Web Java+Node) - -### Download +You may need to add the following code snippet just after **server.startInsecure()**, to ensure your server stays alive until you terminate it (Only add this if you run the above code and the server stops prematurely). For a server set to serve a production application, this may not be necessary. -#### Server - -**Node** - -```shell -npm install --save africastalking +``` +//A loop to help us keep our server online until we terminate it + System.out.println("Press ENTER to exit"); + System.in.read(); ``` -**Java** +This is enough to run your simple server. Now to the android app. -```groovy -repositories { - maven { - url "http://dl.bintray.com/africastalking/java" - } -} -dependencies{ - compile 'com.africastalking:server:VERSION' -} -``` +### 2. Android App -Or Maven (from `http://dl.bintray.com/africastalking/java`) +In your android app, you need to add the following dependencies, and structure your code as shown below. -```xml - - com.africastalking - server - VERSION - -``` +#### a. Add dependencies +Go to the build.gradle file (Module: app [or the name of the module your app's code is in]) and add the following code snippet. -#### Client (Android) ```groovy android { @@ -117,65 +144,353 @@ android { // ... + //ADD THIS ndk { abiFilters "armeabi", "x86" } } } +//ADD THIS repositories { maven { url "http://dl.bintray.com/africastalking/android" } } dependencies{ - compile 'com.africastalking:client:VERSION' + + //ADD THIS + implementation 'com.africastalking:client:VERSION' // or - compile 'com.africastalking:client-ui:VERSION' // with checkout UI for payment + implementation 'com.africastalking:client-ui:VERSION' // with checkout UI for payment +} +``` + +#### b. Add Africa's Talking SDK Code + +First, import the following library classes. + +```Java + + import com.africastalking.AfricasTalking; + + import java.io.IOException; +``` + +Adding the following code snippet in, preferrably, MainActivity (or whatever activity your app launches to). + +```java +/* On The Client (Android) */ +public class SomeActivity extends Activity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(Bundle savedInstanceState); + setContentView(R.layout.some_activity); + + // Initialize SDK + try{ + + AfricasTalking.initialize(SERVER_HOSTNAME); + + //Use this instead if you specified a port for your server + //AfricasTalking.initialize(SERVER_HOSTNAME, port, true); + + //The SERVER_HOSTNAME can be the ip address of your server on the network or a domain name that can be resolved + + }catch (IOException e){ + + //Do something + + } + + // + } } ``` +The code snippet above initializes the SDK. Now, you can use the various Africa's Talking API services as follows: +#### b.1 Airtime Service -## Initialization +Add this code snippet in whatever method or activity you would want to invoke for using the Airtime service. + +Import the following library classes + +```Java + + import com.africastalking.services.AirtimeService; + import com.africastalking.AfricasTalking; + import com.africastalking.models.airtime.AirtimeResponse; + + import java.io.IOException; + +``` + +Write the java code. It may look like this. + +```Java +// Get Service + + try{ + + AirtimeService airtime = AfricasTalking.getAirtimeService(); + + // Use Service + //Will send ksh 100 airtime to +254... + airtime.send("+254...", "KES", 100, new Callback() { + @Override + void onSuccess(AirtimeResponses responses) { + //... + } + + @Override + void onError(Throwable throwable) { + //... + } + }); + + } catch (IOException e){ + + //Do something + + } +``` + +#### b.2 SMS Service + +Add this code snippet in whatever method or activity you would want to invoke for using the SMS service. + +Import the following library classes + +```Java + + import com.africastalking.services.SmsService; + import com.africastalking.AfricasTalking; + import com.africastalking.models.sms.Recipient + + import java.io.IOException; + +``` + +Write the Java code. It may look like this. + +```java + +//Get service + + try{ + + SmsService sms = AfricasTalking.getSmsService(); + + //Will send "Hello" to "+254...". Note that the String is an array, so you can add more numbers to do a bulk + //sms + sms.send("Hello", new String[]{"+254...."}, false, new Callback>() { + @Override + public void onSuccess(List data) { + + //Do something + } + + @Override + public void onFailure(Throwable throwable) { + + //Do something + } + }); + + } catch (IOException e) { + + //Do something + + } + +``` + +#### b.3 Payment Service + +Add this code snippet in whatever method or activity you would want to invoke for using the Payment service. + +Import the following library classes + +```Java + + import com.africastalking.services.PaymentService; + import com.africastalking.AfricasTalking; + import com.africastalking.models.payment.checkout.MobileCheckoutRequest; + import com.africastalking.models.payment.checkout.CheckoutResponse; + + import java.io.IOException; + +``` + +Write the Java code. It may look like this. + +```Java + +//Get service + + try{ + + //get the service + PaymentService payment = AfricasTalking.getPaymentService(); + + //Create the checkout request. You can create a product for testing by visiting + // https://account.africastalking.com/apps/sandbox/payments/products + MobileCheckoutRequest checkoutRequest = new MobileCheckoutRequest("your_product_name", "KES 500",phoneNumber); + + //Checkout + payment.checkout(checkoutRequest, new Callback() { + @Override + public void onSuccess(CheckoutResponse data) { + + //Do something + } + + @Override + public void onFailure(Throwable throwable) { + + //Do something + } + }); + + } catch (IOException e) { + + //Do something + + } + +``` + +#### b.4 Voice Service + +Please find this code provided in the Advanced section + +**NOTE** +See the [example](./example) for complete sample apps (Android, Web Java+Node) + +The code snippets above will allow for simple use of the Android SDK to use Africa's Talking API services. For a full list and description of the methods, classes and functionalities of the android SDK, see the Advanced section below. + + +## Advanced + +This section holds the set of all functions that can be used to perform various tasks in the Android SDK. + +### 1. Server + +#### a. Initialization +The following static method is available on the `AfricasTalking` class to initialize the library, server side. + +- `initialize(String username, String apiKey)`: Initialize the library, passing in the username and apiKey. + +#### b. Start Server +The following methods are available to start your server. + +- `startInsecure()`: Start the server insecurely. + +- `startInsecure(int port)`: Start the server insecurely, providing a port for the server. + +- `start(File certChainFile, File privateKeyFile)`: Start the server securely, providing the certificate and private key. + +- `start(File certChainFile, File privateKeyFile, int port)`: Same as method shown before, but pass in the port to start the server. + +#### c. Add Sip Credentials (Voice Only) + +- `addSipCredentials(String username, String password, String host)`: Add sip credentials. The actual values for the arguments will be provided by Africa's Talking on request of a SIP phone. + +- `addSipCredentials(String username, String password, String host, int port, String transport)`: Add sip credentials, this +time passing in a port, and transport value. The value for transport will be provided by Africa's Talking on request of a SIP phone. + +#### d. Stop server + +- `stop()`: Stop the server. + +### 2. Android + +#### a. Initialization The following static methods are available on the `AfricasTalking` class to initialize the library: -- `initialize(String host, int port, bool disableTLS)`: Initialize the library. +- `initialize(String host)`: Initialize the library, only passing in the server hostname. + +- `initialize(String host, int port)`: Initialize the library, passing in the server hostname and port only. + +- `initialize(String host, int port, bool disableTLS)`: Initialize the library, passing the server hostname, port, and disableTLS boolean option. + +#### b. Services + +##### Get a service + - `getXXXService()`: Get an instance to a given `XXX` service. e.g. `AfricasTalking.getSmsService()`, `AfricasTalking.getPaymentService()`, etc. +**NOTE** +All methods for all services are synchronous (i.e. will block current thread) but provide asynchronous variants that take a `Callback` as the last argument. -## Services +Synchronous variants return a service reponse, asynchronous variants return void. -All methods are synchronous (i.e. will block current thread) but provide asynchronous variants that take a `Callback` as the last argument. +If you use the synchronous variants, then make sure you run them in a separate thread from the main UI thread to prevent your app from crashing, and ensuring that you conform to Android's programming standards (since we are making network calls). -### `Account` +##### b.1 Application Service (For getting user account information - `getUser()`: Get user information. -### `Airtime` +- `getUser(Callback callback)`: asynchronous variant of getUser(). + +##### b.2 Airtime Service -- `send(String phone, String currencyCode, float amount)`: Send airtime to a phone number. +- `send(String phone, String currency, float amount)`: Send airtime to a single phone number. - `send(HashMap recipients)`: Send airtime to a bunch of phone numbers. The keys in the `recipients` map are phone numbers while the values are airtime amounts ( e.g. `KES 678`). -For more information about status notification, please read [http://docs.africastalking.com/airtime/callback](http://docs.africastalking.com/airtime/callback) +- `send(String phone, String currency, float amount, Callback callback)`: Send airtime to a single phone number, with a callback. -### `Token` +- `send(HashMap recipients, Callback callback)`: Send airtime to a bunch of phone numbers, with a callback. + +For more information about status notification, please read [http://docs.africastalking.com/airtime/callback](http://docs.africastalking.com/airtime/callback) + +###### b.3 Token Service - `createCheckoutToken(String phoneNumber)`: Create a checkout token. -### `SMS` +- `createCheckoutToken(String phoneNumber, Callback callback)`: Create a checkout token with a callback response. + +###### b.4 SMS Service + +###### Send an sms to one or more numbers -- `send(String message, String[] recipients)`: Send a message +**NOTE:** Setting enqueue to false means that the message will be sent and you will receive the response immediately. Setting it to true means that the response will be received later after the message was sent. -- `sendBulk(String message, String[] recipients)`: Send a message in bulk +- `send(String message, String[] recipients, boolean enqueue)`: Send a message + +- `send(String message, String[] recipients, boolean enqueue, Callback> callback)`: Send a message, with a callback + +- `send(String message, String from, String[] recipients, boolean enqueue)`: Send a message, passing in the number the message is from. + +- `send(String message, String from, String[] recipients, boolean enqueue, Callback> callback)`: Send a message, passing in the number the message is from, with a callback. + +**Note** "from" is your sms shortcode or alphanumeric name created from your Africa's Talking account. You can create one for testing from: https://account.africastalking.com/apps/sandbox/sms/shortcodes/create + +###### Send premium sms - `sendPremium(String message, String keyword, String linkId, String[] recipients)`: Send a premium SMS -- `fetchMessage()`: Fetch your messages +- `sendPremium(String message, String from, String keyword, String linkId, String[] recipients)`: Send a premium SMS, passing in the number the message is from -- `fetchSubscription(String shortCode, String keyword)`: Fetch your premium subscription data +- `sendPremium(String message, String keyword, String linkId, long retryDurationInHours, String[] recipients)`: Send a premium SMS, passing in the retry duration + +- `sendPremium(String message, String from, String keyword, String linkId, long retryDurationInHours, String[] recipients)`: Send a premium SMS, passing in the retry duration and the number the message is from -- `createSubscription(String shortCode, String keyword, String phoneNumber)`: Create a premium subscription +- `sendPremium(String message, String keyword, String linkId, String[] recipients, Callback> callback)`: Send a premium SMS, with a callback + +- `sendPremium(String message, String from, String keyword, String linkId, String[] recipients, Callback> callback)`: Send a premium SMS, passing in the number the message is from and a callback + +- `sendPremium(String message, String keyword, String linkId, long retryDurationInHours, String[] recipients, Callback> callback)`: Send a premium SMS, passing in the retry duration and callback. + +- `sendPremium(String message, String from, String keyword, String linkId, long retryDurationInHours, String[] recipients, Callback> callback)`: Send a premium SMS,passing in the number the message is from, retry duration, and a callback + +###### Create premium sms subscription + +- `createSubscription(String shortCode, String keyword, String phoneNumber, String checkoutToken)`: Create a premium subscription + +- `createSubscription(String shortCode, String keyword, String phoneNumber, String checkoutToken, Callback callback)`: create a premium sms subscription, with a callback. For more information on: @@ -185,64 +500,229 @@ For more information on: - How to listen for subscription notifications: [http://docs.africastalking.com/subscriptions/callback](http://docs.africastalking.com/subscriptions/callback) -### `Payment` +###### Fetch messages + +- `fetchMessage()`: Fetch your messages + +- `fetchMessage(Callback> callback)`: Fetch your messages, with a callback. + +- `fetchMessage(String lastReceivedId)`: Fetch the last received message + +- `fetchMessage(String lastReceivedId, Callback> callback)`: Fetch the last received message with a callback + +- `fetchSubscription(String shortCode, String keyword)`: Fetch your premium subscription data + +- `fetchSubscription(String shortCode, String keyword, String lastReceivedId)`: Fetch your premium subscription data, for last received message + +- `fetchSubscription(String shortCode, String keyword, Callback> callback)`: Fetch your premium subscription data, with a callback + +- `fetchSubscription(String shortCode, String keyword, String lastReceivedId)`: Fetch your premium subscription data, for last received message, with a callback + +###### b.5 Payment - `checkout(CheckoutRequest request)`: Initiate checkout(mobile, card or bank). +- `checkout(CheckoutRequest request, Callback callback)`: Initiate checkout(mobile, card or bank), with a callback. + - `validateCheckout(CheckoutValidateRequest request)`: Validate checkout (card or bank). +- `validateCheckout(CheckoutValidateRequest request, Callback callback)`: Validate checkout (card or bank), with a callback. + - `mobileB2C(String productName, List recipients)`: Send money to consumer. +- `mobileB2C(String productName, List recipients, Callback callback)`: Send money to consumer, with a callback. + - `mobileB2B(String productName, Business recipient)`: Send money to business. -- `bankTransfer(String productName, List recipients)`: Move money form payment wallet to bank account. +- `mobileB2B(String productName, Business recipient, Callback callback)`: Send money to business, with a callback. + +- `bankTransfer(String productName, List recipients)`: Move money from payment wallet to bank account. -### Voice +- `bankTransfer(String productName, List recipients, Callback callback)`: Move money from payment wallet to bank account, with a callback. + +###### b.6 Voice + +To use the voice service, you'll need to import the following libraries. + +```java + + import com.africastalking.AfricasTalking; + import com.africastalking.AfricasTalkingException; //handling exceptions + import com.africastalking.utils.Callback; + import com.africastalking.utils.Logger; //Used for logging + + import com.africastalking.services.VoiceService; + import com.africastalking.utils.voice.CallInfo; + import com.africastalking.utils.voice.CallListener; + import com.africastalking.utils.voice.RegistrationListener; + +``` Unlike other services, voice is initialized as follows: ```java -AfricasTalking.initializeVoiceService(Context cxt, RegistrationListener listener, new Callback() { - @Override - public void onSuccess(VoiceService service) { - // keep a reference to the 'service' - } +try{ + + AfricasTalking.initializeVoiceService(Context cxt, RegistrationListener listener, new Callback() { + @Override + public void onSuccess(VoiceService service) { + // keep a reference to the 'service' + mService = service; + } + + @Override + public void onFailure(Throwable throwable) { + // something blew up + } + }); + + } catch (Exception ex){ + //failed to initialize + } +``` + +The following listeners are needed: + +**i. Registration listener** + +```java + + RegistrationListener listener = new RegistrationListener() { + @Override + public void onError(Throwable error) { + + //handle error in registering to the SIP server + } + + @Override + public void onStarting() { + + //registration starting + } + + @Override + public void onComplete() { + + //register call listener + mService.registerCallListener(mCallListener); + + //register logger + mService.registerLogger(mLogger); + + //mCallListener is an instance of CallListener. It's instantiated below + } + }; - @Override - public void onFailure(Throwable throwable) { - // something blew up - } -}); ``` +**ii. Call Listener** + +```java + + private CallListener mCallListener = new CallListener() { + @Override + public void onCallBusy(CallInfo call) { + + //Do something + } + + @Override + public void onError(CallInfo call, final int errorCode, final String errorMessage) { + + //Do something based on error + } + + @Override + public void onRinging(final CallInfo callInfo) { + + //Do something + } + + @Override + public void onRingingBack(final CallInfo call) { + + //Do something + } + + @Override + public void onCallEstablished(CallInfo call) { + + //The call has been established. So, start audio + mService.startAudio(); + mService.setSpeakerMode(VoiceActivity.this, false); + + // show in-call ui + //Probably set up an activity or fragment to do this + } + + @Override + public void onCallEnded(CallInfo call) { + + //Handle the end of the call + } + + @Override + public void onIncomingCall(CallInfo callInfo) { + + //Do something. + //You can show in-call UI here, + } + }; + + +``` + +You can optionally set up a logger as follows: + +```Java + + private Logger logger = new Logger() { + @Override + public void log(String message, Object... args) { + //Log the messages + Timber.d(message, args); + } + }; + +``` + +The following methods may be of use in using the Voice Service in the SDK. They belong to the VoiceService class. + +- `registerCallListener(CallListener listener)`: register the call listener + +- `unregisterCallListener(CallListener listener)`: unregister the call listener + +- `registerLogger(Logger logger)`: register the logger + +- `unregisterLogger(Logger logger)`: unregister the logger -- `registerCallListener(CallListener listener)`: +- `makeCall(String phoneNumber)`: make a phone call -- `makeCall(String phoneNumber)`: +- `pickCall()`: pick a call -- `picCall()`: +- `holdCall()`: hold a call -- `holdCall()`: +- `resumeCall()`: resume a held call -- `resumeCall()`: +- `endCall()`: end a call -- `endCall()`: +- `sendDtmf(char character)`: send the dialpad character the user has pressed -- `sendDtmf(char character)`: +- `startAudio()`: initiate the phone speaker to start audio -- `startAudio()`: +- `toggleMute()`: mute or unmute a call -- `toggleMute()`: +- `setSpeakerMode(Context context, boolean loudSpeaker)`: toggle between using the loudspeaker and not -- `setSpeakerMode(Context context, boolean loudSpeaker)`: +- `isCallInProgress()`: returns a boolean indicating whether a call is in progress or not -- `isCallInProgress()`: +- `getCallInfo()`: get an instance of CallInfo -- `getCallInfo()` +- `destroyService()`: destroy the voice service -- `queueStatus(String phoneNumbers)`: +You can get an instance of the voice service using the following static method of the Africa's Talking class -- `mediaUpload(String url)`: +- `getVoiceService()`: get an instance of the voice service From 6ae8c94288ed8ec7983289e592cca6a557d249f3 Mon Sep 17 00:00:00 2001 From: Ian-Cornelius <41118653+Ian-Cornelius@users.noreply.github.com> Date: Tue, 20 Nov 2018 17:04:55 +0300 Subject: [PATCH 24/24] Update README.md --- README.md | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 15378cd..df579d1 100755 --- a/README.md +++ b/README.md @@ -189,22 +189,13 @@ public class SomeActivity extends Activity { setContentView(R.layout.some_activity); // Initialize SDK - try{ - - AfricasTalking.initialize(SERVER_HOSTNAME); - //Use this instead if you specified a port for your server - //AfricasTalking.initialize(SERVER_HOSTNAME, port, true); + AfricasTalking.initialize(SERVER_HOSTNAME); - //The SERVER_HOSTNAME can be the ip address of your server on the network or a domain name that can be resolved - - }catch (IOException e){ - - //Do something - - } - - // + //Use this instead if you specified a port for your server + //AfricasTalking.initialize(SERVER_HOSTNAME, port, true); + + //The SERVER_HOSTNAME can be the ip address of your server on the network or a domain name that can be resolved } } ```