Getting started with sensitivity.io on Android

Sensitivity.io for Android offers 2 API’s to use depending on your needs:

  • High Level API - easier to integrate, less control
  • Low Level API - harder to integrate, more control

1. High Level API

The High Level API offers you simple methods for an easy integration of sensitivity.io. If you are looking for a fast integration time with no need to micromanage every part of sensitivity.io, this is the way to go.

1.1 Registration

To register a device use the Registration class. You need to register in order to download the license and the settings. You will receive the response from the server in a RegistrationListener.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
RegistrationListener registrationListener = new RegistrationListener() {

    @Override
    public void onRegistrationSuccess() {
        // success
    }

    @Override
    public void onRegistrationFailed(String errorMessage) {
        // log error
    }
};

Registration registration = new Registration(context);
if (!registration.isRegistered()) {
    registration.register(accountId, projectId, authKey, registrationListener);
}

You need 3 types of credentials for this:

  • Account Id
  • Project Id
  • Auth Key

Your credentials can be found under Account Summary here.

1.2 Retrievers

To retrieve the license and the settings use the Retriever class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
LicenseRetrieverListener licenseRetrieverListener = new LicenseRetrieverListener() {

    @Override
    public void onRetrieveLicenseSuccess(String license) {
        // store license
    }

    @Override
    public void onRetrieveLicenseFailed(String errorMessage) {
        // log error
    }
};

SettingsRetrieverListener settingsRetrieverListener = new SettingsRetrieverListener() {

    @Override
    public void onRetrieveSettingsSuccess(String settings) {
        // store settings
    }

    @Override
    public void onRetrieveSettingsFailed(String errorMessage) {
        // log error
    }
};

Retriever retriever = new Retriever(context);
retriever.retrieveLicense(licenseRetrieverListener);
retriever.retrieveSettings(settingsRetrieverListener, Module.SDS);

You should store the license and the settings because you will need them in the future.

1.3 Sensitive Data Scanner (SDS)

The SDS module scans files for possible threats (email addresses, phone numbers, etc.) and returns the results as a list of Threat objects. You can use the SDS in 5 different ways:

  • with a LocalScanner (the straightforward way)
  • with a LocalScanner and a ThreatHandler (if you want to handle threats)
  • with a MultithreadedScanner (if you want the scanner to run on more than 1 thread)
  • with a MultithreadedScanner and a ThreatHandler (if you want the scanner to run on more than 1 thread and to handle threats)
  • with a CloudScanner (if you want to send the data to the cloud)

Note

The LocalScanner and MultithreadedScanner require android.permission.WRITE_EXTERNAL_STORAGE.

1.3.1 Using the LocalScanner

The LocalScanner scans files, string or buffers on a single thread.

1
2
3
4
5
6
7
LocalScanner localScanner = new LocalScanner(context);
localScanner.loadLicense(license);
localScanner.loadSettings(settings);
List<Threat> results1 = localScanner.scanFile(file1, false);
List<Threat> results2 = localScanner.scanFile(file2, false);
List<Threat> results3 = localScanner.scanFile(file3, false);
localScanner.destroy();

If you want to handle each threat when it is found you can scan using a ThreatHandler.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
ThreatHandler threatHandler = new ThreatHandler() {

    @Override
    public boolean onThreatFound(Threat threat) {
        Log.i(TAG, "Found threat! " + threat.getType());
        return true;
    }
};

LocalScanner localScanner = new LocalScanner(context);
localScanner.loadLicense(license);
localScanner.loadSettings(settings);
localScanner.scanFile(file1, threatHandler);
localScanner.scanFile(file2, threatHandler);
localScanner.scanFile(file3, threatHandler);
localScanner.destroy();

You should always destroy the LocalScanner by calling the destroy() method to avoid memory leaks.

1.3.2 Using the MultithreadedScanner

The MultithreadedScanner scans files, string or buffers on multiple threads. You can specify the number of threads by calling the setMaxThreadCount() method. You also need a MultithreadedScanListener to get the results.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
MultithreadedScanListener multithreadedScanListener = new MultithreadedScanListener() {

    @Override
    public void onScanFinished(List<Threat> threats) {
        Log.i(TAG, "Found " + threats.size() + " threats!");
    }

    @Override
    public void onScanFailed(Exception e) {
        // log error
    }
};

MultithreadedScanner multithreadedScanner = new MultithreadedScanner(context, multithreadedScanListener);
multithreadedScanner.loadLicense(license);
multithreadedScanner.loadSettings(settings);
multithreadedScanner.setMaxThreadCount(2);
multithreadedScanner.scanFile(file1, false, 2);
multithreadedScanner.scanFile(file2, false, 3);
multithreadedScanner.scanFile(file3, false, 1);
multithreadedScanner.waitForFinished();
multithreadedScanner.destroy();

If you want to handle each threat when it is found you can scan using a ThreatHandler. In this case the MultithreadedScanListener is not needed.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
ThreatHandler threatHandler = new ThreatHandler() {

    @Override
    public boolean onThreatFound(Threat threat) {
        Log.i(TAG, "Found threat! " + threat.getType());
        return true;
    }
};

MultithreadedScanner multithreadedScanner = new MultithreadedScanner(context);
multithreadedScanner.loadLicense(license);
multithreadedScanner.loadSettings(settings);
multithreadedScanner.setMaxThreadCount(2);
multithreadedScanner.scanFile(file1, threatHandler, 2);
multithreadedScanner.scanFile(file2, threatHandler, 3);
multithreadedScanner.scanFile(file3, threatHandler, 1);
multithreadedScanner.waitForFinished();
multithreadedScanner.destroy();

You should always destroy the MultithreadedScanner by calling the destroy() method to avoid memory leaks.

1.3.3 Using the CloudScanner

The CloudScanner scans files or strings by sending the data to our web API. The license and settings are not needed in this case and you can scan multiple files on the same request. You also need a CloudScanListener to get the results.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
CloudScanListener cloudScanListener = new CloudScanListener() {

    @Override
    public void onCloudScanSuccess(List<Threat> threats) {
        Log.i(TAG, "Found " + threats.size() + " threats!");
    }

    @Override
    public void onCloudScanFailed(String errorMessage) {
        // log error
    }
};

CloudScanner cloudScanner = new CloudScanner(context, cloudScanListener);
cloudScanner.scanFiles(files, true, false);

1.4 Sensitive Data Classifier (SDC)

The SDC module classifies files into corporate or public files and returns a boolean that indicates if the content is corporate or not. You can use the SDC in 3 different ways:

  • with a LocalClassifer (the straightforward way)
  • with a MultithreadedClassifier (if you want the classifier to run on more than 1 thread)
  • with a CloudClassifier (if you want to send the data to the cloud)

Note

The LocalClassifer and MultithreadedClassifier require android.permission.WRITE_EXTERNAL_STORAGE.

1.4.1 Using the LocalClassifer

The LocalClassifer classifies files, strings or buffers on a single thread.

1
2
3
4
5
6
7
LocalClassifier localClassifier = new LocalClassifier(context);
localClassifier.loadLicense(license);
localClassifier.loadSettings(settings);
boolean isCorporate1 = localClassifier.classifyFile(file1);
boolean isCorporate2 = localClassifier.classifyFile(file2);
boolean isCorporate3 = localClassifier.classifyFile(file3);
localClassifier.destroy();

You should always destroy the LocalClassifier by calling the destroy() method to avoid memory leaks.

1.4.2 Using the MultithreadedClassifier

The MultithreadedClassifier classifies files, string or buffers on multiple threads. You can specify the number of threads by calling the setMaxThreadCount() method. You also need a MultithreadedClassificationListener to get the results.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
MultithreadedClassificationListener multithreadedClassificationListener = new MultithreadedClassificationListener() {

    @Override
    public void onClassificationFinished(boolean isCorporate) {
        Log.i(TAG, isCorporate ? "File is corporate!" : "File is public");
    }

    @Override
    public void onClassificationFailed(Exception e) {
        // handle error
    }
};

MultithreadedClassifier multithreadedClassifier = new MultithreadedClassifier(context, multithreadedClassificationListener);
multithreadedClassifier.loadLicense(license);
multithreadedClassifier.loadSettings(settings);
multithreadedClassifier.setMaxThreadCount(2);
multithreadedClassifier.classifyFile(file1, 2);
multithreadedClassifier.classifyFile(file2, 3);
multithreadedClassifier.classifyFile(file3, 1);
multithreadedClassifier.waitForFinished();
multithreadedClassifier.destroy();

You should always destroy the MultithreadedClassifier by calling the destroy() method to avoid memory leaks.

2. Low Level API

The Low Level API offers you comprehensive methods which allow you to control every part of sensitivity.io. If you need more efficiency and control at the cost of a longer integration time and more micromanagement this is the way to go.

Note

The Low Level API requires android.permission.READ_PHONE_STATE.

2.1 Loading the libraries

sensitivity.io is a C library at its core, so the first thing you need to do is load the libraries.

1
2
3
4
com.cososys.sensitivityio.base.NativeLibrariesLoader.LoadNativeLibraries();
com.cososys.sensitivityio.license.NativeLibrariesLoader.LoadNativeLibraries();
com.cososys.sensitivityio.sds.NativeLibrariesLoader.LoadNativeLibraries(); // if you use SDS module
com.cososys.sensitivityio.sdc.NativeLibrariesLoader.LoadNativeLibraries(); // if you use SDC module

Next you should give the libraries your application context.

1
com.cososys.sensitivityio.android_utils.ApplicationContext.Set(getApplicationContext());

2.2 Registration

You need to register your device in order to download the license and the settings. First initialize your HttpRetriever.

1
2
3
HttpRetriever.SetAccountId(accountId);
HttpRetriever.SetProjectId(projectId);
HttpRetriever.SetAuthenticationKey(authKey);

Then proceed and register your device.

1
ApplicationIdRetriever.GetInstance().RetrieveApplicationId();

You need 3 types of credentials for this:

  • Account Id
  • Project Id
  • Auth Key

Your credentials can be found under Account Summary here.

2.3 Retrievers

To retrieve the license use the LicenseRetriever class.

1
2
LicenseRetriever licenseRetriever = LicenseRetriever.GetInstance();
String license = licenseRetriever.RetrieveToStringAndNotifyLoader();

To retrieve the settings use the ScannerSettingsRetriever or the ClassifierSettingsRetriever class, depending on which module you use.

1
2
ScannerSettingsRetriever settingsRetriever = new ScannerSettingsRetriever();
String settings = settingsRetriever.RetrieveToStringAndNotifyLoader();

You should store the license and the settings because you will need them in the future.

2.4 Sensitive Data Scanner (SDS)

The SDS module scans files for possible threats (email addresses, phone numbers, etc.). You can use the SDS in 4 different ways:

  • with a Scanner (the straightforward way)
  • with a Scanner and a IThreatHandler (if you want to handle threats)
  • with a ScannerExecutor (if you want the scanner to run on more than 1 thread)
  • with a ScannerExecutor and a IThreatHandler (if you want the scanner to run on more than 1 thread and to handle threats)

Note

The Scanner and ScannerExecutor require android.permission.WRITE_EXTERNAL_STORAGE.

2.4.1 Using the Scanner

The Scanner scans files, string or buffers on a single thread and returns an array of ThreatInfo objects.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Scanner scanner = new Scanner();
LicenseLoader.GetInstance().LoadLicenseFromString(license);
ScannerSettingsLoader settingsLoader = new ScannerSettingsLoader();
settingsLoader.LoadSettingsFromString(settings);
settingsLoader.RegisterScanner(scanner);
ThreatInfo[] threatsInfos1 = scanner.ScanFile(filePath1, false);
ThreatInfo[] threatsInfos2 = scanner.ScanFile(filePath2, false);
ThreatInfo[] threatsInfos3 = scanner.ScanFile(filePath3, false);
settingsLoader.UnregisterScanner(scanner);
scanner.Destroy();
settingsLoader.Destroy();

If you want to handle each threat when it is found you can scan using an IThreatHandler.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
IThreatHandler iThreatHandler = new IThreatHandler() {

    @Override
    public boolean HandleThreat(ThreatInfo threatInfo) {
      Log.i(TAG, "  Found threat! " + ThreatTypeId.GetThreatTypeName(threatInfo.GetThreatTypeId()));
      return true;
    }
};

Scanner scanner = new Scanner();
LicenseLoader.GetInstance().LoadLicenseFromString(license);
ScannerSettingsLoader settingsLoader = new ScannerSettingsLoader();
settingsLoader.LoadSettingsFromString(settings);
settingsLoader.RegisterScanner(scanner);
scanner.ScanFile(filePath1, iThreatHandler);
scanner.ScanFile(filePath2, iThreatHandler);
scanner.ScanFile(filePath3, iThreatHandler);
settingsLoader.UnregisterScanner(scanner);
scanner.Destroy();
settingsLoader.Destroy();

You should always destroy the Scanner and the ScannerSettingsLoader by calling the Destroy() method to avoid memory leaks.

2.4.2 Using the ScannerExecutor

The ScannerExecutor scans files, string or buffers on multiple threads. You can specify the number of threads by calling the SetMaxThreadCount() method. You will get the results in a ThreatInfosFuture object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
ScannerExecutor scannerExecutor = new ScannerExecutor();
LicenseLoader.GetInstance().LoadLicenseFromString(license);
ScannerSettingsLoader settingsLoader = new ScannerSettingsLoader();
settingsLoader.LoadSettingsFromString(settings);
settingsLoader.RegisterScannerExecutor(scannerExecutor);
scannerExecutor.GetThreadPool().SetMaxThreadCount(2);
ThreatInfosFuture threatsInfosFuture1 = scannerExecutor.ScanFile(filePath1, false, 2);
ThreatInfosFuture threatsInfosFuture2 = scannerExecutor.ScanFile(filePath2, false, 3);
ThreatInfosFuture threatsInfosFuture3 = scannerExecutor.ScanFile(filePath3, false, 1);
scannerExecutor.GetThreadPool().WaitForDone();
ThreatInfo[] threatInfos1 = threatsInfosFuture1.GetResult();
ThreatInfo[] threatInfos2 = threatsInfosFuture2.GetResult();
ThreatInfo[] threatInfos3 = threatsInfosFuture3.GetResult();
threatsInfosFuture1.Destroy();
threatsInfosFuture2.Destroy();
threatsInfosFuture3.Destroy();
settingsLoader.UnregisterScannerExecutor(scannerExecutor);
scannerExecutor.Destroy();
settingsLoader.Destroy();

Note

The ThreatInfosFuture object does not have the result straight away, so you will have to periodically check for the result until it returns a non null value.

If you want to handle each threat when it is found you can scan using an IThreatHandler.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
IThreatHandler iThreatHandler = new IThreatHandler() {

    @Override
    public boolean HandleThreat(ThreatInfo threatInfo) {
        Log.i(TAG, "  Found threat! " + ThreatTypeId.GetThreatTypeName(threatInfo.GetThreatTypeId()));
        return true;
    }
};

ScannerExecutor scannerExecutor = new ScannerExecutor();
LicenseLoader.GetInstance().LoadLicenseFromString(license);
ScannerSettingsLoader settingsLoader = new ScannerSettingsLoader();
settingsLoader.LoadSettingsFromString(settings);
settingsLoader.RegisterScannerExecutor(scannerExecutor);
scannerExecutor.GetThreadPool().SetMaxThreadCount(2);
VoidFuture voidFuture1 = scannerExecutor.ScanFile(filePath1, iThreatHandler, 2);
VoidFuture voidFuture2 = scannerExecutor.ScanFile(filePath2, iThreatHandler, 3);
VoidFuture voidFuture3 = scannerExecutor.ScanFile(filePath3, iThreatHandler, 1);
scannerExecutor.GetThreadPool().WaitForDone();
voidFuture1.Destroy();
voidFuture2.Destroy();
voidFuture3.Destroy();
settingsLoader.UnregisterScannerExecutor(scannerExecutor);
scannerExecutor.Destroy();
settingsLoader.Destroy();

You should always destroy the ScannerExecutor and the ScannerSettingsLoader by calling the Destroy() method to avoid memory leaks.

2.5 Sensitive Data Classifier (SDC)

The SDC module classifies files into corporate or public files and returns the result as a Classification object. You can use the SDC in 2 different ways:

  • with a Classifier (the straightforward way)
  • with a ClassifierExecutor (if you want the classifier to run on more than 1 thread)

Note

The Classifier and ClassifierExecutor require android.permission.WRITE_EXTERNAL_STORAGE.

2.5.1 Using the Classifier

The Classifier classifies files, strings or buffers on a single thread.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Classifier classifier = new Classifier();
LicenseLoader.GetInstance().LoadLicenseFromString(license);
ClassifierSettingsLoader settingsLoader = new ClassifierSettingsLoader();
settingsLoader.LoadSettingsFromString(settings);
settingsLoader.RegisterClassifier(classifier);
Classification classification1 = classifier.ClassifyFile(filePath1);
Classification classification2 = classifier.ClassifyFile(filePath2);
Classification classification3 = classifier.ClassifyFile(filePath3);
settingsLoader.UnregisterClassifier(classifier);
classifier.Destroy();
settingsLoader.Destroy();

You should always destroy the Classifier and ClassifierSettingsLoader by calling the Destroy() method.

2.5.2 Using the ClassifierExecutor

The ClassifierExecutor classifies files, string or buffers on multiple threads. You can specify the number of threads by calling the SetMaxThreadCount() method. You will get the result in a ClassificationFuture object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
ClassifierExecutor classifierExecutor = new ClassifierExecutor();
LicenseLoader.GetInstance().LoadLicenseFromString(license);
ClassifierSettingsLoader settingsLoader = new ClassifierSettingsLoader();
settingsLoader.LoadSettingsFromString(settings);
settingsLoader.RegisterClassifierExecutor(classifierExecutor);
classifierExecutor.GetThreadPool().SetMaxThreadCount(2);
ClassificationFuture classificationFuture1 = classifierExecutor.ClassifyFile(filePath1, 2);
ClassificationFuture classificationFuture2 = classifierExecutor.ClassifyFile(filePath2, 3);
ClassificationFuture classificationFuture3 = classifierExecutor.ClassifyFile(filePath3, 1);
classifierExecutor.GetThreadPool().WaitForDone();
Classification classification1 = classificationFuture1.GetResult();
Classification classification2 = classificationFuture2.GetResult();
Classification classification3 = classificationFuture3.GetResult();
classificationFuture1.Destroy();
classificationFuture2.Destroy();
classificationFuture3.Destroy();
settingsLoader.UnregisterClassifierExecutor(classifierExecutor);
classifierExecutor.Destroy();
settingsLoader.Destroy();

Note

The ClassificationFuture object does not have the result straight away, so you will have to periodically check for the result until it returns a non null value.

You should always destroy the ClassifierExecutor and ClassifierSettingsLoader by calling the Destroy() method.