diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5edb4ee
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
new file mode 100644
index 0000000..ad97ff4
Binary files /dev/null and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..7ac24c7
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..dc34569
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..d4ea1c9
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,51 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 27
+ defaultConfig {
+ applicationId "com.example.ian.sambazaquick"
+ minSdkVersion 19
+ targetSdkVersion 27
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.android.support:appcompat-v7:27.1.1'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ implementation 'com.google.firebase:firebase-auth:11.6.0'
+ implementation 'com.google.firebase:firebase-database:11.6.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+ implementation 'com.google.android.gms:play-services:12.0.1'
+ implementation 'com.google.firebase:firebase-core:11.6.0'
+ implementation files('json-20090211.jar')
+}
+
+allprojects{
+ repositories {
+ //...
+ }
+
+ subprojects {
+ project.configurations.all {
+ resolutionStrategy.eachDependency{details ->
+ if (details.requested.group == 'com.google.android.gms' && !details.requested.name.contains('multidex')){
+ details.useVersion "12.0.1"
+ }
+ }
+ }
+ }
+}
+
+apply plugin: 'com.google.gms.google-services'
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100644
index 0000000..9a8366e
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,55 @@
+{
+ "project_info": {
+ "project_number": "830949487098",
+ "firebase_url": "https://sambazaquick.firebaseio.com",
+ "project_id": "sambazaquick",
+ "storage_bucket": "sambazaquick.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:830949487098:android:73bdf9f61bc2d933",
+ "android_client_info": {
+ "package_name": "com.example.ian.sambazaquick"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "830949487098-ph7npqgq33rj7vh10nt7choddmcbvqs5.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.example.ian.sambazaquick",
+ "certificate_hash": "5cdbfb6243abcaa938a4affb1fb42464d47a4764"
+ }
+ },
+ {
+ "client_id": "830949487098-udensv1lig1q0eki0ru9pk46pito5166.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyBYIG0z2Yl_t0W3f9dsmHlq9vQ0OHUwGfU"
+ }
+ ],
+ "services": {
+ "analytics_service": {
+ "status": 1
+ },
+ "appinvite_service": {
+ "status": 2,
+ "other_platform_oauth_client": [
+ {
+ "client_id": "830949487098-udensv1lig1q0eki0ru9pk46pito5166.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ },
+ "ads_service": {
+ "status": 2
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/json-20090211.jar b/app/json-20090211.jar
new file mode 100644
index 0000000..ef29094
Binary files /dev/null and b/app/json-20090211.jar differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/com/example/ian/sambazaquick/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/ian/sambazaquick/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..9e9c633
--- /dev/null
+++ b/app/src/androidTest/java/com/example/ian/sambazaquick/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.ian.sambazaquick;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.ian.sambazaquick", appContext.getPackageName());
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..193fadc
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/example/ian/sambazaquick/AddNewContactsFragment.java b/app/src/main/java/com/example/ian/sambazaquick/AddNewContactsFragment.java
new file mode 100644
index 0000000..60661c4
--- /dev/null
+++ b/app/src/main/java/com/example/ian/sambazaquick/AddNewContactsFragment.java
@@ -0,0 +1,158 @@
+package com.example.ian.sambazaquick;
+
+import android.app.ProgressDialog;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.Fragment;
+
+//for firebase database access
+import com.google.android.gms.tasks.OnCompleteListener;
+import com.google.android.gms.tasks.Task;
+import com.google.firebase.database.FirebaseDatabase;
+import com.google.firebase.database.DatabaseReference;
+
+//for firebase authentication to get
+import com.google.firebase.auth.FirebaseAuth;
+
+//for our UI widgets
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Button;
+import android.widget.Toast;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+
+public class AddNewContactsFragment extends Fragment {
+
+ //for our db references
+ private DatabaseReference mDbRef;
+
+ //for getting our current user
+ private FirebaseAuth mAuth;
+
+ //for our UI widgets
+ private ImageButton mBtnBck;
+ private EditText mEditName, mEditPhone;
+ private Button mBtnAdd;
+ private TextView mTxtShwName, mTxtShwNo;
+ private ProgressDialog progressDialog;
+
+ //Override onCreate and initialize our DatabaseReference here
+ @Override
+ public void onCreate (Bundle savedInstanceState){
+ super.onCreate(savedInstanceState);
+
+ mDbRef = FirebaseDatabase.getInstance().getReference();
+ mAuth = FirebaseAuth.getInstance();
+ }
+
+ //Now, to load our UI and wire it up
+ @Override
+ public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
+
+ //remove previous views
+ container.removeAllViews();
+
+ //load our UI
+ View view = inflater.inflate(R.layout.add_contacts_fragment,container,false);
+
+ //get widget references
+ mBtnBck = view.findViewById(R.id.btnBack);
+ mEditName = view.findViewById(R.id.editName);
+ mEditPhone = view.findViewById(R.id.editPhone);
+ mBtnAdd = view.findViewById(R.id.btnAdd);
+ mTxtShwName = view.findViewById(R.id.shwName);
+ mTxtShwNo = view.findViewById(R.id.shwPhoneNo);
+
+ progressDialog = new ProgressDialog(getContext());
+
+ //Wire up click event listeners
+ mBtnBck.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //load the main screen fragment
+ getFragmentManager().beginTransaction().replace(R.id.fragmentHolder,new HomeScreenFragment()).commit();
+ }
+ });
+
+ mBtnAdd.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //attempt to save the data
+ saveContact();
+ }
+ });
+
+ return view;
+ }
+
+ //method to save our contacts on the online db
+ public void saveContact(){
+
+ //make sure the form has no blanks
+ if (TextUtils.isEmpty(mEditName.getText().toString()) || TextUtils.isEmpty(mEditPhone.getText().toString())){
+
+ //Show error message based on exact error
+ if (TextUtils.isEmpty(mEditName.getText().toString())){
+ Toast.makeText(getContext(),"Please key in a name",Toast.LENGTH_LONG).show();
+ }
+ if (TextUtils.isEmpty(mEditPhone.getText().toString())){
+ Toast.makeText(getContext(),"Please key in the phone number",Toast.LENGTH_LONG).show();
+ }
+ }else{ //data set is okay
+
+ //show saving progress dialog
+ progressDialog.setMessage("Saving contact...");
+ progressDialog.setCanceledOnTouchOutside(false);
+
+ //create a hash to save this data
+ HashMap contactData = new HashMap<>();
+ contactData.put("Name",mEditName.getText().toString());
+ contactData.put("Phone Number", mEditPhone.getText().toString());
+
+ //Now send it to FirebaseDB
+ //Interesting thing learnt. Putting / jumps us to a new child.
+ //To use authentication, make sure you've enabled identity toolkit in Google APIs console
+ mDbRef.child(mAuth.getCurrentUser().getUid() + "_contacts").child("save_" + new SimpleDateFormat("dd-MM-yy HH:mm:ss").format(new Date()))
+ .setValue(contactData).addOnCompleteListener(new OnCompleteListener() {
+ @Override
+ public void onComplete(@NonNull Task task) {
+
+ if (task.isSuccessful()){
+
+ //dismiss dialog
+ progressDialog.dismiss();
+
+ //show success toast
+ Toast.makeText(getContext(),"Contact added successfully",Toast.LENGTH_LONG).show();
+
+ //update the text view widgets
+ mTxtShwName.setText(mEditName.getText().toString());
+ mTxtShwNo.setText(mEditPhone.getText().toString());
+
+ //clear the edit text widgets
+ mEditName.setText("");
+ mEditPhone.setText("");
+
+ } else{
+
+ //dismiss dialog
+ progressDialog.dismiss();
+
+ //show error message
+ Toast.makeText(getContext(),"Failed to add contact. Please check your internet connection",Toast.LENGTH_LONG).show();
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/ian/sambazaquick/AfricasTalkingGateway.java b/app/src/main/java/com/example/ian/sambazaquick/AfricasTalkingGateway.java
new file mode 100644
index 0000000..08e5a62
--- /dev/null
+++ b/app/src/main/java/com/example/ian/sambazaquick/AfricasTalkingGateway.java
@@ -0,0 +1,516 @@
+package com.example.ian.sambazaquick;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class AfricasTalkingGateway
+{
+ private String _username;
+ private String _apiKey;
+ private String _environment;
+ private int responseCode;
+
+ private static final int HTTP_CODE_OK = 200;
+ private static final int HTTP_CODE_CREATED = 201;
+
+ //Change debug flag to true to view raw server response
+ private static final boolean DEBUG = false;
+
+ public AfricasTalkingGateway(String username_, String apiKey_)
+ {
+ _username = username_;
+ _apiKey = apiKey_;
+ _environment = "production";
+ }
+
+ public AfricasTalkingGateway(String username_, String apiKey_, String environment_)
+ {
+ _username = username_;
+ _apiKey = apiKey_;
+ _environment = environment_;
+ }
+
+
+ //Bulk messages methods
+ public JSONArray sendMessage(String to_, String message_) throws Exception
+ {
+
+ HashMap data = new HashMap();
+ data.put("username", _username);
+ data.put("to", to_);
+ data.put("message", message_);
+
+ return sendMessageImpl(to_, message_, data);
+ }
+
+
+ public JSONArray sendMessage(String to_, String message_, String from_) throws Exception
+ {
+ HashMap data = new HashMap();
+ data.put("username", _username);
+ data.put("to", to_);
+ data.put("message", message_);
+
+ if ( from_.length() > 0 ) data.put("from", from_);
+
+ return sendMessageImpl(to_, message_, data);
+ }
+
+
+ public JSONArray sendMessage(String to_, String message_, String from_, int bulkSMSMode_) throws Exception
+ {
+ HashMap data = new HashMap();
+ data.put("username", _username);
+ data.put("to", to_);
+ data.put("message", message_);
+
+ if ( from_.length() > 0 ) data.put("from", from_);
+
+ data.put("bulkSMSMode", Integer.toString(bulkSMSMode_));
+
+ return sendMessageImpl(to_, message_, data);
+ }
+
+
+ public JSONArray sendMessage(String to_, String message_, String from_, int bulkSMSMode_, HashMap options_) throws Exception
+ {
+ HashMap data = new HashMap();
+ data.put("username", _username);
+ data.put("to", to_);
+ data.put("message", message_);
+
+ if ( from_.length() > 0 ) data.put("from", from_);
+
+ data.put("bulkSMSMode", Integer.toString(bulkSMSMode_));
+
+
+ if (options_.containsKey("enqueue")) data.put("enqueue", options_.get("enqueue"));
+ if (options_.containsKey("keyword")) data.put("keyword", options_.get("keyword"));
+ if (options_.containsKey("linkId")) data.put("linkId", options_.get("linkId"));
+ if (options_.containsKey("retryDurationInHours")) data.put("retryDurationInHours", options_.get("retryDurationInHours"));
+
+ return sendMessageImpl(to_, message_, data);
+ }
+
+
+ public JSONArray fetchMessages(int lastReceivedId_) throws Exception
+ {
+ String requestUrl = getSmsUrl() + "?" +
+ URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(_username, "UTF-8") +
+ "&" + URLEncoder.encode("lastReceivedId", "UTF-8") + "=" + URLEncoder.encode(Integer.toString(lastReceivedId_), "UTF-8");
+
+ String response = sendGETRequest(requestUrl);
+ if(responseCode == HTTP_CODE_OK) {
+ JSONObject jsObject = new JSONObject(response);
+ return jsObject.getJSONObject("SMSMessageData").getJSONArray("Messages");
+ }
+
+ throw new Exception(response.toString());
+ }
+
+
+ //Subcscription methods
+ public JSONObject createSubscription(String phoneNumber_, String shortCode_, String keyword_) throws Exception
+ {
+ if(phoneNumber_.length() == 0 || shortCode_.length() == 0 || keyword_.length() == 0)
+ throw new Exception("Please supply phoneNumber, shortCode and keyword");
+
+ HashMap data_ = new HashMap();
+ data_.put("username", _username);
+ data_.put("phoneNumber", phoneNumber_);
+ data_.put("shortCode", shortCode_);
+ data_.put("keyword", keyword_);
+ String requestUrl = getSubscriptionUrl() + "/create";
+
+ String response = sendPOSTRequest(data_, requestUrl);
+
+ if(responseCode != HTTP_CODE_CREATED)
+ throw new Exception(response.toString());
+
+ JSONObject jsObject = new JSONObject(response);
+ return jsObject;
+ }
+
+
+ public JSONObject deleteSubscription(String phoneNumber_,String shortCode_, String keyword_) throws Exception
+ {
+ if(phoneNumber_.length() == 0 || shortCode_.length() == 0 || keyword_.length() == 0)
+ throw new Exception("Please supply phone number, short code and keyword");
+
+ HashMap data_ = new HashMap();
+ data_.put("username", _username);
+ data_.put("phoneNumber", phoneNumber_);
+ data_.put("shortCode", shortCode_);
+ data_.put("keyword", keyword_);
+ String requestUrl = getSubscriptionUrl() + "/delete";
+
+ String response = sendPOSTRequest(data_, requestUrl);
+
+ if(responseCode != HTTP_CODE_CREATED)
+ throw new Exception(response.toString());
+
+ JSONObject jsObject = new JSONObject(response);
+ return jsObject;
+ }
+
+
+ public JSONArray fetchPremiumSubscriptions (String shortCode_, String keyword_, int lastReceivedId_) throws Exception
+ {
+ if(shortCode_.length() == 0 || keyword_.length() == 0)
+ throw new Exception("Please supply short code and keyword");
+
+ lastReceivedId_ = lastReceivedId_ > 0? lastReceivedId_ : 0;
+ String requestUrl = getSubscriptionUrl() + "?username="+_username+"&shortCode="+shortCode_+"&keyword="+keyword_+"&lastReceivedId="+lastReceivedId_;
+
+ String response = sendGETRequest(requestUrl);
+ if(responseCode == HTTP_CODE_OK) {
+ JSONObject jsObject = new JSONObject(response);
+ return jsObject.getJSONArray("responses");
+ }
+
+ throw new Exception(response.toString());
+ }
+
+
+ public JSONArray call(String from_, String to_) throws Exception
+ {
+ HashMap data = new HashMap();
+ data.put("username", _username);
+ data.put("from", from_);
+ data.put("to", to_);
+ String urlString = getVoiceUrl() + "/call";
+ String response = sendPOSTRequest(data, urlString);
+
+ JSONObject jsObject = new JSONObject(response);
+
+ if(jsObject.getString("errorMessage").equals("None"))
+ return jsObject.getJSONArray("entries");
+ throw new Exception(jsObject.getString("errorMessage"));
+ }
+
+ //Call methods
+ public JSONArray getNumQueuedCalls(String phoneNumber, String queueName) throws Exception
+ {
+ HashMap data = new HashMap();
+ data.put("username", _username);
+ data.put("phoneNumber", phoneNumber);
+ data.put("queueName", queueName);
+
+ return queuedCalls(data);
+ }
+
+
+ public JSONArray getNumQueuedCalls(String phoneNumber) throws Exception
+ {
+ HashMap data = new HashMap();
+ data.put("username", _username);
+ data.put("phoneNumbers", phoneNumber);
+
+ return queuedCalls(data);
+ }
+
+
+ public void uploadMediaFile(String url_, String phoneNumber_) throws Exception
+ {
+ HashMap data = new HashMap();
+ data.put("username", _username);
+ data.put("url", url_);
+ data.put("phoneNumber", phoneNumber_);
+ String requestUrl = getVoiceUrl() + "/mediaUpload";
+
+ sendPOSTRequest(data, requestUrl);
+ }
+
+
+ //Airtime methods
+ public JSONArray sendAirtime(String recipients_) throws Exception
+ {
+ HashMap data_ = new HashMap();
+ data_.put("username", _username);
+ data_.put("recipients", recipients_);
+ String urlString = getAirtimeUrl() + "/send";
+
+ String response = sendPOSTRequest(data_, urlString);
+
+ if(responseCode == HTTP_CODE_CREATED) {
+ JSONObject jsObject = new JSONObject(response);
+ JSONArray results = jsObject.getJSONArray("responses");
+ if(results.length() > 0)
+ return results;
+ throw new Exception(jsObject.getString("errorMessage"));
+ }
+
+ throw new Exception(response);
+ }
+
+
+ //User data method
+ public JSONObject getUserData() throws Exception
+ {
+ String requestUrl = getUserDataUrl() + "?username="+_username;
+
+ String response = sendGETRequest(requestUrl);
+ if(responseCode == HTTP_CODE_OK) {
+ JSONObject jsObject = new JSONObject(response);
+ return jsObject.getJSONObject("UserData");
+ }
+
+ throw new Exception(response);
+ }
+
+ public JSONObject initiateMobilePaymentCheckout(String productName_,
+ String phoneNumber_,
+ String currencyCode_,
+ Double amount_,
+ Map metadata_) throws Exception
+ {
+ JSONObject requestBody = new JSONObject()
+ .put("username", _username)
+ .put("productName", productName_)
+ .put("phoneNumber", phoneNumber_)
+ .put("currencyCode", currencyCode_)
+ .put("amount", amount_)
+ .put("metadata", metadata_);
+ String response = sendJsonPOSTRequest(requestBody.toString(), getMobilePaymentCheckoutUrl());
+ return new JSONObject(response);
+ }
+
+ public JSONArray mobilePaymentB2CRequest(String productName_,
+ List recipients_) throws Exception
+ {
+ List jsonRecipients = new ArrayList();
+ for (MobilePaymentB2CRecipient recipient: recipients_) {
+ jsonRecipients.add(recipient.toJSON());
+ }
+ JSONObject requestBody = new JSONObject()
+ .put("username", _username)
+ .put("productName", productName_)
+ .put("recipients", jsonRecipients);
+
+ if(DEBUG) System.out.println("Raw Request: " + requestBody.toString());
+
+ String response = sendJsonPOSTRequest(requestBody.toString(), getMobilePaymentB2CUrl());
+ JSONObject jsonResponse = new JSONObject(response);
+ JSONArray entries = jsonResponse.getJSONArray("entries");
+ if ( entries.length() > 0 ) return entries;
+ throw new Exception(jsonResponse.getString("errorMessage"));
+ }
+
+ public JSONObject mobilePaymentB2BRequest(String productName_, HashMap providerData_,
+ String currencyCode_, float amount_, HashMap metadata_) throws Exception
+ {
+ if(!providerData_.containsKey("provider"))
+ throw new Exception("Missing field provider");
+
+ if(!providerData_.containsKey("destinationChannel"))
+ throw new Exception("Missing field destinationChannel");
+
+ if(!providerData_.containsKey("destinationAccount"))
+ throw new Exception("Missing field destinationAccount");
+
+ if(!providerData_.containsKey("transferType"))
+ throw new Exception("Missing field transferType");
+
+ JSONObject requestBody = new JSONObject();
+ requestBody.put("username", _username);
+ requestBody.put("productName", productName_);
+ requestBody.put("currencyCode", currencyCode_);
+ requestBody.put("amount", amount_);
+ requestBody.put("provider", providerData_.get("provider"));
+ requestBody.put("destinationChannel", providerData_.get("destinationChannel"));
+ requestBody.put("destinationAccount", providerData_.get("destinationAccount"));
+ requestBody.put("transferType", providerData_.get("transferType"));
+ requestBody.put("metadata", new JSONObject(metadata_));
+
+ if(DEBUG) System.out.println("Raw Request: " + requestBody.toString());
+
+ String response = sendJsonPOSTRequest(requestBody.toString(), getMobilePaymentB2BUrl());
+ JSONObject jsonResponse = new JSONObject(response);
+ return jsonResponse;
+ }
+
+ private JSONArray sendMessageImpl(String to_, String message_, HashMap data_) throws Exception {
+ String response = sendPOSTRequest(data_, getSmsUrl());
+ if (responseCode == HTTP_CODE_CREATED) {
+ JSONObject jsObject = new JSONObject(response);
+ JSONArray recipients = jsObject.getJSONObject("SMSMessageData").getJSONArray("Recipients");
+ if(recipients.length() > 0) return recipients;
+
+ throw new Exception(jsObject.getJSONObject("SMSMessageData").getString("Message"));
+ }
+
+ throw new Exception(response);
+ }
+
+ //Private accessor methods
+ private JSONArray queuedCalls(HashMap data_) throws Exception {
+ String requestUrl = getVoiceUrl() + "/queueStatus";
+ String response = sendPOSTRequest(data_, requestUrl);
+ JSONObject jsObject = new JSONObject(response);
+ if(jsObject.getString("errorMessage").equals("None"))
+ return jsObject.getJSONArray("entries");
+ throw new Exception(jsObject.getString("errorMessage"));
+ }
+
+ private String sendPOSTRequest(HashMap dataMap_, String urlString_) throws Exception {
+ String data = new String();
+ Iterator> it = dataMap_.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry pairs = (Map.Entry)it.next();
+ data += URLEncoder.encode(pairs.getKey().toString(), "UTF-8");
+ data += "=" + URLEncoder.encode(pairs.getValue().toString(), "UTF-8");
+ if ( it.hasNext() ) data += "&";
+ }
+ URL url = new URL(urlString_);
+ URLConnection conn = url.openConnection();
+ conn.setRequestProperty("Accept", "application/json");
+ conn.setRequestProperty("apikey", _apiKey);
+ conn.setDoOutput(true);
+ return sendPOSTRequestImpl(data, conn);
+ }
+
+ private String sendJsonPOSTRequest(String data_, String urlString_) throws Exception
+ {
+ URL url = new URL(urlString_);
+ URLConnection conn = url.openConnection();
+ conn.setRequestProperty("Content-Type", "application/json");
+ conn.setRequestProperty("Accept", "application/json");
+ conn.setRequestProperty("apikey", _apiKey);
+ conn.setDoOutput(true);
+ return sendPOSTRequestImpl(data_, conn);
+ }
+
+ private String sendPOSTRequestImpl(String data_, URLConnection conn_) throws Exception {
+ try {
+ OutputStreamWriter writer = new OutputStreamWriter(conn_.getOutputStream());
+ writer.write(data_);
+ writer.flush();
+
+ HttpURLConnection http_conn = (HttpURLConnection)conn_;
+ responseCode = http_conn.getResponseCode();
+
+ BufferedReader reader;
+ boolean passed = true;
+
+ if(responseCode == HTTP_CODE_OK || responseCode == HTTP_CODE_CREATED) {
+ reader = new BufferedReader(new InputStreamReader(http_conn.getInputStream()));
+ }
+ else {
+ reader = new BufferedReader(new InputStreamReader(http_conn.getErrorStream()));
+ passed = false;
+ }
+ String response = readResponse(reader);
+
+ if(DEBUG) System.out.println("ResponseCode: " + responseCode + " RAW Response: " + response);
+
+ reader.close();
+
+ if(passed) return response;
+
+ throw new Exception(response);
+
+ } catch (Exception e){
+ throw e;
+ }
+ }
+
+ private String readResponse(BufferedReader reader) throws Exception
+ {
+ StringBuilder response = new StringBuilder();
+ String line;
+ while((line = reader.readLine()) != null) {
+ response.append(line);
+ }
+ return response.toString();
+ }
+
+ private String sendGETRequest(String urlString) throws Exception
+ {
+ try {
+ URL url= new URL(urlString);
+ URLConnection connection = (URLConnection)url.openConnection();
+ connection.setRequestProperty("Accept","application/json");
+ connection.setRequestProperty("apikey", _apiKey);
+
+ HttpURLConnection http_conn = (HttpURLConnection)connection;
+ responseCode = http_conn.getResponseCode();
+
+ BufferedReader reader;
+ boolean passed = true;
+ if(responseCode == HTTP_CODE_OK || responseCode == HTTP_CODE_CREATED) {
+ reader = new BufferedReader(new InputStreamReader(http_conn.getInputStream()));
+ }
+ else {
+ reader = new BufferedReader(new InputStreamReader(http_conn.getErrorStream()));
+ passed = false;
+ }
+ String response = reader.readLine();
+
+ if(DEBUG) System.out.println(response);
+
+ reader.close();
+
+ if(passed) return response;
+
+ throw new Exception(response);
+ }
+ catch (Exception e) {throw e;}
+ }
+
+ private String getApiHost() {
+ return (_environment == "sandbox") ? "https://api.sandbox.africastalking.com" : "https://api.africastalking.com";
+ }
+
+ private String getPaymentHost() {
+ return (_environment == "sandbox") ? "https://payments.sandbox.africastalking.com" : "https://payments.africastalking.com";
+ }
+
+ private String getVoiceHost() {
+ return (_environment == "sandbox") ? "https://voice.sandbox.africastalking.com" : "https://voice.africastalking.com";
+ }
+
+ private String getSmsUrl() {
+ return getApiHost() + "/version1/messaging";
+ }
+
+ private String getVoiceUrl() {
+ return getVoiceHost();
+ }
+
+ private String getSubscriptionUrl() {
+ return getApiHost() + "/version1/subscription";
+ }
+
+ private String getUserDataUrl() {
+ return getApiHost() + "/version1/user";
+ }
+
+ private String getAirtimeUrl() {
+ return getApiHost() + "/version1/airtime";
+ }
+
+ private String getMobilePaymentCheckoutUrl() {
+ return getPaymentHost() + "/mobile/checkout/request";
+ }
+
+ private String getMobilePaymentB2BUrl() {
+ return getPaymentHost() + "/mobile/b2b/request";
+ }
+
+ private String getMobilePaymentB2CUrl() {
+ return getPaymentHost() + "/mobile/b2c/request";
+ }
+}
diff --git a/app/src/main/java/com/example/ian/sambazaquick/HomeScreenFragment.java b/app/src/main/java/com/example/ian/sambazaquick/HomeScreenFragment.java
new file mode 100644
index 0000000..74ed0f3
--- /dev/null
+++ b/app/src/main/java/com/example/ian/sambazaquick/HomeScreenFragment.java
@@ -0,0 +1,85 @@
+package com.example.ian.sambazaquick;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+
+//For firebase authentication, to log the user out
+import com.google.firebase.auth.FirebaseAuth;
+
+//For our UI
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+public class HomeScreenFragment extends Fragment {
+
+ //For our UI
+ private Button mBtnAddNewContacts, mBtnSendAirtime, mBtnLogOut;
+
+ //For firebase authentication
+ private FirebaseAuth mAuth;
+
+ //initialize mAuth in onCreate
+ @Override
+ public void onCreate(Bundle savedInstanceState){
+ super.onCreate(savedInstanceState);
+
+ mAuth = FirebaseAuth.getInstance();
+ }
+
+ //Override onCreateView and load UI, wire it up
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
+
+ //remove previous views
+ container.removeAllViews();
+
+ //inflate UI
+ View view = inflater.inflate(R.layout.mainpage_fragment,container,false);
+
+ //get references to our widgets
+ mBtnAddNewContacts = view.findViewById(R.id.btnAddNewContacts);
+ mBtnSendAirtime = view.findViewById(R.id.btnSendAirtime);
+ mBtnLogOut = view.findViewById(R.id.btnLogOut);
+
+ //wire up click event listeners
+ mBtnAddNewContacts.setOnClickListener(new View.OnClickListener(){
+ @Override
+ public void onClick (View v){
+
+ //load the add new contacts fragment
+ getFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in,R.anim.fade_out).replace(R.id.fragmentHolder,new AddNewContactsFragment()).commit();
+ }
+ });
+
+ mBtnSendAirtime.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //load the send airtime fragment
+ getFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in,R.anim.fade_out).replace(R.id.fragmentHolder,new SendAirtimeFragment()).commit();
+ }
+ });
+
+ mBtnLogOut.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //invoke method to logout user
+ logoutUser();
+ }
+ });
+
+ return view;
+ }
+
+ //method to log out user
+ private void logoutUser(){
+
+ mAuth.signOut();
+
+ //load log in fragment
+ getFragmentManager().beginTransaction().replace(R.id.fragmentHolder,new LogInFragment()).commit();
+ }
+}
diff --git a/app/src/main/java/com/example/ian/sambazaquick/LogInFragment.java b/app/src/main/java/com/example/ian/sambazaquick/LogInFragment.java
new file mode 100644
index 0000000..6ad79e6
--- /dev/null
+++ b/app/src/main/java/com/example/ian/sambazaquick/LogInFragment.java
@@ -0,0 +1,139 @@
+package com.example.ian.sambazaquick;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+
+import android.app.ProgressDialog;
+import android.support.annotation.NonNull;
+
+//For our UI widgets
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.Button;
+import android.widget.Toast;
+
+//For our firebase authentication
+import com.google.android.gms.tasks.OnCompleteListener;
+import com.google.android.gms.tasks.Task;
+import com.google.firebase.auth.AuthResult;
+import com.google.firebase.auth.FirebaseAuth;
+import com.google.firebase.auth.FirebaseUser;
+
+public class LogInFragment extends Fragment {
+
+ //For our firebase authentication
+ private FirebaseAuth mAuth;
+
+ //For our UI widgets
+ private EditText mEditEmail, mEditPass;
+ private Button mBtnLogIn, mBtnSignUp;
+ private ProgressDialog progressDialog;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ //instantiate FirebaseAuth
+ mAuth = FirebaseAuth.getInstance();
+
+ //go direct to homepage if we have a current user logged in
+ if (mAuth.getCurrentUser() != null) {
+
+ //load the home screen fragment
+ getFragmentManager().beginTransaction().setCustomAnimations(R.anim.bottom_top, R.anim.top_bottom).replace(R.id.fragmentHolder, new HomeScreenFragment()).commit();
+
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+
+ //remove previous views
+ container.removeAllViews();
+
+ //inflate our UI
+ View view = inflater.inflate(R.layout.log_in_fragment, container,false);
+ //instantiate our UI widgets
+ mEditEmail = view.findViewById(R.id.editEmail);
+ mEditPass = view.findViewById(R.id.editPass);
+ mBtnLogIn = view.findViewById(R.id.loginBtn);
+ mBtnSignUp = view.findViewById(R.id.signupBtn);
+ progressDialog = new ProgressDialog(getContext());
+
+ //Set up click event listeners for log in button and sign up button
+ mBtnLogIn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //attempt logging in the user
+ logInUser();
+ }
+ });
+
+ mBtnSignUp.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //load the sign up fragment
+ getFragmentManager().beginTransaction().setCustomAnimations(R.anim.right_left, R.anim.expand_left_right).replace(R.id.fragmentHolder, new SignUpFragment()).commit();
+ }
+ });
+
+ return view;
+ }
+
+ //Function to log in user
+ private void logInUser() {
+
+ //get the email and password put in
+ String email = mEditEmail.getText().toString();
+ String pass = mEditPass.getText().toString();
+
+ //Ensure no string is empty
+ if (TextUtils.isEmpty(email) || TextUtils.isEmpty(pass)) {
+
+ if (TextUtils.isEmpty(email)) {
+
+ //Show a toast warning that email cannot be empty
+ Toast.makeText(getContext(), "Email cannot be empty", Toast.LENGTH_LONG).show();
+ }
+
+ if (TextUtils.isEmpty(pass)) {
+
+ //Show a toast that password cannot be empty
+ Toast.makeText(getContext(), "Password cannot be empty", Toast.LENGTH_LONG).show();
+ }
+
+ } else {
+
+ //attempt to log in the user
+ progressDialog.setMessage("Please wait as we log you in");
+ progressDialog.setCanceledOnTouchOutside(false);
+ progressDialog.show();
+ mAuth.signInWithEmailAndPassword(email, pass).addOnCompleteListener(new OnCompleteListener() {
+ @Override
+ public void onComplete(@NonNull Task task) {
+ if (task.isSuccessful()) {
+
+ //dismiss progress dialog
+ progressDialog.dismiss();
+
+ //load the homescreen fragment
+ getFragmentManager().beginTransaction().setCustomAnimations(R.anim.bottom_top, R.anim.top_bottom).replace(R.id.fragmentHolder, new HomeScreenFragment()).commit();
+
+ } else {
+
+ //dismiss progress dialog
+ progressDialog.dismiss();
+
+ //Show a toast indicating failure
+ Toast.makeText(getActivity(), "Failed to log you in. Ensure you have a good network connection and your details are okay", Toast.LENGTH_LONG).show();
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/ian/sambazaquick/MainActivity.java b/app/src/main/java/com/example/ian/sambazaquick/MainActivity.java
new file mode 100644
index 0000000..d860154
--- /dev/null
+++ b/app/src/main/java/com/example/ian/sambazaquick/MainActivity.java
@@ -0,0 +1,22 @@
+package com.example.ian.sambazaquick;
+
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+
+
+public class MainActivity extends AppCompatActivity {
+
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ //load the log in fragment
+ getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.top_bottom,R.anim.bottom_top).replace(R.id.fragmentHolder,new LogInFragment()).commit();
+
+ }
+}
diff --git a/app/src/main/java/com/example/ian/sambazaquick/MobilePaymentB2CRecipient.java b/app/src/main/java/com/example/ian/sambazaquick/MobilePaymentB2CRecipient.java
new file mode 100644
index 0000000..837529f
--- /dev/null
+++ b/app/src/main/java/com/example/ian/sambazaquick/MobilePaymentB2CRecipient.java
@@ -0,0 +1,33 @@
+package com.example.ian.sambazaquick;
+
+import org.json.JSONObject;
+
+import java.util.HashMap;
+
+public class MobilePaymentB2CRecipient {
+ private String _phoneNumber;
+ private String _currencyCode;
+ private Double _amount;
+ private HashMap _metadata;
+
+ public MobilePaymentB2CRecipient(String phoneNumber_,
+ String currencyCode_,
+ Double amount_) {
+ _phoneNumber = phoneNumber_;
+ _currencyCode = currencyCode_;
+ _amount = amount_;
+ _metadata = new HashMap();
+ }
+
+ public void addMetadata(String key_, String value_) {
+ _metadata.put(key_, value_);
+ }
+
+ public JSONObject toJSON() throws Exception {
+ return new JSONObject()
+ .put("phoneNumber", _phoneNumber)
+ .put("currencyCode", _currencyCode)
+ .put("amount", _amount)
+ .put("metadata", _metadata);
+ }
+}
diff --git a/app/src/main/java/com/example/ian/sambazaquick/SendAirtimeFragment.java b/app/src/main/java/com/example/ian/sambazaquick/SendAirtimeFragment.java
new file mode 100644
index 0000000..d8c4c3f
--- /dev/null
+++ b/app/src/main/java/com/example/ian/sambazaquick/SendAirtimeFragment.java
@@ -0,0 +1,309 @@
+package com.example.ian.sambazaquick;
+
+import android.app.ProgressDialog;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+
+//for our UI widgets
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.ImageButton;
+import android.widget.EditText;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+//For our firebase database
+import com.google.firebase.database.DataSnapshot;
+import com.google.firebase.database.DatabaseError;
+import com.google.firebase.database.FirebaseDatabase;
+import com.google.firebase.database.DatabaseReference;
+import com.google.firebase.auth.FirebaseAuth;
+import com.google.firebase.database.ValueEventListener;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+//For Africa's talking API integration
+import org.json.*;
+
+public class SendAirtimeFragment extends Fragment {
+
+ //For our UI widgets
+ private ImageButton mBtnBack;
+ private EditText mEditPhoneNo;
+ private EditText mEditAmnt;
+ private TextView mShwName, mShwTotalAmnt;
+ private ProgressDialog progressDialog;
+ private ImageView mImgError;
+ private Button mBtnAdd, mBtnSend;
+
+ //For our UI works/magic
+ private boolean clickOnce = true;
+
+ //For storing details of who the airtime is being sent to
+ private String phoneNo;
+ private String amnt;
+
+ //To store the total amnt of credit to be bought
+ private int mTotalAmnt = 0;
+
+ //Storing our contacts List
+ private List contactsList = new ArrayList<>();
+
+ //My JSONArray for recepients
+ JSONArray recepients = new JSONArray();
+
+ //for firebase
+ private DatabaseReference mDbRef;
+ private ValueEventListener dbListener;
+
+
+ @Override
+ public void onCreate (Bundle savedInstanceState){
+ super.onCreate(savedInstanceState);
+
+ //instantiate our mDbRef
+ mDbRef = FirebaseDatabase.getInstance().getReference();
+
+ //instantiate our listener
+ dbListener = new ValueEventListener() {
+ @Override
+ public void onDataChange(DataSnapshot dataSnapshot) {
+
+ //call method to load our contacts list
+ loadContactsList((Map) dataSnapshot.getValue());
+ }
+
+ @Override
+ public void onCancelled(DatabaseError databaseError) {
+
+ Toast.makeText(getActivity(),"Error loading your contacts. Please check your internet connection",Toast.LENGTH_LONG).show();
+ }
+ };
+
+ //set up our listener
+ mDbRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid() + "_contacts").addValueEventListener(dbListener);
+
+ }
+
+ @Override
+ public View onCreateView (LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState){
+
+ container.removeAllViews();
+
+ //Inflate our UI and wire it up
+ View view = inflater.inflate(R.layout.send_airtime_fragment,container,false);
+ mBtnBack = view.findViewById(R.id.btnBack);
+ mEditPhoneNo = view.findViewById(R.id.keyNumber);
+ mEditAmnt = view.findViewById(R.id.keyAmount);
+ mShwName = view.findViewById(R.id.shwName);
+ mShwTotalAmnt = view.findViewById(R.id.shwTotalAirtime);
+ mImgError = view.findViewById(R.id.imgError);
+ mBtnAdd = view.findViewById(R.id.btnAddAnother);
+ mBtnSend = view.findViewById(R.id.btnSendAirtime);
+
+ //set the visibility of amount and imgError to gone
+ mEditAmnt.setVisibility(View.GONE);
+ mImgError.setVisibility(View.GONE);
+
+ //set the button add text to Next
+ mBtnAdd.setText("Next");
+ mBtnAdd.setBackgroundColor(Integer.valueOf(R.color.orangeShade));
+
+ //Listener for clicks on btnAdd
+ mBtnAdd.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ MyContacts c = null;
+
+ if (clickOnce){
+
+ boolean found = false;
+ for (int i = 0; i < contactsList.size();i++){
+ c = contactsList.get(i);
+
+ if (c.getPhoneNo() == mEditPhoneNo.getText().toString()){
+ //This contact exists in the user's contact list
+ //Load the number in our string
+ phoneNo = mEditPhoneNo.getText().toString();
+
+ //show the amounts widget and change the next button to add new contact
+ mEditAmnt.setVisibility(View.VISIBLE);
+ mBtnAdd.setBackgroundResource(R.drawable.add_another_contact_btn_bg);
+ mBtnAdd.setBackgroundColor(Integer.valueOf(R.color.white));
+
+ clickOnce = !clickOnce;
+ found = !found;
+
+ break;
+ }
+ }
+
+ if (found){
+ //Show toast with error
+ Toast.makeText(getActivity(),"This number doesn't exist in your contacts",Toast.LENGTH_LONG).show();
+ }
+ } else{ //dealing with amount here,
+
+ if (TextUtils.isEmpty(mEditAmnt.getText().toString())){
+ Toast.makeText(getActivity(),"Please key in the amount", Toast.LENGTH_LONG).show();
+ } else if (mEditAmnt.getText().toString().contains(" ")) {
+
+ //Do not allow for spaces
+ Toast.makeText(getContext(),"Leave no space in your text",Toast.LENGTH_LONG).show();
+ } else {
+
+ //amount has been keyed in
+ amnt = mEditAmnt.getText().toString();
+
+ //update the amount variable
+ mTotalAmnt += Integer.valueOf(amnt);
+
+ //feed this data to our JSONObjectArray
+ try {
+ recepients.put(new JSONObject().put("phoneNumber", phoneNo).put("amount", "KES " + amnt));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ //change the clickOnce
+ clickOnce = !clickOnce;
+
+ //Update the textviews
+ mShwName.setText(mShwName.getText().toString() + c.getName() + ",");
+ mShwTotalAmnt.setText(String.valueOf(mTotalAmnt));
+
+ //set the button add text to Next
+ mBtnAdd.setText("Next");
+ mBtnAdd.setBackgroundColor(Integer.valueOf(R.color.orangeShade));
+ //set the visibility of amount and imgError to gone
+ mEditAmnt.setVisibility(View.GONE);
+
+ //Handle click on send
+ }
+ }
+ }
+ });
+
+ mBtnBack.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ getFragmentManager().beginTransaction().replace(R.id.fragmentHolder, new HomeScreenFragment()).commit();
+ }
+ });
+
+ mBtnSend.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //ensure our JSONarray is not empty
+ if (recepients == null){
+ Toast.makeText(getContext(),"Please provide recepients and an amount",Toast.LENGTH_LONG).show();
+ }else{
+
+ //invoke sendAirtimeMethod
+ sendAirtime();
+ }
+
+ }
+ });
+
+ return view;
+ }
+
+ private void loadContactsList(Map dbData){
+
+ //Start our progress dialog
+ progressDialog = new ProgressDialog(getContext());
+ progressDialog.setMessage("Retrieving your contacts list");
+ progressDialog.setCanceledOnTouchOutside(false);
+ progressDialog.show();
+
+ //create an instance of our node
+ MyContacts myContacts = null;
+
+ if (dbData == null){
+ Toast.makeText(getContext(),"No contacts to load",Toast.LENGTH_LONG).show();
+ } else {
+
+ Map contact = null;
+ //gather all contacts data
+ for (Map.Entry entry: dbData.entrySet()){
+
+ myContacts = new MyContacts();
+
+ contact = (Map) entry.getValue();
+
+ //Get the necessary data
+ myContacts.setName((String) contact.get("Name"));
+ myContacts.setPhoneNo((String) contact.get("Phone Number"));
+
+ //push to the array list
+ contactsList.add(myContacts);
+
+ }
+ }
+
+ //Remove listener. Thus this will only fire once
+ mDbRef.removeEventListener(dbListener);
+ progressDialog.dismiss();
+
+ }
+
+ private void sendAirtime(){
+
+ String username = "sandbox";
+ String apiKey = "8d98d8c1b6efbcb51daa68a3dc93756b3ad3b7eddc68fd28668beb474a502ffd";
+
+ String recipientStringFormat = recepients.toString();
+
+ //Create an instance of GateWayClass
+ AfricasTalkingGateway gateway = new AfricasTalkingGateway(username,apiKey,"sandbox");
+
+ try {
+ JSONArray results = gateway.sendAirtime(recipientStringFormat);
+ int length = results.length();
+ for(int i = 0; i < length; i++) {
+ JSONObject result = results.getJSONObject(i);
+ Log.e("Error",result.getString("status"));
+ Log.e("Error",result.getString("amount"));
+ Log.e("Error",result.getString("phoneNumber"));
+ System.out.println(result.getString("discount"));
+ System.out.println(result.getString("requestId"));
+ //Error message is important when the status is not Success
+ System.out.println(result.getString("errorMessage"));
+ }
+ } catch(Exception e){
+ System.out.println(e.getMessage());
+ }
+ }
+
+ //an inner class to act as our node for contact list
+ private class MyContacts{
+
+ private String name;
+ private String phoneNo;
+
+ protected void setName(String name){
+ this.name = name;
+ }
+ protected String getName(){
+ return name;
+ }
+
+ protected void setPhoneNo(String phoneNo){
+ this.phoneNo = phoneNo;
+ }
+
+ protected String getPhoneNo(){
+ return phoneNo;
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/ian/sambazaquick/SignUpFragment.java b/app/src/main/java/com/example/ian/sambazaquick/SignUpFragment.java
new file mode 100644
index 0000000..2ee4f29
--- /dev/null
+++ b/app/src/main/java/com/example/ian/sambazaquick/SignUpFragment.java
@@ -0,0 +1,138 @@
+package com.example.ian.sambazaquick;
+
+import android.app.ProgressDialog;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.Fragment;
+
+//For our UI widgets
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.Toast;
+
+//For our firebase authentication
+import com.google.android.gms.tasks.OnCompleteListener;
+import com.google.android.gms.tasks.Task;
+import com.google.firebase.auth.AuthResult;
+import com.google.firebase.auth.FirebaseAuth;
+import com.google.firebase.auth.FirebaseUser;
+
+public class SignUpFragment extends Fragment {
+
+ //For our firebase authentication
+ private FirebaseAuth mAuth;
+
+ //For our UI widgets
+ private EditText mEditEmail, mEditPass, mConfirmPass;
+ private Button mBtnSignUp;
+ private ImageButton mBtnBack;
+ private ProgressDialog progressDialog;
+
+ //Overriding onCreate to instantiate mAuth
+ @Override
+ public void onCreate(Bundle savedInstanceState){
+ super.onCreate(savedInstanceState);
+
+ //mAuth = FirebaseAuth.getInstance();
+ }
+
+ //now, override onCreateView to load the UI and wire it up
+ @Override
+ public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
+
+ //remove the previous views. Sometimes necessary
+ container.removeAllViews();
+
+ //load our view
+ View view = inflater.inflate(R.layout.sign_up_fragment,container,false);
+
+ //get our UI references
+ mEditEmail = view.findViewById(R.id.editEmail);
+ mEditPass = view.findViewById(R.id.editPass);
+ mConfirmPass = view.findViewById(R.id.confirmPass);
+ mBtnSignUp = view.findViewById(R.id.btnSignUp);
+ mBtnBack = view.findViewById(R.id.back);
+ progressDialog = new ProgressDialog(getContext());
+
+ //Wire our click event listener for the sign up button
+ mBtnSignUp.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //attempt to sign up the user
+ signUpNewUser();
+ }
+ });
+
+ mBtnBack.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //load the log in fragment
+ getFragmentManager().beginTransaction().replace(R.id.fragmentHolder,new LogInFragment()).commit();
+ }
+ });
+
+ return view;
+ }
+
+ //Method to sign up our new user
+ private void signUpNewUser(){
+
+ //confirm that none of the fields are empty
+ if (TextUtils.isEmpty(mEditEmail.getText().toString()) || TextUtils.isEmpty(mEditPass.getText()) || TextUtils.isEmpty(mConfirmPass.getText().toString())){
+
+ //Show a message based on which one exactly is empty
+ if (TextUtils.isEmpty(mEditEmail.getText().toString())){
+ Toast.makeText(getContext(),"Email field cannot be empty",Toast.LENGTH_LONG).show();
+ }
+ if (TextUtils.isEmpty(mEditPass.getText().toString())){
+ Toast.makeText(getContext(),"Password field cannot be empty",Toast.LENGTH_LONG).show();
+ }
+ if (TextUtils.isEmpty(mConfirmPass.getText().toString())){
+ Toast.makeText(getContext(),"Please confirm your password",Toast.LENGTH_LONG).show();
+ }
+ } else if (!(mEditPass.getText().toString()).equals(mConfirmPass.getText().toString())){ //A test to ensure the password fields match
+
+ Toast.makeText(getContext(),"Your passwords don't match",Toast.LENGTH_LONG).show();
+ } else{ //No empty field, passwords match
+
+ String email = mEditEmail.getText().toString();
+ String pass = mEditPass.getText().toString();
+ progressDialog.setMessage("Signing you up");
+ progressDialog.setCanceledOnTouchOutside(false);
+ progressDialog.show();
+
+ mAuth = FirebaseAuth.getInstance();
+ mAuth.createUserWithEmailAndPassword(email,pass).addOnCompleteListener( new OnCompleteListener() {
+ @Override
+ public void onComplete(@NonNull Task task) {
+
+
+ if (task.isSuccessful()){
+
+ //get the current user
+ mAuth.getCurrentUser();
+ progressDialog.dismiss();
+
+ //load the home screen fragment
+ getFragmentManager().beginTransaction().setCustomAnimations(R.anim.bottom_top,R.anim.top_bottom).replace(R.id.fragmentHolder,new HomeScreenFragment()).commit();
+ }else{
+
+ //use toast to show error in signing up user
+
+ Toast.makeText(getContext(),"Failed to sign up. Make sure you have a good internet connection and your " +
+ "password is at least 8 characters long" + task.getException().getMessage().toString(),Toast.LENGTH_LONG).show();
+
+ progressDialog.dismiss();
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/app/src/main/res/anim/bottom_top.xml b/app/src/main/res/anim/bottom_top.xml
new file mode 100644
index 0000000..8a64f36
--- /dev/null
+++ b/app/src/main/res/anim/bottom_top.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/bounce.xml b/app/src/main/res/anim/bounce.xml
new file mode 100644
index 0000000..da9ad4d
--- /dev/null
+++ b/app/src/main/res/anim/bounce.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/close_along_x.xml b/app/src/main/res/anim/close_along_x.xml
new file mode 100644
index 0000000..38c080f
--- /dev/null
+++ b/app/src/main/res/anim/close_along_x.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/expand_left_right.xml b/app/src/main/res/anim/expand_left_right.xml
new file mode 100644
index 0000000..c2ac784
--- /dev/null
+++ b/app/src/main/res/anim/expand_left_right.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml
new file mode 100644
index 0000000..884a84c
--- /dev/null
+++ b/app/src/main/res/anim/fade_in.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/fade_in_signin.xml b/app/src/main/res/anim/fade_in_signin.xml
new file mode 100644
index 0000000..50ca53e
--- /dev/null
+++ b/app/src/main/res/anim/fade_in_signin.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml
new file mode 100644
index 0000000..538591a
--- /dev/null
+++ b/app/src/main/res/anim/fade_out.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/flashing_alpha.xml b/app/src/main/res/anim/flashing_alpha.xml
new file mode 100644
index 0000000..fcb83a0
--- /dev/null
+++ b/app/src/main/res/anim/flashing_alpha.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/right_left.xml b/app/src/main/res/anim/right_left.xml
new file mode 100644
index 0000000..a1e7822
--- /dev/null
+++ b/app/src/main/res/anim/right_left.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/top_bottom.xml b/app/src/main/res/anim/top_bottom.xml
new file mode 100644
index 0000000..0a6b701
--- /dev/null
+++ b/app/src/main/res/anim/top_bottom.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/add_another_contact_btn_bg.png b/app/src/main/res/drawable-hdpi/add_another_contact_btn_bg.png
new file mode 100644
index 0000000..4356089
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/add_another_contact_btn_bg.png differ
diff --git a/app/src/main/res/drawable-hdpi/add_btn_bg.png b/app/src/main/res/drawable-hdpi/add_btn_bg.png
new file mode 100644
index 0000000..8b3ce77
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/add_btn_bg.png differ
diff --git a/app/src/main/res/drawable-hdpi/add_contacts_txt.png b/app/src/main/res/drawable-hdpi/add_contacts_txt.png
new file mode 100644
index 0000000..65a1f41
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/add_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/add_new_contacts_btn_bg.png b/app/src/main/res/drawable-hdpi/add_new_contacts_btn_bg.png
new file mode 100644
index 0000000..a564d6c
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/add_new_contacts_btn_bg.png differ
diff --git a/app/src/main/res/drawable-hdpi/enter_amount_txt.png b/app/src/main/res/drawable-hdpi/enter_amount_txt.png
new file mode 100644
index 0000000..872cc7e
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/enter_amount_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/home_txt.png b/app/src/main/res/drawable-hdpi/home_txt.png
new file mode 100644
index 0000000..0163d0e
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/home_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_arrow_back.png b/app/src/main/res/drawable-hdpi/ic_arrow_back.png
new file mode 100644
index 0000000..9370875
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_arrow_back.png differ
diff --git a/app/src/main/res/drawable-hdpi/key_in_phone_number_txt.png b/app/src/main/res/drawable-hdpi/key_in_phone_number_txt.png
new file mode 100644
index 0000000..a42a3d0
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/key_in_phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/list_of_contacts_youve_just_added_txt.png b/app/src/main/res/drawable-hdpi/list_of_contacts_youve_just_added_txt.png
new file mode 100644
index 0000000..61bfcd2
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/list_of_contacts_youve_just_added_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/log_in_txt.png b/app/src/main/res/drawable-hdpi/log_in_txt.png
new file mode 100644
index 0000000..94d263b
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/log_in_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/log_out_btn_bg.png b/app/src/main/res/drawable-hdpi/log_out_btn_bg.png
new file mode 100644
index 0000000..9e2937b
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/log_out_btn_bg.png differ
diff --git a/app/src/main/res/drawable-hdpi/login_btn_bg.png b/app/src/main/res/drawable-hdpi/login_btn_bg.png
new file mode 100644
index 0000000..e8c0dce
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/login_btn_bg.png differ
diff --git a/app/src/main/res/drawable-hdpi/name_txt.png b/app/src/main/res/drawable-hdpi/name_txt.png
new file mode 100644
index 0000000..395029f
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/name_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/open_an_acc_txt.png b/app/src/main/res/drawable-hdpi/open_an_acc_txt.png
new file mode 100644
index 0000000..66fd3f4
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/open_an_acc_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/phone_number_txt.png b/app/src/main/res/drawable-hdpi/phone_number_txt.png
new file mode 100644
index 0000000..938ae1b
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/red_warning_icon.png b/app/src/main/res/drawable-hdpi/red_warning_icon.png
new file mode 100644
index 0000000..bce00a2
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/red_warning_icon.png differ
diff --git a/app/src/main/res/drawable-hdpi/sambaza_header.png b/app/src/main/res/drawable-hdpi/sambaza_header.png
new file mode 100644
index 0000000..a8ab4eb
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/sambaza_header.png differ
diff --git a/app/src/main/res/drawable-hdpi/selected_contacts_txt.png b/app/src/main/res/drawable-hdpi/selected_contacts_txt.png
new file mode 100644
index 0000000..105ff73
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/selected_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/send_airtime_btn_bg.png b/app/src/main/res/drawable-hdpi/send_airtime_btn_bg.png
new file mode 100644
index 0000000..fb441d8
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/send_airtime_btn_bg.png differ
diff --git a/app/src/main/res/drawable-hdpi/send_airtime_txt.png b/app/src/main/res/drawable-hdpi/send_airtime_txt.png
new file mode 100644
index 0000000..52963c2
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/send_airtime_txt.png differ
diff --git a/app/src/main/res/drawable-hdpi/send_btn_bg.png b/app/src/main/res/drawable-hdpi/send_btn_bg.png
new file mode 100644
index 0000000..51c53e0
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/send_btn_bg.png differ
diff --git a/app/src/main/res/drawable-hdpi/sign_up_btn_bg.png b/app/src/main/res/drawable-hdpi/sign_up_btn_bg.png
new file mode 100644
index 0000000..9f7da57
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/sign_up_btn_bg.png differ
diff --git a/app/src/main/res/drawable-hdpi/sign_up_txt.png b/app/src/main/res/drawable-hdpi/sign_up_txt.png
new file mode 100644
index 0000000..2c9a57d
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/sign_up_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/add_another_contact_btn_bg.png b/app/src/main/res/drawable-ldpi/add_another_contact_btn_bg.png
new file mode 100644
index 0000000..3505414
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/add_another_contact_btn_bg.png differ
diff --git a/app/src/main/res/drawable-ldpi/add_btn_bg.png b/app/src/main/res/drawable-ldpi/add_btn_bg.png
new file mode 100644
index 0000000..137d0c2
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/add_btn_bg.png differ
diff --git a/app/src/main/res/drawable-ldpi/add_contacts_txt.png b/app/src/main/res/drawable-ldpi/add_contacts_txt.png
new file mode 100644
index 0000000..160f333
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/add_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/add_new_contacts_btn_bg.png b/app/src/main/res/drawable-ldpi/add_new_contacts_btn_bg.png
new file mode 100644
index 0000000..73b33cb
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/add_new_contacts_btn_bg.png differ
diff --git a/app/src/main/res/drawable-ldpi/enter_amount_txt.png b/app/src/main/res/drawable-ldpi/enter_amount_txt.png
new file mode 100644
index 0000000..dc1736b
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/enter_amount_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/home_txt.png b/app/src/main/res/drawable-ldpi/home_txt.png
new file mode 100644
index 0000000..02e4701
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/home_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/ic_arrow_back.png b/app/src/main/res/drawable-ldpi/ic_arrow_back.png
new file mode 100644
index 0000000..e21ceab
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_arrow_back.png differ
diff --git a/app/src/main/res/drawable-ldpi/key_in_phone_number_txt.png b/app/src/main/res/drawable-ldpi/key_in_phone_number_txt.png
new file mode 100644
index 0000000..c79b31b
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/key_in_phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/list_of_contacts_youve_just_added_txt.png b/app/src/main/res/drawable-ldpi/list_of_contacts_youve_just_added_txt.png
new file mode 100644
index 0000000..30f58f8
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/list_of_contacts_youve_just_added_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/log_in_txt.png b/app/src/main/res/drawable-ldpi/log_in_txt.png
new file mode 100644
index 0000000..41e06dd
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/log_in_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/log_out_btn_bg.png b/app/src/main/res/drawable-ldpi/log_out_btn_bg.png
new file mode 100644
index 0000000..e78aa3f
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/log_out_btn_bg.png differ
diff --git a/app/src/main/res/drawable-ldpi/login_btn_bg.png b/app/src/main/res/drawable-ldpi/login_btn_bg.png
new file mode 100644
index 0000000..95cbd7a
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/login_btn_bg.png differ
diff --git a/app/src/main/res/drawable-ldpi/name_txt.png b/app/src/main/res/drawable-ldpi/name_txt.png
new file mode 100644
index 0000000..18e2dea
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/name_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/open_an_acc_txt.png b/app/src/main/res/drawable-ldpi/open_an_acc_txt.png
new file mode 100644
index 0000000..1f27011
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/open_an_acc_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/phone_number_txt.png b/app/src/main/res/drawable-ldpi/phone_number_txt.png
new file mode 100644
index 0000000..e950c08
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/red_warning_icon.png b/app/src/main/res/drawable-ldpi/red_warning_icon.png
new file mode 100644
index 0000000..104a4ef
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/red_warning_icon.png differ
diff --git a/app/src/main/res/drawable-ldpi/sambaza_header.png b/app/src/main/res/drawable-ldpi/sambaza_header.png
new file mode 100644
index 0000000..5fd196b
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/sambaza_header.png differ
diff --git a/app/src/main/res/drawable-ldpi/selected_contacts_txt.png b/app/src/main/res/drawable-ldpi/selected_contacts_txt.png
new file mode 100644
index 0000000..bf4c586
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/selected_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/send_airtime_btn_bg.png b/app/src/main/res/drawable-ldpi/send_airtime_btn_bg.png
new file mode 100644
index 0000000..2e94b0d
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/send_airtime_btn_bg.png differ
diff --git a/app/src/main/res/drawable-ldpi/send_airtime_txt.png b/app/src/main/res/drawable-ldpi/send_airtime_txt.png
new file mode 100644
index 0000000..ddaed9c
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/send_airtime_txt.png differ
diff --git a/app/src/main/res/drawable-ldpi/send_btn_bg.png b/app/src/main/res/drawable-ldpi/send_btn_bg.png
new file mode 100644
index 0000000..0798eab
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/send_btn_bg.png differ
diff --git a/app/src/main/res/drawable-ldpi/sign_up_btn_bg.png b/app/src/main/res/drawable-ldpi/sign_up_btn_bg.png
new file mode 100644
index 0000000..e28896c
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/sign_up_btn_bg.png differ
diff --git a/app/src/main/res/drawable-ldpi/sign_up_txt.png b/app/src/main/res/drawable-ldpi/sign_up_txt.png
new file mode 100644
index 0000000..271ccc4
Binary files /dev/null and b/app/src/main/res/drawable-ldpi/sign_up_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/add_another_contact_btn_bg.png b/app/src/main/res/drawable-mdpi/add_another_contact_btn_bg.png
new file mode 100644
index 0000000..128c1ce
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/add_another_contact_btn_bg.png differ
diff --git a/app/src/main/res/drawable-mdpi/add_btn_bg.png b/app/src/main/res/drawable-mdpi/add_btn_bg.png
new file mode 100644
index 0000000..b3f9764
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/add_btn_bg.png differ
diff --git a/app/src/main/res/drawable-mdpi/add_contacts_txt.png b/app/src/main/res/drawable-mdpi/add_contacts_txt.png
new file mode 100644
index 0000000..1feb128
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/add_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/add_new_contacts_btn_bg.png b/app/src/main/res/drawable-mdpi/add_new_contacts_btn_bg.png
new file mode 100644
index 0000000..5128c54
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/add_new_contacts_btn_bg.png differ
diff --git a/app/src/main/res/drawable-mdpi/enter_amount_txt.png b/app/src/main/res/drawable-mdpi/enter_amount_txt.png
new file mode 100644
index 0000000..407032a
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/enter_amount_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/home_txt.png b/app/src/main/res/drawable-mdpi/home_txt.png
new file mode 100644
index 0000000..f7b8f23
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/home_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_arrow_back.png b/app/src/main/res/drawable-mdpi/ic_arrow_back.png
new file mode 100644
index 0000000..4c2e4f3
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_arrow_back.png differ
diff --git a/app/src/main/res/drawable-mdpi/key_in_phone_number_txt.png b/app/src/main/res/drawable-mdpi/key_in_phone_number_txt.png
new file mode 100644
index 0000000..2ad644a
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/key_in_phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/list_of_contacts_youve_just_added_txt.png b/app/src/main/res/drawable-mdpi/list_of_contacts_youve_just_added_txt.png
new file mode 100644
index 0000000..6635187
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/list_of_contacts_youve_just_added_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/log_in_txt.png b/app/src/main/res/drawable-mdpi/log_in_txt.png
new file mode 100644
index 0000000..0397931
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/log_in_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/log_out_btn_bg.png b/app/src/main/res/drawable-mdpi/log_out_btn_bg.png
new file mode 100644
index 0000000..808019f
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/log_out_btn_bg.png differ
diff --git a/app/src/main/res/drawable-mdpi/login_btn_bg.png b/app/src/main/res/drawable-mdpi/login_btn_bg.png
new file mode 100644
index 0000000..3bd314e
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/login_btn_bg.png differ
diff --git a/app/src/main/res/drawable-mdpi/name_txt.png b/app/src/main/res/drawable-mdpi/name_txt.png
new file mode 100644
index 0000000..0d88053
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/name_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/open_an_acc_txt.png b/app/src/main/res/drawable-mdpi/open_an_acc_txt.png
new file mode 100644
index 0000000..1efb8c9
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/open_an_acc_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/phone_number_txt.png b/app/src/main/res/drawable-mdpi/phone_number_txt.png
new file mode 100644
index 0000000..3e8ab44
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/red_warning_icon.png b/app/src/main/res/drawable-mdpi/red_warning_icon.png
new file mode 100644
index 0000000..6370c1a
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/red_warning_icon.png differ
diff --git a/app/src/main/res/drawable-mdpi/sambaza_header.png b/app/src/main/res/drawable-mdpi/sambaza_header.png
new file mode 100644
index 0000000..e159304
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/sambaza_header.png differ
diff --git a/app/src/main/res/drawable-mdpi/selected_contacts_txt.png b/app/src/main/res/drawable-mdpi/selected_contacts_txt.png
new file mode 100644
index 0000000..5f6097c
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/selected_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/send_airtime_btn_bg.png b/app/src/main/res/drawable-mdpi/send_airtime_btn_bg.png
new file mode 100644
index 0000000..a961f9f
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/send_airtime_btn_bg.png differ
diff --git a/app/src/main/res/drawable-mdpi/send_airtime_txt.png b/app/src/main/res/drawable-mdpi/send_airtime_txt.png
new file mode 100644
index 0000000..e838134
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/send_airtime_txt.png differ
diff --git a/app/src/main/res/drawable-mdpi/send_btn_bg.png b/app/src/main/res/drawable-mdpi/send_btn_bg.png
new file mode 100644
index 0000000..64d133c
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/send_btn_bg.png differ
diff --git a/app/src/main/res/drawable-mdpi/sign_up_btn_bg.png b/app/src/main/res/drawable-mdpi/sign_up_btn_bg.png
new file mode 100644
index 0000000..185c95e
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/sign_up_btn_bg.png differ
diff --git a/app/src/main/res/drawable-mdpi/sign_up_txt.png b/app/src/main/res/drawable-mdpi/sign_up_txt.png
new file mode 100644
index 0000000..e729c78
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/sign_up_txt.png differ
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..c7bd21d
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable-xhdpi/add_another_contact_btn_bg.png b/app/src/main/res/drawable-xhdpi/add_another_contact_btn_bg.png
new file mode 100644
index 0000000..008ffe4
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/add_another_contact_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xhdpi/add_btn_bg.png b/app/src/main/res/drawable-xhdpi/add_btn_bg.png
new file mode 100644
index 0000000..04598d1
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/add_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xhdpi/add_contacts_txt.png b/app/src/main/res/drawable-xhdpi/add_contacts_txt.png
new file mode 100644
index 0000000..2ed14d0
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/add_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/add_new_contacts_btn_bg.png b/app/src/main/res/drawable-xhdpi/add_new_contacts_btn_bg.png
new file mode 100644
index 0000000..ed9b911
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/add_new_contacts_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xhdpi/enter_amount_txt.png b/app/src/main/res/drawable-xhdpi/enter_amount_txt.png
new file mode 100644
index 0000000..cb9066f
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/enter_amount_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/home_txt.png b/app/src/main/res/drawable-xhdpi/home_txt.png
new file mode 100644
index 0000000..921d26e
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/home_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow_back.png b/app/src/main/res/drawable-xhdpi/ic_arrow_back.png
new file mode 100644
index 0000000..9999f72
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_arrow_back.png differ
diff --git a/app/src/main/res/drawable-xhdpi/key_in_phone_number_txt.png b/app/src/main/res/drawable-xhdpi/key_in_phone_number_txt.png
new file mode 100644
index 0000000..f219ace
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/key_in_phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/list_of_contacts_youve_just_added_txt.png b/app/src/main/res/drawable-xhdpi/list_of_contacts_youve_just_added_txt.png
new file mode 100644
index 0000000..4d1c3fb
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/list_of_contacts_youve_just_added_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/log_in_txt.png b/app/src/main/res/drawable-xhdpi/log_in_txt.png
new file mode 100644
index 0000000..20acff9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/log_in_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/log_out_btn_bg.png b/app/src/main/res/drawable-xhdpi/log_out_btn_bg.png
new file mode 100644
index 0000000..019b512
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/log_out_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xhdpi/login_btn_bg.png b/app/src/main/res/drawable-xhdpi/login_btn_bg.png
new file mode 100644
index 0000000..0b8a6a3
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/login_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xhdpi/name_txt.png b/app/src/main/res/drawable-xhdpi/name_txt.png
new file mode 100644
index 0000000..23f148a
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/name_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/open_an_acc_txt.png b/app/src/main/res/drawable-xhdpi/open_an_acc_txt.png
new file mode 100644
index 0000000..2d7c0a7
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/open_an_acc_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/phone_number_txt.png b/app/src/main/res/drawable-xhdpi/phone_number_txt.png
new file mode 100644
index 0000000..f0e0007
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/red_warning_icon.png b/app/src/main/res/drawable-xhdpi/red_warning_icon.png
new file mode 100644
index 0000000..570e5ee
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/red_warning_icon.png differ
diff --git a/app/src/main/res/drawable-xhdpi/sambaza_header.png b/app/src/main/res/drawable-xhdpi/sambaza_header.png
new file mode 100644
index 0000000..b78ea44
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/sambaza_header.png differ
diff --git a/app/src/main/res/drawable-xhdpi/selected_contacts_txt.png b/app/src/main/res/drawable-xhdpi/selected_contacts_txt.png
new file mode 100644
index 0000000..43c6f77
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/selected_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/send_airtime_btn_bg.png b/app/src/main/res/drawable-xhdpi/send_airtime_btn_bg.png
new file mode 100644
index 0000000..9f1ddde
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/send_airtime_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xhdpi/send_airtime_txt.png b/app/src/main/res/drawable-xhdpi/send_airtime_txt.png
new file mode 100644
index 0000000..7fff027
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/send_airtime_txt.png differ
diff --git a/app/src/main/res/drawable-xhdpi/send_btn_bg.png b/app/src/main/res/drawable-xhdpi/send_btn_bg.png
new file mode 100644
index 0000000..8b05cdf
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/send_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xhdpi/sign_up_btn_bg.png b/app/src/main/res/drawable-xhdpi/sign_up_btn_bg.png
new file mode 100644
index 0000000..cccab5c
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/sign_up_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xhdpi/sign_up_txt.png b/app/src/main/res/drawable-xhdpi/sign_up_txt.png
new file mode 100644
index 0000000..2d3e4a4
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/sign_up_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/add_another_contact_btn_bg.png b/app/src/main/res/drawable-xxhdpi/add_another_contact_btn_bg.png
new file mode 100644
index 0000000..54fa614
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/add_another_contact_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/add_btn_bg.png b/app/src/main/res/drawable-xxhdpi/add_btn_bg.png
new file mode 100644
index 0000000..e2befd8
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/add_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/add_contacts_txt.png b/app/src/main/res/drawable-xxhdpi/add_contacts_txt.png
new file mode 100644
index 0000000..ffa6ec8
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/add_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/add_new_contacts_btn_bg.png b/app/src/main/res/drawable-xxhdpi/add_new_contacts_btn_bg.png
new file mode 100644
index 0000000..74b2a60
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/add_new_contacts_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/enter_amount_txt.png b/app/src/main/res/drawable-xxhdpi/enter_amount_txt.png
new file mode 100644
index 0000000..832febe
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/enter_amount_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/home_txt.png b/app/src/main/res/drawable-xxhdpi/home_txt.png
new file mode 100644
index 0000000..473f34c
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/home_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_back.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_back.png
new file mode 100644
index 0000000..2a2303a
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_arrow_back.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/key_in_phone_number_txt.png b/app/src/main/res/drawable-xxhdpi/key_in_phone_number_txt.png
new file mode 100644
index 0000000..fbc1e1d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/key_in_phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/list_of_contacts_youve_just_added_txt.png b/app/src/main/res/drawable-xxhdpi/list_of_contacts_youve_just_added_txt.png
new file mode 100644
index 0000000..221666c
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/list_of_contacts_youve_just_added_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/log_in_txt.png b/app/src/main/res/drawable-xxhdpi/log_in_txt.png
new file mode 100644
index 0000000..6ee98d6
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/log_in_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/log_out_btn_bg.png b/app/src/main/res/drawable-xxhdpi/log_out_btn_bg.png
new file mode 100644
index 0000000..79c5355
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/log_out_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/login_btn_bg.png b/app/src/main/res/drawable-xxhdpi/login_btn_bg.png
new file mode 100644
index 0000000..e0173c8
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/login_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/name_txt.png b/app/src/main/res/drawable-xxhdpi/name_txt.png
new file mode 100644
index 0000000..33d9800
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/name_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/open_an_acc_txt.png b/app/src/main/res/drawable-xxhdpi/open_an_acc_txt.png
new file mode 100644
index 0000000..8184807
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/open_an_acc_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/phone_number_txt.png b/app/src/main/res/drawable-xxhdpi/phone_number_txt.png
new file mode 100644
index 0000000..b4abb7a
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/red_warning_icon.png b/app/src/main/res/drawable-xxhdpi/red_warning_icon.png
new file mode 100644
index 0000000..3ce4308
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/red_warning_icon.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/sambaza_header.png b/app/src/main/res/drawable-xxhdpi/sambaza_header.png
new file mode 100644
index 0000000..8cbe063
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/sambaza_header.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/selected_contacts_txt.png b/app/src/main/res/drawable-xxhdpi/selected_contacts_txt.png
new file mode 100644
index 0000000..48e1116
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/selected_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/send_airtime_btn_bg.png b/app/src/main/res/drawable-xxhdpi/send_airtime_btn_bg.png
new file mode 100644
index 0000000..d90d82b
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/send_airtime_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/send_airtime_txt.png b/app/src/main/res/drawable-xxhdpi/send_airtime_txt.png
new file mode 100644
index 0000000..81864fb
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/send_airtime_txt.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/send_btn_bg.png b/app/src/main/res/drawable-xxhdpi/send_btn_bg.png
new file mode 100644
index 0000000..1b26f89
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/send_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/sign_up_btn_bg.png b/app/src/main/res/drawable-xxhdpi/sign_up_btn_bg.png
new file mode 100644
index 0000000..c357207
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/sign_up_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/sign_up_txt.png b/app/src/main/res/drawable-xxhdpi/sign_up_txt.png
new file mode 100644
index 0000000..eeb98ac
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/sign_up_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/add_another_contact_btn_bg.png b/app/src/main/res/drawable-xxxhdpi/add_another_contact_btn_bg.png
new file mode 100644
index 0000000..e1ecb21
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/add_another_contact_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/add_btn_bg.png b/app/src/main/res/drawable-xxxhdpi/add_btn_bg.png
new file mode 100644
index 0000000..d18cbed
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/add_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/add_contacts_txt.png b/app/src/main/res/drawable-xxxhdpi/add_contacts_txt.png
new file mode 100644
index 0000000..771974f
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/add_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/add_new_contacts_btn_bg.png b/app/src/main/res/drawable-xxxhdpi/add_new_contacts_btn_bg.png
new file mode 100644
index 0000000..3a03b70
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/add_new_contacts_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/enter_amount_txt.png b/app/src/main/res/drawable-xxxhdpi/enter_amount_txt.png
new file mode 100644
index 0000000..eb20585
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/enter_amount_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/home_txt.png b/app/src/main/res/drawable-xxxhdpi/home_txt.png
new file mode 100644
index 0000000..8fbb709
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/home_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_arrow_back.png b/app/src/main/res/drawable-xxxhdpi/ic_arrow_back.png
new file mode 100644
index 0000000..3ea26df
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_arrow_back.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/key_in_phone_number_txt.png b/app/src/main/res/drawable-xxxhdpi/key_in_phone_number_txt.png
new file mode 100644
index 0000000..697aa43
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/key_in_phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/list_of_contacts_youve_just_added_txt.png b/app/src/main/res/drawable-xxxhdpi/list_of_contacts_youve_just_added_txt.png
new file mode 100644
index 0000000..e9cb22e
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/list_of_contacts_youve_just_added_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/log_in_txt.png b/app/src/main/res/drawable-xxxhdpi/log_in_txt.png
new file mode 100644
index 0000000..2b5477d
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/log_in_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/log_out_btn_bg.png b/app/src/main/res/drawable-xxxhdpi/log_out_btn_bg.png
new file mode 100644
index 0000000..c9d2807
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/log_out_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/login_btn_bg.png b/app/src/main/res/drawable-xxxhdpi/login_btn_bg.png
new file mode 100644
index 0000000..03a8b17
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/login_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/name_txt.png b/app/src/main/res/drawable-xxxhdpi/name_txt.png
new file mode 100644
index 0000000..b4c29b9
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/name_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/open_an_acc_txt.png b/app/src/main/res/drawable-xxxhdpi/open_an_acc_txt.png
new file mode 100644
index 0000000..0d609f0
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/open_an_acc_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/phone_number_txt.png b/app/src/main/res/drawable-xxxhdpi/phone_number_txt.png
new file mode 100644
index 0000000..ae07b5b
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/phone_number_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/red_warning_icon.png b/app/src/main/res/drawable-xxxhdpi/red_warning_icon.png
new file mode 100644
index 0000000..a9d4c64
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/red_warning_icon.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/sambaza_header.png b/app/src/main/res/drawable-xxxhdpi/sambaza_header.png
new file mode 100644
index 0000000..6bccfb0
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/sambaza_header.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/selected_contacts_txt.png b/app/src/main/res/drawable-xxxhdpi/selected_contacts_txt.png
new file mode 100644
index 0000000..75f034c
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/selected_contacts_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/send_airtime_btn_bg.png b/app/src/main/res/drawable-xxxhdpi/send_airtime_btn_bg.png
new file mode 100644
index 0000000..b60e06c
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/send_airtime_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/send_airtime_txt.png b/app/src/main/res/drawable-xxxhdpi/send_airtime_txt.png
new file mode 100644
index 0000000..90f38e7
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/send_airtime_txt.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/send_btn_bg.png b/app/src/main/res/drawable-xxxhdpi/send_btn_bg.png
new file mode 100644
index 0000000..765a086
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/send_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/sign_up_btn_bg.png b/app/src/main/res/drawable-xxxhdpi/sign_up_btn_bg.png
new file mode 100644
index 0000000..d357d43
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/sign_up_btn_bg.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/sign_up_txt.png b/app/src/main/res/drawable-xxxhdpi/sign_up_txt.png
new file mode 100644
index 0000000..4e6cbfe
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/sign_up_txt.png differ
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..d5fccc5
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..e375185
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/add_contacts_fragment.xml b/app/src/main/res/layout/add_contacts_fragment.xml
new file mode 100644
index 0000000..a488147
--- /dev/null
+++ b/app/src/main/res/layout/add_contacts_fragment.xml
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/log_in_fragment.xml b/app/src/main/res/layout/log_in_fragment.xml
new file mode 100644
index 0000000..da70fe3
--- /dev/null
+++ b/app/src/main/res/layout/log_in_fragment.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/mainpage_fragment.xml b/app/src/main/res/layout/mainpage_fragment.xml
new file mode 100644
index 0000000..6b27acf
--- /dev/null
+++ b/app/src/main/res/layout/mainpage_fragment.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/send_airtime_fragment.xml b/app/src/main/res/layout/send_airtime_fragment.xml
new file mode 100644
index 0000000..1bd9606
--- /dev/null
+++ b/app/src/main/res/layout/send_airtime_fragment.xml
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/sign_up_fragment.xml b/app/src/main/res/layout/sign_up_fragment.xml
new file mode 100644
index 0000000..6420241
--- /dev/null
+++ b/app/src/main/res/layout/sign_up_fragment.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a2f5908
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..1b52399
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..ff10afd
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..115a4c7
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..dcd3cd8
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..459ca60
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..8ca12fe
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8e19b41
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b824ebd
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4c19a13
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..6188fa4
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,8 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+ #F69E3F
+ #ffffff
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..f908a28
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Sambaza Quick
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/app/src/test/java/com/example/ian/sambazaquick/AfricasTalkingGateway.java b/app/src/test/java/com/example/ian/sambazaquick/AfricasTalkingGateway.java
new file mode 100644
index 0000000..18de219
--- /dev/null
+++ b/app/src/test/java/com/example/ian/sambazaquick/AfricasTalkingGateway.java
@@ -0,0 +1,48 @@
+package com.example.ian.sambazaquick; /**********************************************************************************************************************
+ * # COPYRIGHT (C) 2014 AFRICASTALKING LTD *
+ **********************************************************************************************************************
+ *AFRICAStALKING SMS GATEWAY CLASS IS A FREE SOFTWARE IE. CAN BE MODIFIED AND/OR REDISTRIBUTED *
+ *UNDER THER TERMS OF GNU GENERAL PUBLIC LICENCES AS PUBLISHED BY THE *
+ *FREE SOFTWARE FOUNDATION VERSION 3 OR ANY LATER VERSION *
+ **********************************************************************************************************************
+ *THE CLASS IS DISTRIBUTED ON 'AS IS' BASIS WITHOUT ANY WARRANTY, INCLUDING BUT NOT LIMITED TO *
+ *THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
+ *IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, *
+ *WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
+ *OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+ **********************************************************************************************************************/
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.Map.Entry;
+
+import org.json.*;
+
+class MobilePaymentB2CRecipient {
+ private String _phoneNumber;
+ private String _currencyCode;
+ private Double _amount;
+ private HashMap _metadata;
+
+ public MobilePaymentB2CRecipient(String phoneNumber_,
+ String currencyCode_,
+ Double amount_) {
+ _phoneNumber = phoneNumber_;
+ _currencyCode = currencyCode_;
+ _amount = amount_;
+ _metadata = new HashMap();
+ }
+
+ public void addMetadata(String key_, String value_) {
+ _metadata.put(key_, value_);
+ }
+
+ public JSONObject toJSON() throws Exception {
+ return new JSONObject()
+ .put("phoneNumber", _phoneNumber)
+ .put("currencyCode", _currencyCode)
+ .put("amount", _amount)
+ .put("metadata", _metadata);
+ }
+}
diff --git a/app/src/test/java/com/example/ian/sambazaquick/ExampleUnitTest.java b/app/src/test/java/com/example/ian/sambazaquick/ExampleUnitTest.java
new file mode 100644
index 0000000..8e7dccf
--- /dev/null
+++ b/app/src/test/java/com/example/ian/sambazaquick/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.ian.sambazaquick;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..90aa1c7
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,28 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.1.3'
+
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ classpath 'com.google.gms:google-services:4.0.0'
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..743d692
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,13 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7a3265e
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..745f5e8
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Sep 12 11:47:18 EAT 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'