Get Started in less than a minute

Android Documentation


Installing the SDK with Android Studio / Gradle


To install the library inside Android Studio, you can simply declare it as dependency in your build.gradle file.

Just include it in your list of dependencies, make sure to use always the latest available version.

dependencies {
    compile 'com.ringcaptcha.android:ringcaptcha:1.1.4'
}

Once you've updated your build.gradle file, you can force Android Studio to sync with your new configuration by clicking the "Sync Project with Gradle Files" icon at the top of the window. This should download the aar dependency at which point you'll have access to the RingCaptcha library.

Installing the SDK Manually


To embed the SDK just drag & drop the Android SDK library into your libs folder of your project on your favorite IDE.

This will copy the folder straight into your libs section, including the assets and res folders. You will need to merge the contents of the folders assets and res with your project's respective folders so the activity views can be loaded.

Once the SDK has been included in your app, add the following permissions, activities and SMS Broadcaster to your application AndroidManifest.xml file. The SMS Broadcaster (SMS_RECEIVED) will automatically read the SMS and throw an event with the PIN code.

//AndroidManifest.xml file to merge
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sampleapp"
    android:versionCode="1"
    android:versionName="1.0"
    android:hardwareAccelerated="true" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="17" />
    
    <!-- ringcaptcha sdk permissions -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:hardwareAccelerated="true"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.example.sampleapp.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data
                    android:scheme="yourAppScheme"
                    android:host="ringcaptcha" />
            </intent-filter>
        </activity>
        
        <!-- ringcaptcha sdk activities|receivers -->
        <activity
            android:name="com.thrivecom.ringcaptcha.SetNumberActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
            android:windowSoftInputMode="stateVisible|adjustPan|adjustResize"
            android:screenOrientation="sensor">
        </activity>
        
        <activity
            android:name="com.thrivecom.ringcaptcha.HelpActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="sensor">
        </activity>
        <activity
            android:name="com.thrivecom.ringcaptcha.VerifyActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="sensor">
        </activity>
        <activity
            android:name="com.thrivecom.ringcaptcha.CountryListActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="sensor">
        </activity>
        
         <activity
            android:name="com.thrivecom.ringcaptcha.OnboardActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="sensor">
        </activity>
        
        <activity
            android:name="com.thrivecom.ringcaptcha.CodeActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="sensor"
            android:windowSoftInputMode="stateVisible|adjustPan|adjustResize">
        </activity>
        
        <receiver
            android:name="com.thrivecom.ringcaptcha.RingcaptchaAPIController"
            android:enabled="true"
            android:exported="true" >
            <intent-filter android:priority="999">
                <action
                    android:name="android.provider.Telephony.SMS_RECEIVED"
                    android:scheme="sms" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

Download Android SDK now


Launching an Onboarding widget

To use the one screen onboarding process bundled into the SDK with the option of onboarding automatically from a website PIN, all you need to do is call the RingcaptchaApplication.onboard method as described below from any user action like starting the app for the first time when is not logged-in.


Simple widget Simple widget Simple widget

On your initial Activity, in the method hooked to the user event add the following line of code.

RingcaptchaApplication.onboard(getApplicationContext(),"{{ app_key }}", "{{ secret_key }}", new RingcaptchaApplicationHandler() {
      @Override
      public void onSuccess(RingcaptchaVerification ringcaptchaVerification) {
          //Verification successful
      }
      @Override
      public void onCancel() {
          //Decide what to do if user cancelled operation
      }
  });

In the event the widget does not find an open session or is unable to attribute the onboarding process to a user, it will automatically start the verification process by asking the phone number to the user to send the PIN code to.


Launching a Verification widget

To use the two screen verification process bundled into the SDK, all you need to do is call the RingcaptchaApplication.verifyPhoneNumber method as described below from any user action like tapping a button for Verify your Phone Number.


Simple widget Simple widget Simple widget

On your Activity, in the method hooked to the user event add the following line of code.

RingcaptchaApplication.verifyPhoneNumber(getApplicationContext(),"{{ app_key }}", "{{ secret_key }}", new RingcaptchaApplicationHandler() {
    @Override
    public void onSuccess(RingcaptchaVerification ringcaptchaVerification) {
        //Verification successful
    }
    @Override
    public void onCancel() {
        //Decide what to do if user cancelled operation
    }
});

Implementing SMS Deep-Linking

Every SMS link sent by RingCaptcha will deep-link the user to either the application store for onboarding or the installed application for verification. Ringcaptcha link will redirect to the configured scheme and host for the app whenever a user opens the SMS link in their browser. In order to implement the custom sceheme in your app to populate automatically the PIN code, you will need to create a new intent-filter in your activity to match the following URL:

scheme://ringcaptcha/verified?token={TOKEN}&pin={PIN_CODE}

Then just add the following intent-filter in your AndroidManifest.xml file for the activity that will be managing the deep-linking:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data
        android:scheme="yourAppScheme"
        android:host="ringcaptcha" />
</intent-filter>
        

Lastly, in the Activity you've configured the intent-filter, include in the onCreate method code to handle the custom scheme like the below:

Uri data = getIntent().getData();
if(data != null && data.getQueryParameter("pin") != null) {
    String pin = data.getQueryParameter("pin");

    RingcaptchaApplication.onboard(getApplicationContext(), "{{ app_key }}", "{{ secret_key }}", pin, new RingcaptchaApplicationHandler() {
        @Override
        public void onSuccess(RingcaptchaVerification ringcaptchaVerification) {
            Log.i(TAG, "success");
        }

        @Override
        public void onCancel() {
            Log.i(TAG, "cancel");
        }
    });
}

Implementing your own UI


Should you be interested on using your own UI and calling the backend of RingCaptcha, you can do so by calling the API methods as described below.

First, Create Ringcaptcha controller using your app key

RingcaptchaAPIController controller = new RingcaptchaAPIController("{{ app_key }}");

Send an initial SMS pin code

controller.sendCaptchaCodeToNumber(getApplicationContext(), phone, RingcaptchaService.SMS, new RingcaptchaHandler() {

  //Called when the response is successful
  @Override
  public void onSuccess(RingcaptchaResponse response) {

    //Handle SMS reception automatically (only valid for verification)
    RingcaptchaAPIController.setSMSHandler(new RingcaptchaSMSHandler() {

      //Only called when SMS reception was detected
      @Override
      public boolean handleMessage(String s, String s1) {
        //Automatically verify PIN code
        return true;
      }
    });
  }
  //Called when the response is unsuccessful
  @Override
  public void onError(Exception e) {
    //Display an error to the user
  }
}, "{{ api_key }}");

Send the pin code via a VOICE call. Ideal for retry attempts or landline phones

controller.sendCaptchaCodeToNumber(getApplicationContext(), phone, RingcaptchaService.VOICE, new RingcaptchaHandler() {

  //Called when the response is successful
  @Override
  public void onSuccess(RingcaptchaResponse ringcaptchaResponse) {
    //Clear SMS handler to avoid multiple verification attempts
    RingcaptchaAPIController.setSMSHandler(null);
  }

  //Called when the response is unsuccessful
  @Override
  public void onError(Exception e) {
    //Display an error to the user
  }
}, "{{ api_key }}");

To Verify the PIN code entered by the user

controller.verifyCaptchaWithCode(getApplicationContext(), pin, new RingcaptchaHandler() {

  //Called when the response is successful
  @Override
  public void onSuccess(RingcaptchaResponse ringcaptchaResponse) {
    //Clear SMS handler to avoid multiple verification attempts
    RingcaptchaAPIController.setSMSHandler(null);
  }

  //Called when the response is unsuccessful
  @Override
  public void onError(Exception e) {
    //Display an error to the user
  }
},"{{ api_key }}");

Lookup an existing session for this device for automatic onboarding. The status of the session will be NEW if the service could not find an open session for this device, otherwise it will be SUCCESS in which case will return a list of phone numbers that match with this device.

controller.onboard(getApplicationContext(), new RingcaptchaHandler() {

  //Called when the response is successful
  @Override
  public void onSuccess(RingcaptchaResponse ringcaptchaResponse) {
    //Handle NEW or EXISTING sessions
  }

  //Called when the response is unsuccessful
  @Override
  public void onError(Exception e) {
    //Display an error to the user
  }
},"{{ api_key }}");

To use the Blink verification process bundled into the SDK, you need to handle 2 things.
First, you need to ask users for runtime permissions.
Second, call the RingcaptchaApplication.verifyPhoneNumberViaFlashCall method.

The permissions you need to ask are below.
For Android OS version >= 8.0 users, you need to ask Manifest.permission.ANSWER_PHONE_CALLS and Manifest.permission.READ_PHONE_STATE.
For Android OS version >= 6.0 and < 8.0 users, you need to ask Manifest.permission.READ_PHONE_STATE.

Here is the code sample.

public class MainActivity extends AppCompatActivity {
    private final int PERMISSIONS = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (this.checkSelfPermission(Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED || this.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                this.requestPermissions(new String[]{Manifest.permission.ANSWER_PHONE_CALLS, Manifest.permission.READ_PHONE_STATE}, PERMISSIONS);
            } else {
                verify();
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (this.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                this.requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, PERMISSIONS);
            } else {
                verify();
            }
        } else {
            verify();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSIONS:
                if (grantResults.length >= 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    verify();
                } else {
                    Toast.makeText(this, "Permissions Rejected", Toast.LENGTH_LONG).show();
                }
        }
    }

    private void verify() {
        RingcaptchaApplication.verifyPhoneNumberViaFlashCall(getApplicationContext(), "{{ app_key }}", "{{ secret_key }}", new RingcaptchaApplicationHandler() {
            @Override
            public void onSuccess(RingcaptchaVerification ringObj) {
                Toast.makeText(getApplicationContext(), "Successfully verified!", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onCancel() {
                //Decide what to do if user cancelled operation
            }
        });
    }
}