Augmented Reality is not a new technology, but its use has been seen by the public since the advent of the Pokemon GO, which shows that the AR technology has a great potential.

 

Wikitude

The Wikitude SDK of augmented reality combines technologies of 3D-tracking (based on the Simultaneous Localisation and Mapping (SLAM)), image recognition, tracking and geolocation of AR for mobile devices, tablets and smart glasses. Also extensions for Unity, Cordova, Titanium, and Xamarin are available.
 
After registering on the Wikitude website (https://www.wikitude.com/), you can open a web application Wikitude Studio (http://studio.wikitude.com/dashboard).
The Wikitude Studio panel allows you to create a project that will serve as the container for target images to be used as a pattern for image recognition, when they appear in a device’s camera.
 
After the addition of a target image in the project, you could select a type of augmented reality:
Text - displays a text over the target image.
Image - displays an image on the top of the target image.
Button - displays a button on the top of the target image, by clicking on which you can go to a URL.
HTML Widget - an HTML code that appears on the top of the target image.
 
3D Model - displays a 3D model on the top of the target image. The 3D model is pre-converted from the FBX (.fbx) format in the Wikitude 3D Format (.wt3) using the Wikitude 3D Encoder.
Video – displays a video on the top of the target image.
 
After selecting a type of augmented reality and defining properties of an object of augmented reality displayed on the top of the target image, let’s click the Preview.
You should install the application Wikitude App from the Google Play on your Android device.
 
Open the application menu and choose the Developer. Type a username and password from the Wikitude Studio. Select a project and focus the device camera on the target image – you can see the augmented reality.
Click the Export button in the Wikitude Studio of a web browser. You can export the application to access from the Wikitude App and from the Wikitude Hosting, also you can download the application to store on your own server, as well as download an application project to develop in the IDE based on the Wikitude SDK.
 
When using the Wikitude Hosting or your own hosting, an application URL address is typed in the Wikitude App, in the Developer section, in the Wikitude Studio, to download an application.
For application development in the Android Studio, you could download an application project based on the Android App Template and import it in the Android Studio.
 
After correcting errors in the project settings, you can run the application on your Android device.
Let’s download the Wikitude SDK (https://www.wikitude.com/download/) and obtain a license key, which insert into the protected static final String WIKITUDE_SDK_KEY = ""; of the file WikitudeSDKConstants to remove the watermark from the camera view. As a result, you will still see a watermark Trial.
 
In the libs folder of the project, there is an archive file of the Wikitude SDK. In the assets folder of the project, there is the same application that is downloaded when you select the Self-Hosting in the Wikitude Studio of a web browser.
 
When you run the application, firstly the activity RuntimePermissionRequestActivity is launched, which requests the permission android.permission.CAMERA, then it starts the activity SampleCamActivity that extends the class AbstractArchitectCamActivity.
In the SampleCamActivity class, the overridden method getARchitectWorldPath returns the path to the file index.html of the assets folder of the application. If you want to download the application from a server, in the string WORLD_PATH, you should type the URL of the index.html file.
 
In the SampleCamActivity class, the overridden method getWikitudeSDKLicenseKey returns a license key specified in the string WikitudeSDKConstants.WIKITUDE_SDK_KEY.
 
In the class AbstractArchitectCamActivity, an instance of the class StartupConfiguration of the Wikitude SDK is created, which constructor specifies a license key. It also creates a main view of the application represented by the class ArchitectView of the Wikitude SDK.
 
In the class StartupConfiguration, the license key is passed to the string field of the class.
package com.wikitude.architect;
 
import java.util.ArrayList;
 
public class StartupConfiguration {
private final String a;
private String b;
private final int c;
private final CameraPosition d;
public static final String ORIGIN_PHONEGAP = "CORDOVA";
public static final String ORIGIN_TITANIUM = "TITANIUM";
public static final String ORIGIN_XAMARIN = "XAMARIN";
public static final String ORIGIN_DEFAULT = "JAVASCRIPT_API";
 
protected String getOrigin() {
return this.a() ? this.b : "JAVASCRIPT_API";
}
 
private boolean a() {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("CORDOVA");
arrayList.add("TITANIUM");
arrayList.add("XAMARIN");
arrayList.add("JAVASCRIPT_API");
return this.b != null && arrayList.contains(this.b);
}
 
public void setOrigin(String string) {
this.b = string;
}
 
public StartupConfiguration(String string) {
this(string, 3);
}
 
public StartupConfiguration(String string, int n2) {
this(string, n2, CameraPosition.DEFAULT);
}
 
public StartupConfiguration(String string, int n2, CameraPosition cameraPosition) {
this.a = string;
this.c = n2;
this.d = cameraPosition;
}
 
public String getKey() {
return this.a;
}
 
public int getFeatures() {
return this.c;
}
 
public CameraPosition getCameraMode() {
return this.d;
}
 
public static enum CameraPosition {
DEFAULT,
FRONT,
BACK;
 
 
private CameraPosition() {
}
}
 
public static interface Features {
public static final int Geo = 1;
public static final int Tracking2D = 2;
}
 
}
 
In the class ArchitectView, in the method onCreate, the license key is passed from the class StartupConfiguration in the string field of the ArchitectView class and in the method onPostCreate, the native method setKey(this.getContext().getPackageName(), startupConfiguration.getKey()) is called. Next, a package name and the license key are compared in the native library of the folder jni of the Wikitude SDK.
 
package com.wikitude.architect;
 
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.util.AttributeSet;
import android.util.JsonWriter;
import android.util.Log;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.wikitude.architect.ArchitectWebView;
import com.wikitude.architect.BrowserActivity;
import com.wikitude.architect.CallbackHandler;
import com.wikitude.architect.Gameplay3dView;
import com.wikitude.architect.HtmlDrawableInterface;
import com.wikitude.architect.HtmlRenderManager;
import com.wikitude.architect.IArchitectCallbackListener;
import com.wikitude.architect.PlatformBridge;
import com.wikitude.architect.PlatformCamera;
import com.wikitude.architect.PluginManager;
import com.wikitude.architect.SensorService;
import com.wikitude.architect.ServiceManager;
import com.wikitude.architect.StartupConfiguration;
import com.wikitude.architect.plugin.Plugin;
import com.wikitude.tools.device.features.MissingDeviceFeatures;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;
import java.util.regex.Pattern;
 
public class ArchitectView
extends FrameLayout
implements e,
t {
static final String a = ArchitectView.class.getSimpleName();
private static final String i = "core";
private x j = null;
private PlatformCamera k = null;
private static final String l = "https://sdktracking.wikitude.com";
ArchitectWebView b;
private ViewState m;
Activity c;
static boolean d;
private ServiceManager n;
Gameplay3dView e;
private String o = "JAVASCRIPT_API";
private boolean p = false;
private AssetManager q;
private static final String r = "libarchitect.so";
private long nativePtr;
private ArchitectInitializeException s = null;
private static final Properties t;
private PlatformBridge u;
private HtmlDrawableInterface v;
private HtmlRenderManager w;
CallbackHandler f;
private m x;
private o y;
private StartupConfiguration z;
private StartupConfiguration.CameraPosition A;
private NetworkStateReceiver B;
private PluginManager C;
private List<Plugin> D = new ArrayList<Plugin>();
private String E;
public String g = "";
 
public ArchitectView(Context context, AttributeSet attributeSet, int n2) {
super(context, attributeSet, n2);
this.a(context);
}
 
public ArchitectView(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0);
}
 
public ArchitectView(Context context) {
super(context);
this.a(context);
}
 
@Override
public void onCameraOpen(Camera camera) {
Camera.Parameters parameters = camera.getParameters();
this.j.a(camera);
this.j.setCameraParams(parameters);
this.k = new PlatformCamera(this.nativePtr);
this.j.setPlatformCamera(this.k);
this.e.a(parameters);
this.j.a((Object)parameters);
if (parameters == null) {
this.m = ViewState.initFailed;
throw new CamNotAccessibleException("Could not get camera parameters");
}
this.f.a(parameters.getHorizontalViewAngle(), parameters.getVerticalViewAngle());
}
 
@Override
public void onCameraReleased() {
}
 
@Override
public void onCameraOpenAbort() {
}
 
private boolean d() {
this.p = ArchitectView.e();
try {
if (t.getProperty("archive.type") != null && t.getProperty("archive.type").equals("jar")) {
PackageManager packageManager = this.getContext().getPackageManager();
String string = packageManager.getApplicationInfo((String)this.getContext().getPackageName(), (int)0).dataDir;
String string2 = "";
String string3 = System.getProperty("os.arch");
String string4 = string3.substring(0, 3).toUpperCase();
string2 = string4.equals("X86") || string4.equals("I68") ? "x86" : (string4.equals("AAR") ? "arm64-v8a" : (this.p ? "armeabi-v7a" : "armeabi"));
File file = new File(string, "libarchitect.so");
String string5 = "/libs/" + string2 + "/" + "libarchitect.so";
ArchitectView.a(file, string5);
try {
System.load(file.getAbsolutePath());
}
catch (UnsatisfiedLinkError var8_10) {
if (string2.equals("arm64-v8a")) {
string5 = "/libs/armeabi-v7a/libarchitect.so";
file.delete();
file = new File(string, "libarchitect.so");
ArchitectView.a(file, string5);
System.load(file.getAbsolutePath());
}
throw var8_10;
}
file.delete();
} else {
System.loadLibrary("architect");
}
d = true;
return true;
}
catch (IOException var1_2) {
var1_2.printStackTrace();
}
catch (PackageManager.NameNotFoundException var1_3) {
var1_3.printStackTrace();
}
return false;
}
 
private static void a(File file, String string) throws FileNotFoundException, IOException {
InputStream inputStream = ArchitectWebView.class.getResourceAsStream(string);
if (inputStream == null) {
return;
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
int n2 = 0;
byte[] arrby = new byte[8192];
while ((n2 = inputStream.read(arrby)) > -1) {
fileOutputStream.write(arrby, 0, n2);
}
fileOutputStream.close();
inputStream.close();
}
 
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
private static boolean e() {
boolean bl;
bl = false;
String string = System.getProperty("os.arch");
String string2 = string.substring(0, 3).toUpperCase();
if (string2.equals("X86") || string2.equals("I68") || string2.equals("AAR")) {
bl = true;
} else {
Scanner scanner = null;
try {
scanner = new Scanner(new FileInputStream("/proc/cpuinfo"));
while (scanner.hasNextLine()) {
if (!bl && scanner.findInLine("neon") != null) {
bl = true;
}
scanner.nextLine();
}
}
catch (Exception var4_4) {}
finally {
if (scanner != null) {
scanner.close();
}
}
}
return bl;
}
 
private void a(Context context) {
if (!this.d()) {
this.m = ViewState.initFailed;
this.s = new LibraryLoadFailedException("Architect native Library could not be loaded");
return;
}
this.c = (Activity)this.getContext();
this.e = new Gameplay3dView(context);
this.e.setZOrderMediaOverlay(true);
this.j = Build.VERSION.SDK_INT >= 21 ? new c(this, context) : (this.p && ArchitectView.g() ? new c(this, context) : new d(this, context));
this.n = new ServiceManager(this.c, this.j, this);
this.n.a(new OrientationEventListener(context){
 
public void onOrientationChanged(int n2) {
ArchitectView.this.e.b();
}
});
this.b = new ArchitectWebView(context, this);
this.f = new CallbackHandler(this.c, this);
this.u = new PlatformBridge((Context)this.c, this.b);
this.v = new HtmlDrawableInterface((Context)this.c, this.b);
this.b.addJavascriptInterface((Object)this.u, this.u.a());
this.b.addJavascriptInterface((Object)this.v, this.v.a());
this.b.enableJavascript();
this.y = new o((Activity)context, new r(), this.f);
this.e.setRenderListener(this.y);
this.x = new m((Activity)context, this.f);
FrameLayout frameLayout = new FrameLayout(context);
frameLayout.setLayoutParams((ViewGroup.LayoutParams)new FrameLayout.LayoutParams(-1, -1));
this.w = new HtmlRenderManager((Context)this.c, frameLayout, this.v);
this.f.a(this.n);
this.f.a(this.w);
this.f.a(this.y);
this.f.a(this.x);
this.setBackgroundColor(-16777216);
this.removeAllViews();
this.a((View)frameLayout);
this.a(this.j.getView());
this.j.addViewToLayout((View)this.e);
this.a((View)this.b);
this.createNative();
}
 
private static Properties f() {
Properties properties = new Properties();
try {
properties.load(ArchitectView.class.getClassLoader().getResourceAsStream("assets/sdk.properties"));
}
catch (Exception var1_1) {
Log.w((String)a, (String)"Cannot open properties file, use defaults");
}
return properties;
}
 
private static boolean g() {
boolean bl;
try {
File[] arrfile = new File("/sys/devices/system/cpu/").listFiles(new FileFilter(){
 
@Override
public boolean accept(File file) {
if (Pattern.matches("cpu[0-9]+", file.getName())) {
return true;
}
return false;
}
});
bl = arrfile.length > 1;
}
catch (Exception var1_1) {
bl = false;
}
return bl;
}
 
private void a(View view) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
if (layoutParams == null && (layoutParams = this.generateDefaultLayoutParams()) == null) {
throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
}
super.addView(view, -1, layoutParams);
}
 
public void setLocation(double d2, double d3, double d4, float f2) {
if (this.n != null && this.n.a() != null && this.n.a().h()) {
this.n.a().setLocation(d2, d3, d4, "FAKE", f2, System.currentTimeMillis());
}
}
 
public void setLocation(double d2, double d3, float f2) {
if (this.n != null && this.n.a() != null && this.n.a().h()) {
this.n.a().setLocationAltitudeUnknown(d2, d3, "FAKE", f2, System.currentTimeMillis());
}
}
 
public void registerUrlListener(ArchitectUrlListener architectUrlListener) {
if (this.b != null) {
this.b.registerUrlHandler(architectUrlListener);
}
}
 
public void registerWorldLoadedListener(ArchitectWorldLoadedListener architectWorldLoadedListener) {
if (this.b != null) {
this.b.registerWorldLoadedHandler(architectWorldLoadedListener);
}
}
 
public void onCreate(String string) {
this.onCreate(new StartupConfiguration(string));
}
 
public void onCreate(StartupConfiguration startupConfiguration) {
this.z = startupConfiguration;
this.o = startupConfiguration.getOrigin();
if (this.m == ViewState.initFailed) {
Log.e((String)a, (String)"delayed exception from constructor", (Throwable)this.s);
throw this.s;
}
if (startupConfiguration != null && startupConfiguration.getKey() != null) {
this.E = startupConfiguration.getKey();
int n2 = startupConfiguration.getFeatures();
if ((ArchitectView.getSupportedFeaturesForDevice(this.getContext()) & n2) != n2) {
throw new MissingFeatureException("Required feature set is not supported");
}
this.m = ViewState.constructed;
} else {
Log.e((String)a, (String)"App key not set. Switch to failsave state");
this.removeAllViews();
}
this.A = this.z.getCameraMode();
}
 
public StartupConfiguration.CameraPosition getCurrentCamera() {
return this.A;
}
 
public void setCameraPositionSimple(StartupConfiguration.CameraPosition cameraPosition) {
this.A = cameraPosition;
}
 
private long getTrackingId() {
String string = Settings.Secure.getString((ContentResolver)this.getContext().getContentResolver(), (String)"android_id");
if (string == null || string.trim().equals("")) {
string = Build.BRAND + Build.MODEL;
}
return ("wiki" + string + "tude").hashCode();
}
 
private void h() {
SharedPreferences sharedPreferences = this.getContext().getSharedPreferences("WTTRACKED", 0);
sharedPreferences.edit().putLong("value", this.getTrackingId()).commit();
}
 
private boolean i() {
SharedPreferences sharedPreferences = this.getContext().getSharedPreferences("WTTRACKED", 0);
return sharedPreferences.getLong("value", 0) == this.getTrackingId();
}
 
public void onPostCreate() {
if (this.m != ViewState.constructed) {
throw new IllegalStateException("This method only has to be called right after the object has been constructed");
}
this.m = ViewState.onPostCreate;
this.q = this.getResources().getAssets();
File file = new File(a.d(this.getContext()), "core");
if (!file.exists()) {
file.mkdir();
}
String string = ArchitectView.getBuildProperty("build.hardware");
String string2 = ArchitectView.getBuildProperty("cloud.tracker.url");
if (string != null) {
this.g = string;
}
this.createARchitectCore(this.f, this.q, file.getAbsolutePath(), this.g, this.z.getFeatures());
String string3 = this.getContext().getPackageName();
this.setKey(string3, this.E);
n.a(this.getContext(), this, this.getShowIcon(), this.getShowSplash());
if (this.A == StartupConfiguration.CameraPosition.FRONT) {
this.setCameraMirroring(true);
}
if (string2 != null) {
this.setCloudTrackerURL(string2);
}
if (this.getDoTracking() && !this.i()) {
String string4 = this.getSdkVersion();
String string5 = this.trackingOriginIdentifierFromString(this.o);
String string6 = System.getenv("XAMARIN_BUILD_ID");
if (string6 != null) {
string5 = this.trackingOriginIdentifierFromString("XAMARIN");
}
String string7 = this.trackingPlatformIdentifierFromString("android");
this.sendUsageTrackingRequest(string4, string5, string7);
String string8 = this.getLicenseType();
this.a(string8);
this.h();
}
this.j();
this.k();
this.e.c();
}
 
private void a(String string) {
if (string.equalsIgnoreCase("invalid")) {
((TextView)new AlertDialog.Builder((Context)this.c).setTitle((CharSequence)"License key is missing or invalid").setMessage((CharSequence)Html.fromHtml((String)"<p>Please add a valid license key to your app. <br><br> <a href=\"http://www.wikitude.com/external/doc/documentation/latest/android/triallicense.html#free-trial-license\">More information</a></p>")).show().findViewById(16908299)).setMovementMethod(LinkMovementMethod.getInstance());
Log.e((String)a, (String)"License key is missing or invalid. Please add a valid license key to your app.");
}
}
 
private void j() {
ConnectivityManager connectivityManager = (ConnectivityManager)this.getContext().getSystemService("connectivity");
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isConnectedOrConnecting()) {
this.setNetworkStatus(NetworkStatus.NONE.name());
} else if (networkInfo.getType() == 1) {
this.setNetworkStatus(NetworkStatus.WIFI.name());
} else {
this.setNetworkStatus(NetworkStatus.MOBILE.name());
}
this.B = new NetworkStateReceiver(this);
this.getContext().registerReceiver((BroadcastReceiver)this.B, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
}
 
private void k() {
this.f.c(this.nativePtr);
this.e.a(this.nativePtr);
this.n.a(this.nativePtr);
this.u.connectNative(this.nativePtr);
this.v.connectNative(this.nativePtr);
}
 
public void onResume() {
if (this.m != ViewState.initFailed) {
this.m = ViewState.onResume;
this.j.onResume();
this.e.onResume();
this.n.c();
this.u.resume();
this.b.onResume();
this.x.resume();
this.y.resume();
} else {
Log.w((String)a, (String)"Can't resume activity, since intialization failed", (Throwable)this.s);
}
}
 
public void onPause() {
if (this.m != ViewState.onResume) {
throw new IllegalStateException("onResume() needs to be called before this method is called in the appropriate lifecycle method");
}
this.j.onPause();
this.m = ViewState.onPause;
this.u.pause();
this.b.onPause();
this.n.d();
this.x.pause();
this.y.pause();
this.e.onPause();
}
 
/*
* Unable to fully structure code
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
* Lifted jumps to return sites
*/
public void onDestroy() {
if (this.m != ViewState.initFailed) {
this.getContext().unregisterReceiver((BroadcastReceiver)this.B);
this.removeView((View)this.b);
if (this.C != null) {
this.C.destroyNative();
}
this.u.destroy();
this.v.onDestroy();
this.b.onDestroy();
this.n.e();
this.x.destroy();
this.y.destroy();
this.e.a();
if (this.k != null) {
this.k.a();
}
this.n = null;
var1_1 = new Thread(new Runnable(){
 
@Override
public void run() {
ArchitectView.this.destroyEngine();
ArchitectView.this.destroyNative();
}
});
try {
var1_1.start();
if (!var1_1.isAlive()) ** GOTO lbl25
var1_1.join();
}
catch (InterruptedException var2_2) {
throw new RuntimeException("Could not join pause/destroy thread, please check life-cycle calls");
}
} else {
Log.w((String)ArchitectView.a, (String)"Nothing was initialized, nothing will be destroyed", (Throwable)this.s);
}
lbl25: // 3 sources:
this.l();
}
 
private void l() {
try {
f.a(a.d((Context)this.c));
}
catch (Exception var1_1) {
Log.e((String)"Wikitude SDK onDestroy", (String)String.valueOf(var1_1.getMessage()));
}
}
 
public void callJavascript(String string) {
this.b.callJavaScript(string);
}
 
public void load(String string) throws IOException {
if (string.startsWith("http") || string.startsWith("file:")) {
this.b.loadArchitectFileFromUrl(string);
} else {
this.b.loadArchitectFileFromAssets(string);
}
}
 
public void a() {
}
 
void b() {
this.u.callSync("{\"is\":\"AR.i.contextInterface.destroyAll\"}");
}
 
public void onLowMemory() {
this.f.a();
}
 
public static String getCacheDirectoryAbsoluteFilePath(Context context) {
return ArchitectWebView.getCacheDirectoryRoot(context).getAbsolutePath();
}
 
public static int getSupportedFeaturesForDevice(Context context) {
boolean bl;
int n2 = 0;
if (Build.VERSION.SDK_INT >= 17) {
bl = context.getPackageManager().hasSystemFeature("android.hardware.camera.any");
} else {
boolean bl2 = bl = context.getPackageManager().hasSystemFeature("android.hardware.camera.front") || context.getPackageManager().hasSystemFeature("android.hardware.camera");
}
if (ArchitectView.b(context) >= 131072.0f && bl) {
if (ArchitectView.e()) {
n2 = 2;
}
LocationManager locationManager = (LocationManager)context.getSystemService("location");
SensorManager sensorManager = (SensorManager)context.getSystemService("sensor");
if (locationManager != null && locationManager.getAllProviders() != null && locationManager.getAllProviders().size() > 0 && sensorManager != null && sensorManager.getDefaultSensor(2) != null) {
n2 |= 1;
}
}
return n2;
}
 
public static boolean isDeviceSupported(Context context) {
return (ArchitectView.getSupportedFeaturesForDevice(context) & 3) == 3;
}
 
public static MissingDeviceFeatures isDeviceSupported(Context context, int n2) {
boolean bl;
String string = System.getProperty("line.separator");
String string2 = "";
if (Build.VERSION.SDK_INT >= 17) {
bl = context.getPackageManager().hasSystemFeature("android.hardware.camera.any");
} else {
boolean bl2 = bl = context.getPackageManager().hasSystemFeature("android.hardware.camera.front") || context.getPackageManager().hasSystemFeature("android.hardware.camera");
}
if (!bl) {
string2 = string2 + "- Camera" + string;
}
if (ArchitectView.b(context) < 131072.0f) {
string2 = string2 + "- OpenGLES version 2.0.+" + string;
}
if ((n2 & 1) == 1) {
LocationManager locationManager = (LocationManager)context.getSystemService("location");
SensorManager sensorManager = (SensorManager)context.getSystemService("sensor");
if (locationManager == null || locationManager.getAllProviders() == null || locationManager.getAllProviders().size() <= 0) {
string2 = string2 + "- GPS / Location Provider" + string;
}
if (sensorManager == null || sensorManager.getDefaultSensor(2) == null) {
string2 = string2 + "- Compass" + string;
}
}
if ((n2 & 2) == 2 && !ArchitectView.e()) {
string2 = string2 + "- Chipset supporting NEON" + string;
}
return new MissingDeviceFeatures(!string2.isEmpty(), "The device is missing following features:" + string + string2);
}
 
public String getSdkVersion() {
return d ? this.getArchitectVersion() : "N.A.";
}
 
public void setCullingDistance(float f2) {
if (this.e != null) {
this.e.setCullingDistance(f2);
}
}
 
public float getCullingDistance() {
return this.e != null ? this.e.getCullingDistance() : Float.MAX_VALUE;
}
 
public void clearAppCache() {
ArchitectWebView.clearCache((Context)this.c, 0);
}
 
private static float b(Context context) {
ActivityManager activityManager = (ActivityManager)context.getSystemService("activity");
ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
return configurationInfo.reqGlEsVersion;
}
 
private static boolean a(ApplicationInfo applicationInfo) {
return applicationInfo != null && 2 == (2 & applicationInfo.flags);
}
 
public void registerSensorAccuracyChangeListener(SensorAccuracyChangeListener sensorAccuracyChangeListener) {
this.n.a(sensorAccuracyChangeListener);
}
 
public void unregisterSensorAccuracyChangeListener(SensorAccuracyChangeListener sensorAccuracyChangeListener) {
this.n.b(sensorAccuracyChangeListener);
}
 
public void captureScreen(int n2, final FileOutputStream fileOutputStream) throws IllegalArgumentException {
int n3 = 100;
CaptureScreenCallback captureScreenCallback = new CaptureScreenCallback(){
 
@Override
public void onScreenCaptured(Bitmap bitmap) {
if (bitmap != null && ArchitectView.this.getContext() != null) {
bitmap.compress(Bitmap.CompressFormat.PNG, Math.max(0, Math.min(100, 100)), (OutputStream)fileOutputStream);
}
}
};
this.captureScreen(n2, captureScreenCallback);
}
 
public void captureScreen(int n2, final CaptureScreenCallback captureScreenCallback) throws IllegalArgumentException {
switch (n2) {
case 0: {
this.e.a(captureScreenCallback);
break;
}
case 1: {
CaptureScreenCallback captureScreenCallback2 = new CaptureScreenCallback(){
 
@Override
public void onScreenCaptured(final Bitmap bitmap) {
if (ArchitectView.this.b != null) {
ArchitectView.this.c.runOnUiThread(new Runnable(){
 
@Override
public void run() {
Bitmap bitmap3;
try {
bitmap3 = Bitmap.createBitmap((int)bitmap.getWidth(), (int)bitmap.getHeight(), (Bitmap.Config)bitmap.getConfig());
Canvas canvas = new Canvas(bitmap3);
canvas.drawBitmap(bitmap, new Matrix(), null);
Bitmap bitmap2 = Bitmap.createBitmap((int)ArchitectView.this.b.getWidth(), (int)ArchitectView.this.b.getHeight(), (Bitmap.Config)Bitmap.Config.ARGB_8888);
Canvas canvas2 = new Canvas(bitmap2);
ArchitectView.this.b.layout(0, 0, ArchitectView.this.b.getWidth(), ArchitectView.this.b.getHeight());
ArchitectView.this.b.draw(canvas2);
canvas.drawBitmap(bitmap2, new Matrix(), null);
}
catch (Exception var2_3) {
Log.w((String)ArchitectView.a, (String)"Can't capture screen - will return null", (Throwable)var2_3);
bitmap3 = null;
}
try {
captureScreenCallback.onScreenCaptured(bitmap3);
}
catch (Exception var2_4) {
Log.e((String)ArchitectView.a, (String)"Capture screen callback threw an exception", (Throwable)var2_4);
}
}
});
}
}
 
};
this.e.a(captureScreenCallback2);
break;
}
default: {
throw new IllegalArgumentException("captureMode must be listed in CaptureScreenCallback.CAPTURE_MODE_*");
}
}
}
 
public void setDisplayMode3dInCore(boolean bl) {
block4 : {
try {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter((Writer)stringWriter);
jsonWriter.beginObject();
if (bl) {
jsonWriter.name("3dmode").value("3d");
} else {
jsonWriter.name("3dmode").value("2d");
}
jsonWriter.endObject();
jsonWriter.close();
Log.i((String)"DEBUG", (String)("JSON:" + stringWriter.toString()));
this.setHardwareConfiguration(stringWriter.toString());
}
catch (IOException var2_3) {
if (h) break block4;
throw new AssertionError();
}
}
}
 
public void setFlashEnabled(boolean bl) {
this.j.setFlashEnabled(bl);
}
 
public static String getBuildProperty(String string) {
return t.getProperty(string);
}
 
void a(String string, boolean bl) {
if (string == null || string.length() < 4) {
Toast.makeText((Context)this.getContext(), (CharSequence)"invalid URL provided", (int)1).show();
return;
}
if (bl) {
Uri uri;
try {
new URL(string).getProtocol();
uri = Uri.parse((String)string);
}
catch (Exception var4_5) {
uri = Uri.parse((String)("http://" + string));
}
Intent intent = new Intent("android.intent.action.VIEW");
intent.setData(uri);
if (string.startsWith("file")) {
Intent intent2;
PackageManager packageManager = this.c.getPackageManager();
List list = packageManager.queryIntentActivities(intent2 = new Intent("android.intent.action.VIEW", Uri.parse((String)"http://")), 0);
if (!list.isEmpty()) {
packageManager.getLaunchIntentForPackage(((ResolveInfo)list.get((int)0)).activityInfo.packageName);
ComponentName componentName = new ComponentName(((ResolveInfo)list.get((int)0)).activityInfo.packageName, ((ResolveInfo)list.get((int)0)).activityInfo.name);
intent.addCategory("android.intent.category.BROWSABLE");
intent.setComponent(componentName);
this.getContext().startActivity(intent);
}
} else {
this.getContext().startActivity(intent);
}
} else {
Intent intent = new Intent(this.getContext(), BrowserActivity.class);
intent.putExtra("URL", string);
this.getContext().startActivity(intent);
}
}
 
boolean c() {
return this.b.isActivityFinishing();
}
 
String getLastLoadedUrl() {
return this.b.getLastLoadedUrl();
}
 
void setCameraZoomLevel(float f2) {
this.j.setZoomLevel(f2);
Camera.Parameters parameters = this.j.getCameraParameter();
if (parameters.isZoomSupported()) {
int n2 = (Integer)parameters.getZoomRatios().get(parameters.getZoom());
float f3 = (float)Math.toDegrees(2.0 * Math.atan(100.0 * Math.tan(Math.toRadians(parameters.getHorizontalViewAngle()) / 2.0) / (double)n2));
float f4 = (float)Math.toDegrees(2.0 * Math.atan(100.0 * Math.tan(Math.toRadians(parameters.getVerticalViewAngle()) / 2.0) / (double)n2));
this.f.a(f3, f4);
} else {
this.f.a(parameters.getHorizontalViewAngle(), parameters.getVerticalViewAngle());
}
this.e.a(parameters);
this.j.setCameraParams(parameters);
}
 
void setCameraFocusMode(CameraFocusMode cameraFocusMode) {
this.j.setFocusMode(cameraFocusMode);
}
 
void setCameraPosition(StartupConfiguration.CameraPosition cameraPosition) {
this.A = cameraPosition;
this.j.f();
Camera.Parameters parameters = this.j.getCameraParameter();
if (parameters == null) {
this.m = ViewState.initFailed;
throw new CamNotAccessibleException("Could not get camera parameters");
}
this.f.a(parameters.getHorizontalViewAngle(), parameters.getVerticalViewAngle());
this.e.a(parameters);
this.j.setCameraParams(parameters);
}
 
public CameraFocusMode getCameraFocusMode() {
return this.j.getFocusMode();
}
 
public float getCameraZoomLevel() {
return this.j.getZoomLevel();
}
 
public float getCameraMaxZoomLevel() {
return this.j.getMaxZoomLevel();
}
 
public String[] getAvailableCameraFocusModes() {
return this.j.getAvailableCameraFocusModes();
}
 
public String[] getAvailableCameraPositions() {
return this.j.getAvailableCameraPositions();
}
 
public boolean registerPlugin(Plugin plugin) {
this.m();
if (this.C.registerPluginInCore(plugin)) {
this.D.add(plugin);
return true;
}
return false;
}
 
public boolean registerNativePlugins(String string) {
return this.registerNativePlugins(string, "");
}
 
public boolean registerNativePlugins(String string, String string2) {
if (this.m.ordinal() >= 1 && this.m != ViewState.initFailed) {
this.m();
try {
System.loadLibrary(string);
}
catch (UnsatisfiedLinkError var3_3) {
Log.e((String)a, (String)("Couldn't load plugins of library '" + string + "' because the library couldn't be loaded. Following error was thrown: " + var3_3.toString()));
return false;
}
long[] arrl = this.C.createNativePlugins(string2);
if (!this.C.registerNativePluginsInCore(arrl)) {
Log.e((String)a, (String)("A native plugin of library '" + string + "' couldn't be registered. All other plugins of this library were unregistered."));
return false;
}
} else {
Log.e((String)a, (String)("Registration of plugins in library '" + string + "' was canceled. Wrong lifecycle state detected."));
return false;
}
return true;
}
 
private void m() {
if (this.C == null) {
this.C = new PluginManager();
this.C.connectNative(this.nativePtr);
}
}
 
List<Plugin> getRegisteredPlugins() {
return this.D;
}
 
@Override
public native void createNative();
 
@Override
public native void destroyNative();
 
private native void createARchitectCore(IArchitectCallbackListener var1, AssetManager var2, String var3, String var4, int var5);
 
native void destroyEngine();
 
native void loadingFinished();
 
native String getArchitectVersion();
 
native void loadingStarted();
 
native void setNetworkStatus(String var1);
 
native void setCameraMirroring(boolean var1);
 
private native void setKey(String var1, String var2);
 
private native String getLicenseType();
 
private native String getCustomerMail();
 
private native boolean getShowIcon();
 
private native boolean getShowSplash();
 
private native boolean getDoTracking();
 
private native void setHardwareConfiguration(String var1);
 
private native void setCloudTrackerURL(String var1);
 
private native boolean sendUsageTrackingRequest(String var1, String var2, String var3);
 
private native String trackingPlatformIdentifierFromString(String var1);
 
private native String trackingOriginIdentifierFromString(String var1);
 
@Override
public long getNativePointer() {
return this.nativePtr;
}
 
static {
t = ArchitectView.f();
}
 
public static interface CaptureScreenCallback {
public static final int CAPTURE_MODE_CAM = 0;
public static final int CAPTURE_MODE_CAM_AND_WEBVIEW = 1;
 
public void onScreenCaptured(Bitmap var1);
}
 
public static interface ArchitectWorldLoadedListener {
public void worldWasLoaded(String var1);
 
public void worldLoadFailed(int var1, String var2, String var3);
}
 
public static interface ArchitectUrlListener {
public boolean urlWasInvoked(String var1);
}
 
public static interface SensorAccuracyChangeListener {
public void onCompassAccuracyChanged(int var1);
}
 
static class NetworkStateReceiver
extends BroadcastReceiver {
private static final String a = "NetworkStateReceiver";
private final ArchitectView b;
 
public NetworkStateReceiver(ArchitectView architectView) {
this.b = architectView;
}
 
public void onReceive(Context context, Intent intent) {
Log.d((String)"NetworkStateReceiver", (String)"Network connectivity change");
if (intent.getExtras() != null) {
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService("connectivity");
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isConnectedOrConnecting()) {
this.b.setNetworkStatus(NetworkStatus.NONE.name());
} else if (networkInfo.getType() == 1) {
this.b.setNetworkStatus(NetworkStatus.WIFI.name());
} else {
this.b.setNetworkStatus(NetworkStatus.MOBILE.name());
}
}
}
}
 
static enum NetworkStatus {
NONE,
WIFI,
MOBILE;
 
 
private NetworkStatus() {
}
}
 
public static enum CameraFocusMode {
ONCE,
CONTINUOUS;
 
 
private CameraFocusMode() {
}
}
 
static enum ViewState {
constructed,
onPostCreate,
onResume,
onPause,
onDestroy,
initFailed;
 
 
private ViewState() {
}
}
 
public static class LibraryLoadFailedException
extends ArchitectInitializeException {
private static final long serialVersionUID = -3436549205240611293L;
 
public LibraryLoadFailedException(String string) {
super(string);
}
}
 
public static class MissingFeatureException
extends ArchitectInitializeException {
private static final long serialVersionUID = -1120070352130259205L;
 
public MissingFeatureException(Exception exception) {
super(exception);
}
 
public MissingFeatureException(String string) {
super(string);
}
}
 
public static class CamNotAccessibleException
extends ArchitectInitializeException {
private static final long serialVersionUID = -2060234091280507469L;
 
public CamNotAccessibleException(Exception exception) {
super(exception);
}
 
public CamNotAccessibleException(String string) {
super(string);
}
}
 
public static abstract class ArchitectInitializeException
extends RuntimeException {
private static final long serialVersionUID = 3315635385062334407L;
 
public ArchitectInitializeException(Exception exception) {
super(exception);
}
 
public ArchitectInitializeException(String string) {
super(string);
}
}
 
}
 

You can download the book Android Application Development with Augmented Reality here.

Our services

Our developments are at the forefront of high technologies

We design and develop web sites

Individual site design
Creating dynamic sites
Website layout and programming

We develop information systems

Automation of business processes for small and medium business
Collection, storage and processing of data
Using cloud technologies

We create mobile apps

Integration with a Web site
Creating mobile versions of web sites
Using Augmented Reality and Computer Vision

About us

NOV Tech Solutions specializes in developing services for operational management of business, creating web and mobile applications on order

NOV Tech Solutions is a team of highly qualified professionals working for the result

We work quickly and efficiently, using the most modern technologies

We appreciate and take care of our customers, constantly improving the service and expanding the list of services

Our partners

Contacts