Android and iOS
Idea
The way software licensing can be added to an application for a mobile OS such as Android or iOS depends on what framework your application is written in. There are multiple possibilities:
- Default for that platform: the application is written in the default language for that platform i.e. Java for Android and Objective-C for iOS.
- Bridge: the original application/library is written in C/C++ (eg. producing a .so file) with a wrapper in the default language for that platform (eg. Java for Android).
- Other framework: the application is written in a framework such as Unity or Xamarin.
We will cover each of these cases below:
Implementation
Default language
Android
Since Java is the default language of Android applications, you can use our Java client. You need to use the jar file called cryptolens-android.jar
. Pre-compiled jar files can be found here.
Please note that
Helpers.GetMachineCode()
is not supported and that when you callHelpers.IsOnRightMachine()
, you need to use those that allow you to specify a custom machine code. You can use InstanceId instead or other approaches described later in the tutorial.
Adding the library
You can add the library by adding api files('libs/cryptolens-android.jar')
in build.gradle
(Module: app), as shown below. Please note that cryptolens-android.jar
needs to be in the libs
folder of your project.
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.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'
api files('libs/cryptolens-android.jar')
}
Verifying a license
Since license key verification (eg. Key.Activate) uses networking, we need to call it asynchronously (i.e. not on the main thread). Moreover, we need to ensure that internet permission is set.
To call a method asynchronously, we can wrap it as shown below. For example, we can paste the code snippet from the key verification tutorial into the run
method below:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// call eg. Key.Activate.
}
});
thread.start();
Internet permission requires a small change in the manifest file:
...
<uses-permission android:name="android.permission.INTERNET"/>
<application ...
Obtaining the machine code
On Android devices, there are many ways of obtaining a unique device identifier, all of them with their own trade offs. If you don’t want to require any specific permission, it’s possible to use Android Id, obtained as shown below:
String machineCode = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID);
This should be unique for each device, but it will change after a factory reset and there have been instances that certain devices had the same Android Id.
You could also use the following method:
TelephonyManager tm =
(TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String machineCode = tm.getDeviceId();
Although it won’t change during a factory restore, it requires a special permission.
iOS
There is no client library for Objective-C or Swift at the moment. Instead, we recommend to use the other approaches listed below.
Bridge
A common way to develop mobile applications or SDKs is to put most of the logic into a C++ library and add a wrapper around it in Java or Objective-C. This approach makes it easier to maintain the application (since you mostly have one code base) and it tends to be harder to reverse engineer (since C++ compiles into native CPU instructions). If you develop an SDK, having a bridge allows you to expose functionality without revealing the source code.
Other framework
Unity
If your application uses Unity, we recommend the following article for more information.
Xamarin
For Xamarin applications, the same approach that was described in the Unity article can be used.
Considerations
Machine codes
On mobile platforms, GetMachineCode
and IsOnRightMachine
will not work. Instead, you can use the the identifiers provided by respective platform.
Android
On Android, we recommend to use Instance Id, as described here.
iOS
On iOS, we recommend to use the identifierForVendor.