Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .idea/.name

This file was deleted.

1 change: 0 additions & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 8 additions & 59 deletions DeviceIdentifiersWrapper/build.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
apply plugin: 'com.android.library'

ext {
PUBLISH_GROUP_ID = 'com.zebra.deviceidentifierswrapper'
PUBLISH_ARTIFACT_ID = 'deviceidentifierswrapper'
PUBLISH_VERSION = '0.2'
plugins {
id 'com.android.library'
}

android {
Expand All @@ -12,8 +8,8 @@ android {
defaultConfig {
minSdkVersion 19
targetSdkVersion 32
versionCode 2
versionName "0.2"
versionCode 8
versionName "0.8"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

Expand All @@ -25,6 +21,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

}

Expand All @@ -36,54 +36,3 @@ dependencies {
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
compileOnly 'com.symbol:emdk:+'
}

/*
Generate release files for publication and Zip them
https://medium.com/@daniellevass/how-to-publish-your-android-studio-library-to-jcenter-5384172c4739
https://raw.githubusercontent.com/blundell/release-android-library/master/android-release-aar.gradle
*/

// ./gradlew clean build generateRelease
apply plugin: 'maven'

def version = project.PUBLISH_VERSION

def localReleaseDest = "${buildDir}/release/${version}"

task androidJavadocs(type: Javadoc) {
failOnError = false
source = android.sourceSets.main.java.srcDirs
ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
classpath += files(ext.androidJar)
}

task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
archiveClassifier = 'javadoc'
from androidJavadocs.destinationDir
}

task androidSourcesJar(type: Jar) {
archiveClassifier = 'sources'
from android.sourceSets.main.java.srcDirs
}

task zipRelease(type: Zip) {
from localReleaseDest
destinationDir buildDir
archiveBaseName = "release-${version}"
}

task generateRelease {
doLast {
println "Release ${version} can be found at ${localReleaseDest}/"
println "Release ${version} zipped can be found ${buildDir}/release-${version}.zip"
}
}

generateRelease.dependsOn(zipRelease)


artifacts {
archives androidSourcesJar
archives androidJavadocsJar
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,32 @@ public class DIHelper {
// TODO: Put your custom certificate in the apkCertificate member for MX AccessMgr registering (only if necessary and if you know what you are doing)
public static Signature apkCertificate = null;

protected static String sIMEI = null;
protected static String sSerialNumber = null;

public static final long SEC_IN_MS = 1000;
public static final long MIN_IN_MS = SEC_IN_MS * 60;
public static long MAX_EMDK_TIMEOUT_IN_MS = 10 * MIN_IN_MS; // 10 minutes
public static long WAIT_PERIOD_BEFORE_RETRY_EMDK_RETRIEVAL_IN_MS = 2 * SEC_IN_MS; // 2 seconds

public static void resetCachedValues()
{
sIMEI = null;
sSerialNumber = null;
}

// This method will return the serial number in the string passed through the onSuccess method
public static void getSerialNumber(Context context, IDIResultCallbacks callbackInterface)
{
if(sSerialNumber != null)
{
if(callbackInterface != null)
{
callbackInterface.onDebugStatus("Serial number already in cache.");
}
callbackInterface.onSuccess(sSerialNumber);
return;
}
if (android.os.Build.VERSION.SDK_INT < 29) {
returnSerialUsingAndroidAPIs(context, callbackInterface);
} else {
Expand All @@ -37,25 +60,54 @@ public static void getSerialNumber(Context context, IDIResultCallbacks callbackI
@SuppressLint({"MissingPermission", "ObsoleteSdkInt", "HardwareIds"})
private static void returnSerialUsingAndroidAPIs(Context context, IDIResultCallbacks callbackInterface) {
if (android.os.Build.VERSION.SDK_INT < 26) {
sSerialNumber = Build.SERIAL;
callbackInterface.onSuccess(Build.SERIAL);
} else {
if (ContextCompat.checkSelfPermission(context, permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
sSerialNumber = Build.getSerial();
callbackInterface.onSuccess(Build.getSerial());
} else {
callbackInterface.onError("Please grant READ_PHONE_STATE permission");
}
}
}

private static void returnSerialUsingZebraAPIs(Context context, IDIResultCallbacks callbackInterface) {
private static void returnSerialUsingZebraAPIs(Context context, final IDIResultCallbacks callbackInterface) {
IDIResultCallbacks tempCallbackInterface = new IDIResultCallbacks() {
@Override
public void onSuccess(String message) {
sSerialNumber = message;
callbackInterface.onSuccess(message);
}

@Override
public void onError(String message) {
callbackInterface.onError(message);
}

@Override
public void onDebugStatus(String message) {
callbackInterface.onDebugStatus(message);
}
};

new RetrieveOEMInfoTask()
.execute(context, Uri.parse("content://oem_info/oem.zebra.secure/build_serial"),
callbackInterface);
tempCallbackInterface);
}

// This method will return the imei number in the string passed through the onSuccess method
public static void getIMEINumber(Context context, IDIResultCallbacks callbackInterface)
{
if(sIMEI != null)
{
if(callbackInterface != null)
{
callbackInterface.onDebugStatus("IMEI number already in cache.");
}
callbackInterface.onSuccess(sIMEI);
return;
}
if (android.os.Build.VERSION.SDK_INT < 29) {
returnImeiUsingAndroidAPIs(context, callbackInterface);
} else {
Expand All @@ -68,6 +120,7 @@ private static void returnImeiUsingAndroidAPIs(Context context, IDIResultCallbac
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (android.os.Build.VERSION.SDK_INT < 26) {String imei = telephonyManager.getDeviceId();
if (imei != null && !imei.isEmpty()) {
sIMEI = imei;
callbackInterface.onSuccess(imei);
} else {
callbackInterface.onError("Could not get IMEI number");
Expand All @@ -76,6 +129,7 @@ private static void returnImeiUsingAndroidAPIs(Context context, IDIResultCallbac
if (ContextCompat.checkSelfPermission(context, permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
String imei = telephonyManager.getImei();
if (imei != null && !imei.isEmpty()) {
sIMEI = imei;
callbackInterface.onSuccess(imei);
} else {
callbackInterface.onError("Could not get IMEI number");
Expand All @@ -86,8 +140,26 @@ private static void returnImeiUsingAndroidAPIs(Context context, IDIResultCallbac
}
}

private static void returnImeiUsingZebraAPIs(Context context, IDIResultCallbacks callbackInterface) {
private static void returnImeiUsingZebraAPIs(Context context, final IDIResultCallbacks callbackInterface) {
IDIResultCallbacks tempCallbackInterface = new IDIResultCallbacks() {
@Override
public void onSuccess(String message) {
sIMEI = message;
callbackInterface.onSuccess(message);
}

@Override
public void onError(String message) {
callbackInterface.onError(message);
}

@Override
public void onDebugStatus(String message) {
callbackInterface.onDebugStatus(message);
}
};

new RetrieveOEMInfoTask().execute(context, Uri.parse("content://oem_info/wan/imei"),
callbackInterface);
tempCallbackInterface);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;

class DIProfileManagerCommand extends DICommandBase {
public class ErrorHolder
Expand Down Expand Up @@ -55,6 +56,9 @@ public class ErrorHolder
// Provides full error description string
public String msErrorString = "";

// To prevent multiple initializations at the same time
private boolean bInitializing = false;

// Status Listener implementation (ensure that we retrieve the profile manager asynchronously
EMDKManager.StatusListener mStatusListener = new EMDKManager.StatusListener() {
@Override
Expand Down Expand Up @@ -114,6 +118,9 @@ public void execute(String mxProfile, String mxProfileName, IDIResultCallbacks r

private void initializeEMDK()
{
if(bInitializing)
return;
bInitializing = true;
if(mEMDKManager == null)
{
EMDKResults results = null;
Expand All @@ -126,6 +133,7 @@ private void initializeEMDK()
{
logMessage("Error while requesting EMDKManager.\n" + e.getLocalizedMessage(), EMessageType.ERROR);
e.printStackTrace();
waitForEMDK();
return;
}

Expand All @@ -134,6 +142,7 @@ private void initializeEMDK()
logMessage("EMDKManager request command issued with success", EMessageType.DEBUG);
}else {
logMessage("EMDKManager request command error", EMessageType.ERROR);
waitForEMDK();
}
}
else
Expand All @@ -142,6 +151,36 @@ private void initializeEMDK()
}
}

private void waitForEMDK()
{
logMessage("EMDKManager error, this could be a BOOT_COMPLETED issue.", EMessageType.DEBUG);
logMessage("Starting watcher thread to wait for EMDK initialization.", EMessageType.DEBUG);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
long startDate = new Date().getTime();
long delta = 0;
while(mEMDKManager == null || delta < DIHelper.MAX_EMDK_TIMEOUT_IN_MS ) {
// Try to initialize EMDK
logMessage("Calling EMDK Initialization method", EMessageType.DEBUG);
initializeEMDK();
try {
logMessage("Waiting " + DIHelper.WAIT_PERIOD_BEFORE_RETRY_EMDK_RETRIEVAL_IN_MS + " milliseconds before retrying.", EMessageType.DEBUG);
Thread.sleep(DIHelper.WAIT_PERIOD_BEFORE_RETRY_EMDK_RETRIEVAL_IN_MS);
} catch (InterruptedException e) {
e.printStackTrace();
}
delta = new Date().getTime() - startDate;
logMessage("Delta in ms since first EMDK retrieval try: " + delta + "ms stops at " + DIHelper.MAX_EMDK_TIMEOUT_IN_MS + "ms", EMessageType.DEBUG);
}
bInitializing = false;
logMessage("Could not retrieve EMDK Manager after waiting " + DIHelper.WAIT_PERIOD_BEFORE_RETRY_EMDK_RETRIEVAL_IN_MS/DIHelper.SEC_IN_MS + " seconds. Please contact your administrator or check logcat for any EMDK related error.", EMessageType.ERROR);
}
});
t.setPriority(Thread.MIN_PRIORITY);
t.start();
}

private void onEMDKManagerRetrieved(EMDKManager emdkManager)
{
mEMDKManager = emdkManager;
Expand Down Expand Up @@ -186,6 +225,7 @@ private void releaseManagers()
private void onProfileManagerInitialized(ProfileManager profileManager)
{
mProfileManager = profileManager;
bInitializing = false;
logMessage("Profile Manager retrieved.", EMessageType.DEBUG);
processMXContent();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.zebra.deviceidentifierswrapper;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
Expand Down Expand Up @@ -106,7 +107,10 @@ private static void registerCurrentApplication(Context context, Uri serviceIdent
// You can copy/paste this snippet if you want to provide your own
// certificate
// TODO: use the following code snippet to extract your custom certificate if necessary
final Signature[] arrSignatures = packageInfo.signingInfo.getApkContentsSigners();
Signature[] arrSignatures = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
arrSignatures = packageInfo.signingInfo.getApkContentsSigners();
}
if(arrSignatures == null || arrSignatures.length == 0)
{
if(callbackInterface != null)
Expand All @@ -124,7 +128,10 @@ private static void registerCurrentApplication(Context context, Uri serviceIdent
final byte[] rawCert = sig.toByteArray();

// Get the certificate as a base64 string
String encoded = Base64.getEncoder().encodeToString(rawCert);
String encoded = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
encoded = Base64.getEncoder().encodeToString(rawCert);
}

profileData =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
Expand Down Expand Up @@ -163,7 +170,7 @@ private static void getURIValue(Cursor cursor, Uri uri, IDIResultCallbacks resul
else{
for (int i = 0; i < cursor.getColumnCount(); i++) {
try {
String data = cursor.getString(cursor.getColumnIndex(cursor.getColumnName(i)));
@SuppressLint("Range") String data = cursor.getString(cursor.getColumnIndex(cursor.getColumnName(i)));
resultCallbacks.onSuccess(data);
cursor.close();
return;
Expand Down
Loading