-
Notifications
You must be signed in to change notification settings - Fork 19
Using the Office 365 SDK for Android wih API levels lower than 18
As you may know, the Office 365 SDK relies on the .Azure Active Directory library (ADAL) to handle OAuth tokens. The readme in the ADAL repo states that they support API level 14 (Ice Cream Sandwich) and higher. This can lead you to assume that, ignoring other constraints, your app can support the same API level. This should be true! However, if you try to run a simple Office 365 Android app in a device running API level 14, 15, 16, or 17 you get an error similar to the following in logcat:
04-13 18:52:39.634 1996-2134/com.microsoft.office365.connect E/DefaultTokenCacheStore﹕ ENCRYPTION_FAILED:2015-04-13 18:52:39-7ce5fe19-314b-4223-83b3-e9326b10175d-Encryption failure ver:1.1.1
java.lang.IllegalArgumentException: rawBytes
at com.microsoft.aad.adal.StorageHelper.getSecretKey(StorageHelper.java:229)
at com.microsoft.aad.adal.StorageHelper.loadSecretKeyForAPI(StorageHelper.java:174)
at com.microsoft.aad.adal.StorageHelper.encrypt(StorageHelper.java:275)
at com.microsoft.aad.adal.DefaultTokenCacheStore.encrypt(DefaultTokenCacheStore.java:104)
at com.microsoft.aad.adal.DefaultTokenCacheStore.setItem(DefaultTokenCacheStore.java:179)
at com.microsoft.aad.adal.AuthenticationContext.setItemToCacheForUser(AuthenticationContext.java:1472)
at com.microsoft.aad.adal.AuthenticationContext.setItemToCache(AuthenticationContext.java:1452)
at com.microsoft.aad.adal.AuthenticationContext.access$300(AuthenticationContext.java:58)
at com.microsoft.aad.adal.AuthenticationContext$3.run(AuthenticationContext.java:818)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
This error doesn't show up if you're using API level 18 (Jelly Bean) or higher. Why? There's a simple reason, we need to set an encryption key in our app. APIs level 18 and higher do this for us automatically. In lower API levels, we must setup our key manually. Here's how, in your application or main activity use the following code before connecting your app:
// Devices with API level lower than 18 must setup an encryption key.
if (Build.VERSION.SDK_INT < 18 && AuthenticationSettings.INSTANCE.getSecretKeyData() == null) {
AuthenticationSettings.INSTANCE.setSecretKey(generateSecretKey());
}
/**
* Randomly generates an encryption key for devices with API level lower than 18.
* @return The encryption key in a 32 byte long array.
*/
protected byte[] generateSecretKey() {
byte[] key = new byte[32];
new SecureRandom().nextBytes(key);
return key;
}
See the snippet on gist.
Want to see an example of how to use this? See the ConnectActivity in the O365-Android-Connect sample.
Hope this helps you to support more devices in your Office 365 apps for Android!