Integration
Related Articles
Starting Begini SDK integration
First in your project’s Application class, override onCreate function and initialize BeginiApp().onCreate()
just below the super.onCreate()
Kotlin:
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
getInstance().onCreate()
}
companion object {
@Volatile
private var beginiInstance: BeginiApp? = null
fun getInstance(): BeginiApp {
return beginiInstance ?: synchronized(this) {
val instance = BeginiApp()
beginiInstance = instance
instance
}
}
}
}
And provide the name of the application class in the application tag inside the Android Manifest file.
<application
android:name=".MyApp"
... >
</application>
How to integrate the Begini SDK's built-in UI?
Begini SDK works in a new Activity. You must have declared the BeginiCoreActivity
in your app’s Android Manifest.
<activity
android:name="com.begini.androidsdkv2.ui.base.BeginiCoreActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />
Applying Theme
When declaring the above BeginiCoreActivity
activity on the manifest, if you are using a theme with the action bar enabled, specify a NoActionBar
theme to the BeginiCoreActivity
.
For example :
<activity
android:name="com.begini.androidsdkv2.ui.base.BeginiCoreActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/Theme.AndroidSdk.NoActionBar"/>
The Begini SDK will automatically adapt the color combination (colorPrimary
) specified on the theme applied on BeginiCoreActivity
.
In the above example : @style/Theme.AndroidSdk.NoActionBar
will contain the color
<item name="colorPrimary">@color/purple_500</item>
And the purple_500 color will be applied as the theme of the Android SDK.
How to change language in the Begini SDK's built-in UI?
Begini SDK supports multiple languages, which can be configured from the client application.
1. Application language can be passed from Activity or fragment before initiating the library.
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
var appLanguage = "en";//setting language english
if (Locale.getDefault().language.equals("th")) {
/*if device language is thai, choosing language as thai*/
appLanguage = "th"
}
//setting sdk UI language as thai
MyApp.getInstance().uiLanguage = appLanguage
// rest of the code
2. Example to set language as “Thai” in library :
MyApp.getInstance().uiLanguage = "th"
Setup SDK Request
BeginiDataSdkOptions(#SDK_INPUT_DATA)
BeginiDataSdkOptions
is the Class which will contain the request from your application to Begini SDK.
Begini SDK reads device data in order to create the most accurate credit score. That is, Contacts, Call Log, Calendar, Battery information, Bluetooth Information, Wifi information, Gallery, Media, Installed Application list, Location and Profile (includes screen, volume, hardware and phone settings information).
BeginiDataSdkOptions
lets you decide which of those device data can be accessed for your App.
Also the integration_id
, api_key
and u_id
must be passed to Begini SDK via BeginiDataSdkOptions
request.
u_id
is the id of the user which can be decided by the client app, but for each user the u_id
should be different.
class BeginiDataSdkOptions(
var u_id:String="",
var integration_id:String="",
var api_key:String="",
var isContactsEnabled: Boolean = false,
var isSmsEnabled: Boolean = false,
var isInstalledAppsEnabled: Boolean = false,
var isProfileEnabled: Boolean = false,
var isBatteryEnabled: Boolean = false,
var isBluetoothEnabled: Boolean = false,
var isWifiEnabled: Boolean = false,
var isMediaMetadataEnabled: Boolean = false,
var isGalleryExifDataEnabled: Boolean = false,
var isCallsEnabled: Boolean = false,
var isCalendarEnabled: Boolean = false,
var isLocationEnabled: Boolean = false,
var isPiiHashingEnabled: Boolean = false,
var language: String = "en",
var countryCode: String = "global",
) : Serializable
Example initialization of BeginiDataSdkOptions
Kotlin:
val beginiDataSdkOptions: BeginiDataSdkOptions = BeginiDataSdkOptions(
u_id = customerID,
integration_id = "6332b79fsdfsfsdfasd"
api_key = "8sdfs1c-dsf8-47ed-82sfb9e1sdfcd53",
isContactsEnabled = true,
isSmsEnabled = false,
isCallsEnabled = false,
isCalendarEnabled = true,
isBatteryEnabled = true,
isBluetoothEnabled = true,
isWifiEnabled = true,
isGalleryExifDataEnabled = true,
isMediaMetadataEnabled = true,
isProfileEnabled = true,
isInstalledAppsEnabled = true,
isLocationEnabled = true,
isPiiHashingEnabled = true,
language = "en",
countryCode= "us"
)
Java:
Intent intent=new Intent(MainActivity.this, BeginiCoreActivity.class);
BeginiDataSdkOptions beginiDataSdkOptions=new BeginiDataSdkOptions();
beginiDataSdkOptions.setU_id("42LW46J9");
beginiDataSdkOptions.setIntegration_id("62uyfhgfjhjaa61e8");
beginiDataSdkOptions.setApi_key("1b4gd-dgf-dfg-fdh-e3105345");
beginiDataSdkOptions.setContactsEnabled(true);
beginiDataSdkOptions.setCalendarEnabled(true);
beginiDataSdkOptions.setBatteryEnabled(true);
beginiDataSdkOptions.setBluetoothEnabled(true);
beginiDataSdkOptions.setWifiEnabled(true);
beginiDataSdkOptions.setGalleryExifDataEnabled(true);
beginiDataSdkOptions.setMediaMetadataEnabled(true);
beginiDataSdkOptions.setProfileEnabled(true);
beginiDataSdkOptions.setInstalledAppsEnabled(true);
beginiDataSdkOptions.setLocationEnabled(true);
beginiDataSdkOptions.setSmsEnabled(true);
beginiDataSdkOptions.setCallsEnabled(true);
beginiDataSdkOptions.setLanguage("en");
beginiDataSdkOptions.setCountryCode("us");
The non-mandatory permissions can be added according to the request that is passing through the BeginiDataSdkOptions
That is,
If isGalleryExifDataEnabled = true
or if isMediaMetadataEnabled = true
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
Will need to be added to your manifest, and is the case for the subsequent optional permissions.
Likewise
For isContactsEnabled = true
<uses-permission android:name="android.permission.READ_CONTACTS" />
For isCalendarEnabled = true
<uses-permission android:name="android.permission.READ_CALENDAR" />
For isBluetoothEnabled = true
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
For isWifiEnabled = true
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
For isLocationEnabled = true
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
For isCallsEnabled = true
<uses-permission android:name="android.permission.READ_CALL_LOG" />
For isSmsEnabled = true
<uses-permission android:name="android.permission.READ_SMS" />
Please note
android.permission.READ_CALL_LOG
and android.permission.READ_SMS
are sensitive permissions.
So if you are using isCallsEnabled
and isSmsEnabled
, make sure that you follow these guidelines. Otherwise, your app will be rejected by the app verification team of Google Play Store.
PII Hashing
We are using SHA-256 cryptographic hashing method to hash personally identifiable information of a user. Once the PII is hashed, a fixed 256-bit (32-byte) hash value will be shown instead of PII.
This Hashing mechanism is irreversible, but if you try to hash the same value using SHA-256 algorithm, you will always get the same result. In that way you can compare/search for a particular word/value. Please note a small change in the input (even one bit) will produce a completely different hash value.
Example of a hashed value will look like:
b94d27b9934d3e08a52e52d7da7dabfa6cfc849bfa19d3e1d6dba3fe134c4aef
The isPiiHashingEnabled
value on BeginiDataSdkOptions
will enable the SHA-256 hashing functionality in the SDK.
Setting isPiiHashingEnabled = true
Starting Begini SDK data collection
Kotlin:
var intent = Intent(activity, BeginiCoreActivity::class.java)
intent.putExtra("OPTIONS", beginiDataSdkOptions)
requestBeginiActivityForResult.launch(intent)
Java:
Intent intent = new Intent(MainActivity.this, BeginiCoreActivity.class);
intent.putExtra("OPTIONS", beginiDataSdkOptions);
requestBeginiActivityForResult.launch(intent);
requestBeginiActivityForResult declaration explained below.
Handling SDK Result
Once you started the BeginiCoreActivity
you can receive the result of SDK from the same fragment/activity using registerForActivityResult
Basic Result Handling
Kotlin:
private val requestBeginiActivityForResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
var result =
(activityResult.data?.extras?.getSerializable("DATA") as BeginiDataSdkResult)
} else {
Log.e("BeginiSdkResult", "Result Not Success.")
}
}
Java:
ActivityResultLauncher<Intent> requestBeginiActivityForResult = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult activityResult) {
if (activityResult.getResultCode() == Activity.RESULT_OK) {
BeginiDataSdkResult result =
(BeginiDataSdkResult) activityResult.getData().getExtras().getSerializable("DATA");
}else {
Log.e("BeginiSdkResult", "Result Not Success.");
}
}
});
Basic results can be identified from ActivityResult.resultCode
The response from BeginiSDK will always pass via ActivityResult.resultCode will be Activity.RESULT_OK
Any other result code can be considered as unsuccessful result.
If the result code is Activity.RESULT_OK the detailed information regarding the SDK working will be available through BeginiDataSdkResult
Kotlin:
var result =(activityResult.data?.extras?.getSerializable("DATA") as BeginiDataSdkResult)
Java:
BeginiDataSdkResult result = (BeginiDataSdkResult)
activityResult.getData().getExtras().getSerializable("DATA");
There will be detailed result information in the BeginiDataSdkResult
class BeginiDataSdkResult(
var isProcessCompletedSuccessfully: Boolean,
var mainErrorReason:String,
var BACKEND_ERROR_CODE: String,
var ERROR_OCCUR_LOCATION: Int,
//Results of DATA_COLLECTION / digging will be in the following variables
var CONTACTS: Int,
var INSTALLED_APPS: Int,
var PROFILE: Int,
var BATTERY: Int,
var BLUETOOTH: Int,
var WIFI: Int,
var MEDIA_METADATA: Int,
var GALLERY_EXIF: Int,
var CALENDER: Int,
var LOCATION: Int,
var CALL_LOG: Int,
var SMS: Int,
var DISK_WRITE: Int,
var SERVER_SYNC: Int,
)
isProcessCompletedSuccessfully: will be true if the entire process is completed successfully.
If isProcessCompletedSuccessfully is false, you can find the reason from the mainErrorReason, ERROR_OCCUR_LOCATION and BACKEND_ERROR_CODE
mainErrorReason will contain a text explanation.
BACKEND_ERROR_CODE: This field will contain the error code from the backend.
ERROR_OCCUR_LOCATION: If any error occurs this field will contain any value from any ResultConstants class.
The other items (DATA_COLLECTION) in the BeginiDataSdkResult will contain one of the below values from ResultConstants
object ResultConstants {
//the below constants will pass to ERROR_OCCUR_LOCATION if any error occur const val RESULT_DEFAULT = 12000
const val DATA_COLLECTION_SUCCESS = 12001
const val DATA_COLLECTION_FAILED_PERMISSION_DENIED = 12002
const val DATA_COLLECTION_OPTION_DISABLED = 12004
const val DATA_COLLECTION_FAILED_EXCEPTION = 12005
const val RESULT_FAILED_NETWORK = 12003
//the below constants will pass to ERROR_OCCUR_LOCATION if any error occur
const val RESULT_ERROR_ON_SESSION = 12006
const val RESULT_ERROR_ON_TOKEN_GENERATION = 12009
const val RESULT_ERROR_ON_FILE_UPLOADING = 12010
const val RESULT_ERROR_ON_DATA_READING = 12011
const val RESULT_CANCELED_FROM_PERMISSION_SCREEN = 12012
const val RESULT_CANCELED_FROM_BACK_BUTTON = 12014
const val RESULT_CANCELED_FROM_DATA_COLLECTION_SCREEN = 12013
const val RESULT_ERROR_ON_PERMISSION_SCREEN = 12016
}
according to ResultConstants value you will get the idea of entire SDK process.
Advanced Result Handing (#SDK_RESULT_HANDLING)
Kotlin:
private val requestBeginiActivityForResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
var result =
(activityResult.data?.extras?.getSerializable("DATA") as BeginiDataSdkResult)
if (result.isProcessCompletedSuccessfully) {
//All sdk process is completed successfully.
} else {
//Something went wrong sdk process is not completed.
if (!result.mainErrorReason.trim().isNullOrEmpty()) {
message=result.mainErrorReason
//Main error reason from sdk can be found in result.mainErrorReason
}
//identify where the error was occur.
if (result.ERROR_OCCUR_LOCATION != ResultConstants.RESULT_DEFAULT) {
when (result.ERROR_OCCUR_LOCATION) {
ResultConstants.RESULT_ERROR_ON_SESSION -> {
//Error happened related to session creation on sdk.
}
ResultConstants.RESULT_ERROR_ON_PERMISSION_SCREEN -> {
//Error happened on the permission request screen of sdk .
}
ResultConstants.RESULT_ERROR_ON_TOKEN_GENERATION -> {
//Error happened on sdk while trying to authenticate client app.
}
ResultConstants.RESULT_ERROR_ON_FILE_UPLOADING -> {
//Error happened on sdk while trying while sync data with begini server.
}
ResultConstants.RESULT_ERROR_ON_DATA_READING -> {
//Error happened on sdk while trying get required data from device.
}
ResultConstants.RESULT_CANCELED_FROM_PERMISSION_SCREEN -> {
//User canceled session from permission screen of sdk.
}
ResultConstants.RESULT_CANCELED_FROM_DATA_COLLECTION_SCREEN -> {
//User canceled session from data collection screen of sdk.
}
}
}
}
} else{
Log.e("Result", "Result Unsuccessful")
}
}
How to integrate the Begini SDK's service?
Begini SDK service is created to integrate Begini SDK manage with your own user interface. Begini SDK’s service works as a Foreground service on Android OS.
Your Application class needs to be updated.
1. Before calling getInstance().onCreate()
; you need to setup your notification channel.
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
MyAppConstants.NOTIFICATION_CHANNEL_FOR_BEGINI,
"Running Notification", NotificationManager.IMPORTANCE_HIGH
)
val notificationManger =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManger.createNotificationChannel(channel)
}
getInstance().onCreate()
}
companion object {
@Volatile
private var beginiInstance: BeginiApp? = null
fun getInstance(): BeginiApp {
return beginiInstance ?: synchronized(this) {
val instance = BeginiApp()
beginiInstance = instance
instance
}
}
}
}
2. MyAppConstants.NOTIFICATION_CHANNEL_FOR_BEGINI
is a string constant value. You can create it anywhere in your code base.
class MyAppConstants {
companion object {
val NOTIFICATION_CHANNEL_FOR_BEGINI = "1000985444"//example NotificationChannel
}
}
3. Now pass the channel name and notification icon resource to the Begini SDK as in the following code
val beginiDataSdkOptions: BeginiDataSdkOptions = BeginiDataSdkOptions(
u_id = customerID,
integration_id = "6724892eb58ceed6841288a7",
api_key = "a6fb8485-8aab-420e-b159-28cab5a33b05",
isContactsEnabled = false,
isSmsEnabled = false,//this should be always false since the sms permission is denied by play store.
isCallsEnabled = false,//this should be always false since the call log permission is denied by play store.
isCalendarEnabled = true,
isBatteryEnabled = true,
isBluetoothEnabled = true,
isWifiEnabled = true,
isGalleryExifDataEnabled = true,
isMediaMetadataEnabled = true,
isProfileEnabled = true,
isInstalledAppsEnabled = true,
isLocationEnabled = true,
isPiiHashingEnabled = true,
notificationChannelName = MyAppConstants.NOTIFICATION_CHANNEL_FOR_BEGINI,
notificationIconResId = R.drawable.ic_launcher_foreground,
language = appLanguage,
countryCode = "us"
)
4. Declare BeginiCoreService
on manifest.
FIrst of all you need to introduce Begini service class to your project. For that
Add
<service
android:name="com.begini.androidsdkv2.services.BeginiCoreService"
android:foregroundServiceType="dataSync">
</service>
To your manifest.
On your Activity or fragment:
1. Get all the runtime permissions including FOREGROUND_SERVICE
which are needed for your data collection.
2. Create a BeginiServiceListener
A BeginiServiceListener
helps you to manage response from BeginiCoreService
.
Kotlin
var beginiServiceListener = object : BeginiServiceListener {
override fun getProgress(progressPercentage: Int, data: Any?,updateStatus:UpdateStatus?,sdkStatus:SDKStatus?) {
when(sdkStatus){
SDKStatus.SESSION_START_SUCCESS->{
//here you should start the data collection process by calling
beginiCoreService?.startDataCollection()
}
SDKStatus.SESSION_DATA_COLLECTION_SUCCESS->{
//here you should update the end session
beginiCoreService?.endSession()
}
Timber.d("#Service Connection Progress: "+progressPercentage)
if(updateStatus!=null&&updateStatus.equals(UpdateStatus.ERROR)){
var result= (data as BeginiDataSdkResult)
if(result.messageToShowUser.isNotEmpty())
showDialog(result.messageToShowUser)
}
}
})
On the service listener these are the parameters which will give you idea about SDK process updates.
progressPercentage will contain progress of SDK working and will have a value between 0-100 which you can use to show progress on your UI on a progress bar or on any other indicator.
data will be a type of BeginiDataSdkResult
can be used just like explained on #SDK_RESULT_HANDLING
updateStatus will contain different status response from SDK and will be one of the following UpdateStatus value
enum class UpdateStatus {
STARTED,
IN_PROGRESS,
COMPLETED,
CANCELED,
ERROR_SHOW_DIALOG,
PROGRESS,
ERROR
}
sdkStatus will contain different status response from SDK and will be one of the following SDKStatus value
enum class SDKStatus {
SESSION_TOKEN_GEN_SUCCESS,
SESSION_TOKEN_GEN_FAILED,
SESSION_START_SUCCESS,
SESSION_START_FAILED,
SESSION_CANCEL_SUCCESS,
SESSION_CANCEL_FAILED,
SESSION_PERMISSION_UPDATE_SUCCESS,
SESSION_PERMISSION_UPDATE_FAILED,
SESSION_DATA_COLLECTION_SUCCESS,
SESSION_DATA_COLLECTION_FAILED,
SESSION_END_SUCCESS,
SESSION_END_FAILED,
STATUS_UNKNOWN,
}
3. Create a service connection.
To get response from BeginiCoreService we need to pass our BeginiServiceListener to a service connection.
val serviceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
val beginiBinder = service as BeginiCoreService.BeginiCoreBinder
beginiCoreService = beginiBinder.getService()
beginiCoreService?.setBeginiListener(beginiServiceListener)
}
override fun onServiceDisconnected(name: ComponentName) {
// The service has unexpectedly disconnected
}
}
Save the beginiCoreService object for future usage. Since beginiCoreService is an instance of your current running BeginiCoreService. You will be able to manage the SDK working by using this beginiCoreService object.
That is
4. Start BeginiCoreService using intent
And here is the sample code to show how to call Begini Service.
Here you can see beginiDataSdkOptions in the code section. I have already explained how to create BeginiDataSdkOptions on the beginning of this document (#SDK_INPUT_DATA). The same input needs to pass instead of beginiDataSdkOptions in the below code.
val intent = Intent(requireActivity(), BeginiCoreService::class.java)
intent.putExtra("OPTIONS", beginiDataSdkOptions)
requireActivity().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
ContextCompat.startForegroundService(context!!,intent)
Once this start ForegroundService method is called, the service will start the session and will share the SESSION_START_SUCCESS or SESSION_START_FAILED status via BeginiServiceListener
5. Start Datacollection
With beginiCoreService object you can start the data collection process. For example.
beginiCoreService?.startDataCollection()
Ensure that the startDataCollection() function is invoked to activate the data collection process within the SDK. The SDK will remain idle until this function is called. It is essential to call startDataCollection() after receiving the SESSION_START_SUCCESS status on your listener. Following the completion or failure of data collection, the SDK will communicate via the BeginiServiceListener with either SESSSION_DATA_COLLECTION_SUCCESS or SESSION_DATA_COLLECTION_FAILED.
6. End session to complete Begini SDK flow.
Once the data collection is completed/failed you can call
beginiCoreService?.endSession()
To end the session, calling endSession() is a very important thing to do, or your session will expire on the Begini dashboard after some time.