The Connect SDK for Android allows developers to create applications that use Telenor Connect for sign-in or payment. More information about Telenor Connect can be found on our partner portal.
This SDK uses the Connect ID and Connect Payment APIs. Documentation for these APIs can be found at docs.telenordigital.com.
Before being able to use Telenor Connect in your application, you first need to get your application registered with Telenor Connect. This can be done using a form on our website.
The binaries are included on JCenter, so the SDK can be added by including a line in your build.gradle
file for your app.
dependencies {
// ...
compile 'com.telenor.connect:connect-android-sdk:0.5.0' // add this line
}
You might have to add JCenter as a repository on your top-level build.gradle
file if this isn't done already:
allprojects {
repositories {
jcenter()
}
}
Notice: The AndroidManifest.xml needs to be setup before you can use the SDK.
You can authenticate the user and authorize your application by using a ConnectLoginButton
:
public class SignInActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_in);
// Initialize the SDK
ConnectSdk.sdkInitialize(getApplicationContext());
// Find the ConnectLoginButton present in activity_sign_in.xml
ConnectLoginButton loginButton = (ConnectLoginButton) findViewById(R.id.login_button);
// Set the scope. The user can click the button afterwords
loginButton.setLoginScopeTokens("profile openid");
}
// onActivityResult will be called once the login has completed
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
Intent intent = new Intent(getApplicationContext(), SignedInActivity.class);
startActivity(intent);
finish();
}
}
}
Where activity_sign_in.xml
looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.telenor.connect.connectidexample.SignInActivity">
<com.telenor.connect.ui.ConnectLoginButton
android:layout_centerInParent="true"
android:id="@+id/login_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/com_telenor_ConnectButton.Dark"/>
</RelativeLayout>
Once the user is signed in you can get a valid Access Token by calling ConnectSdk.getValidAccessToken(…)
:
ConnectSdk.getValidAccessToken(new AccessTokenCallback() {
@Override
public void onSuccess(String accessToken) {
// app code
}
@Override
public void onError(Object errorData) {
// app code
}
});
The SDK allows for two ways of accessing user information. Either by requesting and accessing an IdToken
or by making a network call using getUserInfo(…)
.
Note: The presence of the fields depend on the scope and claim variables that were given at sign in time. See http://docs.telenordigital.com/apis/connect/id/authentication.html for more details.
When authenticating the user make sure to request the openid
scope:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_in);
ConnectSdk.sdkInitialize(getApplicationContext());
ConnectLoginButton loginButton = (ConnectLoginButton) findViewById(R.id.login_button);
loginButton.setLoginScopeTokens("openid");
}
When the user has authenticated you can call:
IdToken idToken = ConnectSdk.getIdToken();
And access user information by calling for example:
String email = idToken.getEmail();
You can also access user information by making a network call using getUserInfo(…)
:
ConnectSdk.getUserInfo(new Callback<UserInfo>() {
@Override
public void success(UserInfo userInfo, Response response) {
// app code
}
@Override
public void failure(RetrofitError error) {
// app code
}
});
For a full example, which includes both the setup in AndroidManifest.xml
and sign in, see the connect-id-example
app.
Run it by following these steps:
git clone git@github.com:telenordigital/connect-android-sdk.git
- Open
connect-android-sdk
in Android Studio. - Select
id-example
Run Configuration and and run it (ctrl+r)
Before using the SDK some entries have to be added to AndroidManifest.xml
. The example app contains a full example of a valid AndroidManifest.xml
.
Telenor Connect has 2 environments
that can be used, staging and production. The environment can be selected using the
com.telenor.connect.USE_STAGING
meta-data property in your AndroidManifest.xml
<meta-data
android:name="com.telenor.connect.USE_STAGING"
android:value="true" />
Set this to false
if you want to use the production environment.
Connect ID supports two different client types: public and confidential. Please see the Native app guide to help you make a decision.
If it is a confidential client add the following to the manifest:
<meta-data
android:name="com.telenor.connect.CONFIDENTIAL_CLIENT"
android:value="true" />
The Connect ID integration requires a Client ID and a redirect URI to work. You should receive these when registering your application.
The Client ID and redirect URI should be added to your strings.xml
file. Add strings with the names connect_client_id
and connect_redirect_uri
.
<string name="connect_client_id">example-clientid</string>
<string name="connect_redirect_uri">example-clientid://oauth2callback</string>
Add meta-data
entries to the application
section of the manifest.
<application>
...
<meta-data
android:name="com.telenor.connect.CLIENT_ID"
android:value="@string/connect_client_id" />
<meta-data
android:name="com.telenor.connect.REDIRECT_URI"
android:value="@string/connect_redirect_uri" />
...
</application>
Open your application's AndroidManifest.xml
file and add the permission required to allow your
application to access the internet.
<uses-permission android:name="android.permission.INTERNET"/>
Optionally you can enable the feature that automatically fills in verification PIN codes received on SMS by adding the following permissions.
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
Note: You should be conscious about the security implications of using this feature. When using this feature your application will load received SMS into memory for up to 60 seconds. Upon finding an SMS with the word CONNECT
and a PIN-code, the PIN code will be parsed and passed back to a callback JavaScript function. More discussion can be found in issue #15.
The ConnectActivity
needs to be added to the manifest in order to work. Add it to the application
section.
<application>
...
<activity
android:name="com.telenor.connect.ui.ConnectActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light.NoActionBar" />
...
</application>
To let the SDK handle Connect ID login, a ConnectLoginButton
can be added to your layout. This is
a custom Button
implementation that has the standard Connect button look-and-feel.
Firstly add a button to your layout XML files using the class name
com.telenor.connect.ConnectLoginButton
:
<com.telenor.connect.ConnectLoginButton
android:id="@+id/login_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Then add the required scope tokens for your
application to the button in the onCreate()
method of your Activity
class.
@Override
public void onCreate(Bundle savedInstanceState) {
...
ConnectLoginButton button = (ConnectLoginButton) findViewById(R.id.login_button);
button.setLoginScopeTokens("profile");
}
The onActivityResult()
method of your Activity
will be called with Activity.RESULT_OK
as
resultCode
if the login was successful or Activity.RESULT_CANCELED
when there was an error.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
// App code
} else if (resultCode == Activity.RESULT_CANCELED) {
// App code
}
}
If you are developing a confidential client you should skip to Next steps for confidential clients
To add additional [claims to your Connect request] (http://docs.telenordigital.com/apis/connect/id/authentication.html#authorization-server-user-authorization),
you can use the setClaims
method on the ConnectLoginButton
.
@Override
public void onCreate(Bundle savedInstanceState) {
...
ConnectLoginButton button = (ConnectLoginButton) findViewById(R.id.login_button);
button.setLoginScopeTokens("profile");
button.setClaims(new Claims(Claims.PHONE_NUMBER, Claims.EMAIL));
}
To set the locale the user sees in the flows, the following is an example of how this can be done:
@Override
public void onCreate(Bundle savedInstanceState) {
// ...
ConnectLoginButton button = (ConnectLoginButton) findViewById(R.id.login_button);
button.setLoginScopeTokens("profile");
Map<String, String> additionalLoginParams = new HashMap<>();
additionalLoginParams.put("ui_locales", "bn en");
button.addLoginParameters(additionalLoginParams)
}
One can customise the native loading screen that is shown before the Web View has finished loading in the following way:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
ConnectLoginButton loginButton = (ConnectLoginButton) findViewById(R.id.login_button);
loginButton.setCustomLoadingLayout(R.layout.custom_loading_screen);
}
Where R.layout.custom_loading_screen
can be any custom layout (.xml) file you have created.
The Connect SDK contains the ConnectTokensStateTracker
class that tracks the login
state of the user. This is useful for handling UI changes in your app based on the login state of
the user.
@Override
protected void onCreate(Bundle savedInstanceState) {
...
new ConnectTokensStateTracker() {
@Override
protected void onTokenStateChanged(boolean hasTokens) {
// App code
}
};
The onTokenStateChanged(boolean hasTokens)
method will be called whenever the token state changes.
The current Connect ID access token can be retrieved using the ConnectSdk.getAccessToken()
method. When the token has expired a new set of tokens can be requested using
ConnectSdk.updateTokens()
.
Access tokens can be used to access resources on your resource server. Please refer to the document about scope tokens for more details.
If you request user claims like email, phone, and name, using either scope tokens or the claims
parameter, you can access these fields on the user from ConnectSdk.getIdToken()
after an authorize
request, without having to do any further requests. Setting the scope will give you access to these
fields and setting the claims will make sure that the user has something in these fields, if the
authorize successfully completes. If both email and phone claims have been requested, we will also
provide the username used for the authentication in the ID token.
See docs.telenordigital.com/apis/connect/id/authentication.html for more details.
The user's access and refresh tokens are stored in a database controlled by you. The SDK will
return an access code
in the onActivityResult()
function. This access code should be exchanged
for access and refresh tokens in your backend system.
Connect Payment allows users to pay for content in your app. Connect Payment uses transactions and subscriptions (recurring transactions) to manage payments. Transactions and subscriptions are created from your app's backend system. Please see the Connect Payment documentation for more details.
Whenever a payment transaction is completed successfully or a payment is
cancelled, your backend should redirect to your application. There is a separate redirect for
a successful or cancelled transaction. The success and cancel redirect URIs should be added to your
application's strings.xml
file. Add strings with the names connect_payment_cancel_uri
and
connect_payment_success_uri
.
<string name="connect_payment_cancel_uri">example-clientid://transactionCancel</string>
<string name="connect_payment_success_uri">example-clientid://transactionSuccess</string>
Open your application's AndroidManifest.xml
file and add two meta-data
entries to the
application
section of the manifest.
<application>
...
<meta-data
android:name="com.telenor.connect.PAYMENT_CANCEL_URI"
android:value="@string/connect_payment_cancel_uri" />
<meta-data
android:name="com.telenor.connect.PAYMENT_SUCCESS_URI"
android:value="@string/connect_payment_success_uri" />
...
</application>
If you are not using Connect ID to sign users into your application you should also add the permission required to allow your application to access the internet.
<uses-permission android:name="android.permission.INTERNET"/>
And add the ConnectActivity
, which handles logging in, to the application
section.
<application>
...
<activity
android:name="com.telenor.connect.ui.ConnectActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light.NoActionBar" />
...
</application>
The SDK contains a custom Button
implementation which contains translations for the Connect
Payment text. This button can be used by adding a ConnectPaymentButton
to your layout.
Add the button to your layout XML files using the class name
com.telenor.connect.ConnectPaymentButton
:
<com.telenor.connect.ConnectPaymentButton
android:id="@+id/payment_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
To perform a transaction you would add a click handler to the payment button in the onCreate()
method of your Activity
class.
@Override
protected void onCreate(Bundle savedInstanceState) {
...
View paymentButton = findViewById(R.id.payment_button);
paymentButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// App code
}
});
}
This click handler would call your backend to let the backend create a transaction and you would
return the Payment link
to your application. The Payment link is then used in a call to
ConnectSdk.initializePayment(Context, String)
, which opens a ConnectActivity
where the user can
perform the transaction.