Java tutorial
package com.vidinoti.pixlive; import android.Manifest; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.Color; import android.media.RingtoneManager; import android.os.Build; import android.os.Bundle; import android.os.Looper; import android.util.DisplayMetrics; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import com.vidinoti.android.vdarsdk.bookmark.BookmarkManager; import com.vidinoti.android.vdarsdk.camera.DeviceCameraImageSender; import com.vidinoti.android.vdarsdk.IBeaconSensor; import android.support.v4.app.NotificationCompat; import com.vidinoti.android.vdarsdk.NotificationFactory; import com.vidinoti.android.vdarsdk.Sensor; import com.vidinoti.android.vdarsdk.VDARAnnotationView; import com.vidinoti.android.vdarsdk.VDARCode; import com.vidinoti.android.vdarsdk.VDARCodeType; import com.vidinoti.android.vdarsdk.VDARContext; import com.vidinoti.android.vdarsdk.VDARIntersectionPrior; import com.vidinoti.android.vdarsdk.VDARPrior; import com.vidinoti.android.vdarsdk.VDARRemoteController; import com.vidinoti.android.vdarsdk.VDARSDKController; import com.vidinoti.android.vdarsdk.VDARRemoteControllerListener; import com.vidinoti.android.vdarsdk.VDARSDKControllerEventReceiver; import com.vidinoti.android.vdarsdk.VDARContentEventReceiver; import com.vidinoti.android.vdarsdk.VDARSDKSensorEventReceiver; import com.vidinoti.android.vdarsdk.VDARTagPrior; import com.vidinoti.android.vdarsdk.VidiBeaconSensor; import com.vidinoti.android.vdarsdk.geopoint.VDARGPSPoint; import com.vidinoti.android.vdarsdk.geopoint.GeoPointManager; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Observable; import java.util.Observer; /** * This class echoes a string called from JavaScript. */ public class PixLive extends CordovaPlugin implements VDARSDKControllerEventReceiver, VDARContentEventReceiver, VDARSDKSensorEventReceiver, VDARRemoteControllerListener { private static final String TAG = "PixLiveCordova"; private boolean locEnabled = false; class TouchInterceptorView extends FrameLayout { public boolean touchEnabled = true; private View.OnTouchListener privateListener = null; public TouchInterceptorView(android.content.Context context) { super(context); } public void setTouchEnabled(boolean val) { touchEnabled = val; } private int getRelativeLeft(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getLeft(); else return myView.getLeft() + getRelativeLeft((View) myView.getParent()); } private int getRelativeTop(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getTop(); else return myView.getTop() + getRelativeTop((View) myView.getParent()); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { //Log.v(TAG,"touch: action:" + ev.getAction() + " touchEnabled: " + touchEnabled +" intercepting " + intercepting); if ((!touchEnabled || arViews.size() == 0)) { return super.onInterceptTouchEvent(ev); } int thisViewLeft = getRelativeLeft(this); int thisViewTop = getRelativeTop(this); //Check if we fall into one AR view for (Map.Entry<Integer, VDARAnnotationView> s : arViews.entrySet()) { VDARAnnotationView view = s.getValue(); if (view.getVisibility() != View.VISIBLE || view.getParent() == null) { continue; } //WARNING: We assume here that the AR view share the same parent as this view. float arViewX = view.getLeft(); float arViewY = view.getTop(); for (int i = 0; i < ev.getPointerCount(); i++) { float xPos = ev.getX(i) - thisViewLeft; float yPos = ev.getY(i) - thisViewTop; if (xPos >= arViewX && xPos < arViewX + view.getWidth() && yPos >= arViewY && yPos < arViewY + view.getHeight()) { return true; } } } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { //Forward it to ar views for (Map.Entry<Integer, VDARAnnotationView> s : arViews.entrySet()) { VDARAnnotationView view = s.getValue(); float arViewX = view.getLeft(); float arViewY = view.getTop(); ev.offsetLocation(-arViewX, -arViewY); if (view.dispatchTouchEvent(ev)) { return true; } ev.offsetLocation(arViewX, arViewY); } return false; } } private HashMap<Integer, VDARAnnotationView> arViews = new HashMap<Integer, VDARAnnotationView>(); private DeviceCameraImageSender imageSender = null; private TouchInterceptorView touchView = null; private CallbackContext eventHandler = null; private ArrayList<Runnable> foregroundCallbacks = new ArrayList<Runnable>(); private boolean activityActive = false; private boolean pageLoaded = false; protected void pluginInitialize() { startSDK(cordova.getActivity()); VDARSDKController.getInstance().setEnableCodesRecognition(true); VDARSDKController.getInstance().registerContentEventReceiver(this); VDARSDKController.getInstance().setActivity(cordova.getActivity()); VDARSDKController.getInstance().registerEventReceiver(this); VDARSDKController.getInstance().registerSensorEventReceiver(this); VDARSDKController.getInstance().addNewAfterLoadingTask(new Runnable() { @Override public void run() { VDARRemoteController.getInstance().addProgressListener(PixLive.this); Intent intent = cordova.getActivity().getIntent(); if (intent != null && intent.getExtras() != null && intent.getExtras().getString("nid") != null) { VDARSDKController.getInstance().processNotification(intent.getExtras().getString("nid"), intent.getExtras().getBoolean("remote")); } } }); cordova.getActivity().runOnUiThread(new Runnable() { public void run() { if (touchView == null) { View v = webView.getView(); FrameLayout parent = ((FrameLayout) v.getParent()); parent.removeView(v); touchView = new TouchInterceptorView(cordova.getActivity()); touchView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); cordova.getActivity().setContentView(touchView); touchView.addView(v); v.setBackgroundColor(Color.TRANSPARENT); if (Build.VERSION.SDK_INT <= 16) { v.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } } } }); } @Override public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException { VDARSDKController.getInstance().onRequestPermissionsResult(requestCode, permissions, grantResults); } static void startSDK(final Context c) { if (VDARSDKController.getInstance() != null) { return; } String storage = c.getApplicationContext().getFilesDir().getAbsolutePath() + "/pixliveSDK"; String licenseKey = null; try { ApplicationInfo ai = c.getPackageManager().getApplicationInfo(c.getPackageName(), PackageManager.GET_META_DATA); Bundle bundle = ai.metaData; licenseKey = bundle.getString("com.vidinoti.pixlive.LicenseKey"); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Unable to start PixLive SDK without valid storage and license key."); return; } catch (NullPointerException e) { Log.e(TAG, "Unable to start PixLive SDK without valid storage and license key."); return; } if (storage == null || licenseKey == null) { Log.e(TAG, "Unable to start PixLive SDK without valid storage and license key."); return; } VDARSDKController.startSDK(c, storage, licenseKey); /* Comment out to disable QR code detection */ VDARSDKController.getInstance().setEnableCodesRecognition(true); VDARSDKController.getInstance().setNotificationFactory(new NotificationFactory() { @Override public Notification createNotification(String title, String message, String notificationID) { Intent appIntent = c.getPackageManager().getLaunchIntentForPackage(c.getPackageName()); appIntent.putExtra("nid", notificationID); appIntent.putExtra("remote", false); PendingIntent contentIntent = PendingIntent.getActivity(c, 0, appIntent, PendingIntent.FLAG_UPDATE_CURRENT); ApplicationInfo ai = c.getApplicationInfo(); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(c) .setSmallIcon(ai.icon != 0 ? ai.icon : android.R.drawable.star_big_off) .setContentTitle(title).setContentText(message).setContentIntent(contentIntent) .setAutoCancel(true).setVibrate(new long[] { 100, 200, 200, 400 }) .setLights(Color.BLUE, 500, 1500); mBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); return mBuilder.getNotification(); } }); } public void onReset() { cordova.getActivity().runOnUiThread(new Runnable() { public void run() { pageLoaded = false; for (VDARAnnotationView view : arViews.values()) { view.onPause(); if (view.getParent() != null) { touchView.removeView(view); } } arViews.clear(); } }); } @Override public void onNewIntent(Intent intent) { if (intent != null && intent.getExtras() != null && intent.getExtras().getString("nid") != null && VDARSDKController.getInstance() != null) { VDARSDKController.getInstance().processNotification(intent.getExtras().getString("nid"), intent.getExtras().getBoolean("remote")); } } @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if (action.equals("createARView") && args.length() >= 5) { int x = args.getInt(0); int y = args.getInt(1); int width = args.getInt(2); int height = args.getInt(3); int ctrlID = args.getInt(4); this.createARView(x, y, width, height, ctrlID, args.length() >= 6 ? args.getBoolean(5) : true, callbackContext); return true; } else if (action.equals("beforeLeave") && args.length() >= 1) { int ctrlID = args.getInt(0); this.beforeLeave(ctrlID, callbackContext); return true; } else if (action.equals("afterLeave") && args.length() >= 1) { int ctrlID = args.getInt(0); this.afterLeave(ctrlID, callbackContext); return true; } else if (action.equals("beforeEnter") && args.length() >= 1) { int ctrlID = args.getInt(0); this.beforeEnter(ctrlID, callbackContext); return true; } else if (action.equals("afterEnter") && args.length() >= 1) { int ctrlID = args.getInt(0); this.afterEnter(ctrlID, callbackContext); return true; } else if (action.equals("destroy") && args.length() >= 1) { int ctrlID = args.getInt(0); this.destroy(ctrlID, callbackContext); return true; } else if (action.equals("resize") && args.length() >= 5) { int x = args.getInt(1); int y = args.getInt(2); int width = args.getInt(3); int height = args.getInt(4); int ctrlID = args.getInt(0); this.resize(x, y, width, height, ctrlID, callbackContext); return true; } else if (action.equals("synchronize")) { JSONArray a = null; if (args.length() > 0) { a = args.getJSONArray(0); } this.synchronize(a, callbackContext); return true; } else if (action.equals("enableTouch")) { this.enableTouch(); return true; } else if (action.equals("disableTouch")) { this.disableTouch(); return true; } else if (action.equals("isContainingGPSPoints")) { this.isContainingGPSPoints(callbackContext); return true; } else if (action.equals("computeDistanceBetweenGPSPoints") && args.length() == 4) { this.computeDistanceBetweenGPSPoints((float) (args.getDouble(0)), (float) (args.getDouble(1)), (float) (args.getDouble(2)), (float) (args.getDouble(3)), callbackContext); return true; } else if (action.equals("getNearbyBeacons")) { this.getNearbyBeacons(callbackContext); return true; } else if (action.equals("getNearbyGPSPoints") && args.length() == 2) { this.getNearbyGPSPoints((float) (args.getDouble(0)), (float) (args.getDouble(1)), callbackContext); return true; } else if (action.equals("getGPSPointsInBoundingBox") && args.length() == 4) { this.getGPSPointsInBoundingBox((float) (args.getDouble(0)), (float) (args.getDouble(1)), (float) (args.getDouble(2)), (float) (args.getDouble(3)), callbackContext); return true; } else if (action.equals("setNotificationsSupport") && args.length() >= 1) { this.setNotificationsSupport(args.getString(0)); return true; } else if (action.equals("installEventHandler")) { this.installEventHandler(callbackContext); return true; } else if (action.equals("presentNotificationsList")) { this.presentNotificationsList(callbackContext); return true; } else if (action.equals("presentNearbyList")) { if (args.length() == 2) { this.presentNearbyList((float) args.getDouble(0), (float) args.getDouble(1)); return true; } else if (args.length() == 0) { this.presentNearbyList(); return true; } else { return false; } } else if (action.equals("refreshNearbyList") && args.length() >= 2) { this.refreshNearbyList((float) args.getDouble(0), (float) args.getDouble(1)); } else if (action.equals("openURLInInternalBrowser") && args.length() >= 1) { this.openURLInInternalBrowser(args.getString(0), callbackContext); return true; } else if (action.equals("getContexts")) { this.getContexts(callbackContext); return true; } else if (action.equals("getContext") && args.length() >= 1) { this.getContext(args.getString(0), callbackContext); return true; } else if (action.equals("activateContext") && args.length() >= 1) { this.activateContext(args.getString(0), callbackContext); return true; } else if (action.equals("ignoreContext") && args.length() >= 1) { this.ignoreContext(args.getString(0), callbackContext); return true; } else if (action.equals("setLocalizationEnabled")) { locEnabled = true; VDARSDKController.getInstance().getLocalizationManager().startLocalization(); return true; } else if (action.equals("pageLoaded")) { if (activityActive) { for (Runnable r : foregroundCallbacks) { r.run(); } foregroundCallbacks.clear(); } pageLoaded = true; return true; } else if (action.equals("setBookmarkSupport") && args.length() >= 1) { this.setBookmarkSupport(args.getBoolean(0)); return true; } else if (action.equals("getBookmarks")) { this.getBookmarks(callbackContext); return true; } else if (action.equals("addBookmark") && args.length() >= 1) { this.addBookmark(args.getString(0)); return true; } else if (action.equals("removeBookmark") && args.length() >= 1) { this.removeBookmark(args.getString(0)); return true; } else if (action.equals("isBookmarked") && args.length() >= 1) { this.isBookmarked(args.getString(0), callbackContext); return true; } return false; } private JSONObject createJSONForGPSPoint(VDARGPSPoint gpsPoint) { JSONObject obj = new JSONObject(); SimpleDateFormat format = new SimpleDateFormat("Z"); try { obj.put("contextId", gpsPoint.getContextID()); obj.put("label", gpsPoint.getLabel()); obj.put("category", gpsPoint.getCategory()); obj.put("lat", gpsPoint.getLat()); obj.put("lon", gpsPoint.getLon()); obj.put("detectionRadius", gpsPoint.getDetectionRadius()); obj.put("distanceFromCurrentPos", gpsPoint.getDistanceFromCurrentPos()); } catch (JSONException e) { } return obj; } private void isContainingGPSPoints(final CallbackContext callback) { boolean containGPSPoints = GeoPointManager.isContainingGPSPoints(); callback.sendPluginResult(new PluginResult(PluginResult.Status.OK, containGPSPoints)); } private void computeDistanceBetweenGPSPoints(float lat1, float lon1, float lat2, float lon2, final CallbackContext callback) { float distance = GeoPointManager.computeDistanceBetweenGPSPoints(lat1, lon1, lat2, lon2); callback.sendPluginResult(new PluginResult(PluginResult.Status.OK, distance)); } private void getNearbyBeacons(final CallbackContext callbackContext) { final List<String> contextIds = VDARSDKController.getInstance().getNearbyBeacons(); JSONArray ret = new JSONArray(); for (String ctxId : contextIds) { VDARContext c = VDARSDKController.getInstance().getContext(ctxId); if (c != null) { ret.put(createJSONForContext(c)); } } if (!isWebViewDestroyed()) { callbackContext.success(ret); } } private void getNearbyGPSPoints(float myLat, float myLon, final CallbackContext callback) { final List<VDARGPSPoint> gpsPoints = GeoPointManager.getNearbyGPSPoints(myLat, myLon); JSONArray ret = new JSONArray(); for (VDARGPSPoint gpsPoint : gpsPoints) { ret.put(createJSONForGPSPoint(gpsPoint)); } if (!isWebViewDestroyed()) { callback.success(ret); } } private void getGPSPointsInBoundingBox(float minLat, float minLon, float maxLat, float maxLon, final CallbackContext callback) { final List<VDARGPSPoint> gpsPoints = GeoPointManager.getGPSPointsInBoundingBox(minLat, minLon, maxLat, maxLon); JSONArray ret = new JSONArray(); for (VDARGPSPoint gpsPoint : gpsPoints) { ret.put(createJSONForGPSPoint(gpsPoint)); } if (!isWebViewDestroyed()) { callback.success(ret); } } private void setBookmarkSupport(boolean enabled) { VDARSDKController.getInstance().setBookmarkSupport(enabled); } private void getBookmarks(final CallbackContext callback) { final List<String> contextIds = BookmarkManager.getBookmarks(); JSONArray ret = new JSONArray(); for (String ctxId : contextIds) { VDARContext c = VDARSDKController.getInstance().getContext(ctxId); if (c != null) { ret.put(createJSONForContext(c)); } } if (!isWebViewDestroyed()) { callback.success(ret); } } private void addBookmark(String contextId) { BookmarkManager.addBookmark(contextId); } private void removeBookmark(String contextId) { BookmarkManager.removeBookmark(contextId); } private void isBookmarked(String contextId, final CallbackContext callbackContext) { boolean bookmarked = BookmarkManager.isBookmarked(contextId); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, bookmarked)); } private void installEventHandler(CallbackContext callback) { this.eventHandler = callback; } private void setNotificationsSupport(String googleProjectKey) { VDARSDKController.getInstance().setNotificationsSupport(googleProjectKey != null, googleProjectKey); } private void enableTouch() { if (touchView != null) { touchView.setTouchEnabled(true); } } private void disableTouch() { if (touchView != null) { touchView.setTouchEnabled(false); } } private boolean isWebViewDestroyed() { if (webView == null) { return true; } if (Thread.currentThread().equals(Looper.getMainLooper().getThread())) { final String url = webView.getUrl(); if (url == null || url.equals("about:blank")) { return true; } else { return false; } } else { return false; } } /** * Called when the system is about to start resuming a previous activity. * * @param multitasking Flag indicating if multitasking is turned on for app */ public void onPause(boolean multitasking) { activityActive = false; for (Map.Entry<Integer, VDARAnnotationView> s : arViews.entrySet()) { VDARAnnotationView view = s.getValue(); if (view.getParent() != null && view.getVisibility() == View.VISIBLE) { view.onPause(); } } VDARSDKController.getInstance().getLocalizationManager().stopLocalization(); } public void onDestroy() { for (Map.Entry<Integer, VDARAnnotationView> s : arViews.entrySet()) { VDARAnnotationView view = s.getValue(); touchView.removeView(view); } arViews.clear(); VDARSDKController.getInstance().unregisterEventReceiver(this); VDARSDKController.getInstance().unregisterContentEventReceiver(this); VDARSDKController.getInstance().unregisterSensorEventReceiver(this); VDARRemoteController.getInstance().removeProgressListener(this); this.eventHandler = null; } /** * Called when the activity will start interacting with the user. * * @param multitasking Flag indicating if multitasking is turned on for app */ public void onResume(boolean multitasking) { activityActive = true; for (Map.Entry<Integer, VDARAnnotationView> s : arViews.entrySet()) { VDARAnnotationView view = s.getValue(); if (view.getParent() != null && view.getVisibility() == View.VISIBLE) { view.onResume(); } } if (locEnabled) VDARSDKController.getInstance().getLocalizationManager().startLocalization(); if (pageLoaded) { for (Runnable r : foregroundCallbacks) { r.run(); } foregroundCallbacks.clear(); } } private void presentNotificationsList(final CallbackContext callbackContext) { if (0 == VDARSDKController.getInstance().getPendingNotifications().size()) { if (!isWebViewDestroyed()) { callbackContext.error("empty"); } } else { if (!isWebViewDestroyed()) { callbackContext.success(); } VDARSDKController.getInstance().presentNotificationsList(); } } private void presentNearbyList() { VDARSDKController.getInstance().presentNearbyList(); } private void presentNearbyList(final float latitude, final float longitude) { VDARSDKController.getInstance().presentNearbyList(latitude, longitude); } private void refreshNearbyList(final float latitude, final float longitude) { VDARSDKController.getInstance().refreshNearbyList(latitude, longitude); } private void openURLInInternalBrowser(String url, final CallbackContext callbackContext) { try { URL urlObj = new URL(url); VDARSDKController.getInstance().openURLInInternalBrowser(urlObj); } catch (MalformedURLException e) { } } private ArrayList<VDARPrior> getPriorsFromJSON(JSONArray a) { ArrayList<VDARPrior> ret = new ArrayList<VDARPrior>(); if (a != null) { for (int i = 0; i < a.length(); i++) { Object s = null; try { s = a.get(i); } catch (JSONException e) { continue; } if (s instanceof String) { ret.add(new VDARTagPrior((String) s)); } else if (s instanceof JSONArray) { ArrayList<VDARPrior> ret2 = getPriorsFromJSON((JSONArray) s); ret.add(new VDARIntersectionPrior(ret2)); } } } return ret; } private void synchronize(JSONArray tags, final CallbackContext callbackContext) { final ArrayList<VDARPrior> priors = getPriorsFromJSON(tags); VDARSDKController.getInstance().addNewAfterLoadingTask(new Runnable() { @Override public void run() { VDARRemoteController.getInstance().syncRemoteContextsAsynchronouslyWithPriors(priors, new Observer() { @Override public void update(Observable observable, Object data) { VDARRemoteController.ObserverUpdateInfo info = (VDARRemoteController.ObserverUpdateInfo) data; if (info.isCompleted()) { if (info.getError() == null) { JSONArray ctx = new JSONArray(info.getFetchedContexts()); if (!isWebViewDestroyed()) { try { callbackContext.success(ctx); } catch (Exception e) { } } } else { if (!isWebViewDestroyed()) { try { callbackContext.error(info.getError()); } catch (Exception e) { } } } } } }); } }); } private void activateContext(String contextId, final CallbackContext callbackContext) { VDARContext c = VDARSDKController.getInstance().getContext(contextId); if (c != null) { c.activate(); } } private void ignoreContext(String contextId, final CallbackContext callbackContext) { VDARContext c = VDARSDKController.getInstance().getContext(contextId); if (c != null) { c.ignore(); } } private JSONObject createJSONForContext(VDARContext c) { JSONObject obj = new JSONObject(); SimpleDateFormat format = new SimpleDateFormat("Z"); try { obj.put("contextId", c.getRemoteID()); obj.put("name", c.getName()); obj.put("lastUpdate", format.format(c.getLastModifiedDate())); obj.put("description", c.getDescription()); obj.put("notificationTitle", c.getNotificationTitle()); obj.put("notificationMessage", c.getNotificationMessage()); obj.put("imageThumbnailURL", c.getImageThumbnailURL()); obj.put("imageHiResURL", c.getImageHiResURL()); } catch (JSONException e) { } return obj; } private void getContexts(final CallbackContext callbackContext) { final ArrayList<String> contextIds = VDARSDKController.getInstance().getAllContextIDs(); JSONArray ret = new JSONArray(); for (String ctxId : contextIds) { VDARContext c = VDARSDKController.getInstance().getContext(ctxId); if (c != null) { ret.put(createJSONForContext(c)); } } if (!isWebViewDestroyed()) { callbackContext.success(ret); } } private void getContext(final String ctxId, final CallbackContext callbackContext) { VDARContext c = VDARSDKController.getInstance().getContext(ctxId); if (c != null) { JSONObject o = createJSONForContext(c); if (!isWebViewDestroyed()) { callbackContext.success(o); } } else { if (!isWebViewDestroyed()) { callbackContext.error("Invalid contextId"); } } } private void beforeLeave(final int ctrlID, CallbackContext callbackContext) { cordova.getActivity().runOnUiThread(new Runnable() { public void run() { VDARAnnotationView view = arViews.get(ctrlID); if (view != null) { view.onPause(); view.setVisibility(View.GONE); } } }); } private void afterLeave(final int ctrlID, CallbackContext callbackContext) { } private void beforeEnter(final int ctrlID, CallbackContext callbackContext) { cordova.getActivity().runOnUiThread(new Runnable() { public void run() { VDARAnnotationView view = arViews.get(ctrlID); if (view != null) { view.onResume(); view.setVisibility(View.VISIBLE); } } }); } private void afterEnter(final int ctrlID, CallbackContext callbackContext) { } private void resize(final int x, final int y, final int width, final int height, final int ctrlID, CallbackContext callbackContext) { cordova.getActivity().runOnUiThread(new Runnable() { public void run() { VDARAnnotationView annotationView = arViews.get(ctrlID); if (annotationView != null) { DisplayMetrics displaymetrics = new DisplayMetrics(); cordova.getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); annotationView.setVisibility(View.VISIBLE); FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) annotationView.getLayoutParams(); params.leftMargin = (int) Math.round(x * displaymetrics.scaledDensity); params.topMargin = (int) Math.round(y * displaymetrics.scaledDensity); params.width = (int) Math.round(width * displaymetrics.scaledDensity); params.height = (int) Math.round(height * displaymetrics.scaledDensity); annotationView.setLayoutParams(params); annotationView.requestLayout(); } } }); } private void destroy(final int ctrlID, CallbackContext callbackContext) { cordova.getActivity().runOnUiThread(new Runnable() { public void run() { VDARAnnotationView view = arViews.get(ctrlID); if (view != null) { view.onPause(); if (view.getParent() != null) { touchView.removeView(view); } arViews.remove(ctrlID); } } }); } private void createARView(final int x, final int y, final int width, final int height, final int ctrlID, final boolean insertBelow, final CallbackContext callbackContext) { cordova.getActivity().runOnUiThread(new Runnable() { public void run() { if (imageSender == null) { try { imageSender = new DeviceCameraImageSender(); } catch (IOException e) { VDARSDKController.log(Log.ERROR, TAG, Log.getStackTraceString(e)); } VDARSDKController.getInstance().setImageSender(imageSender); if (Build.VERSION.SDK_INT >= 23) { //FIXME: This is a hack, we enfore the cordova impl to have our own plugin as requestPermission callback try { Field fs = cordova.getClass().getDeclaredField("permissionResultCallback"); fs.setAccessible(true); fs.set(cordova, PixLive.this); } catch (Exception e) { } } } VDARAnnotationView annotationView = new VDARAnnotationView(cordova.getActivity()); DisplayMetrics displaymetrics = new DisplayMetrics(); cordova.getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); annotationView.setVisibility(View.VISIBLE); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( (int) Math.round(width * displaymetrics.scaledDensity), (int) Math.round(height * displaymetrics.scaledDensity)); params.leftMargin = (int) Math.round(x * displaymetrics.scaledDensity); params.topMargin = (int) Math.round(y * displaymetrics.scaledDensity); annotationView.setLayoutParams(params); touchView.addView(annotationView, 0); arViews.put(ctrlID, annotationView); VDARSDKController.getInstance().setActivity(cordova.getActivity()); annotationView.onResume(); } }); } private String getCodeTypeAsString(VDARCodeType c) { switch (c) { default: case VDAR_CODE_TYPE_NONE: return "none"; case VDAR_CODE_TYPE_EAN2: return "ean2"; case VDAR_CODE_TYPE_EAN5: return "ean5"; case VDAR_CODE_TYPE_EAN8: return "ean8"; case VDAR_CODE_TYPE_UPCE: return "upce"; case VDAR_CODE_TYPE_ISBN10: return "isbn10"; case VDAR_CODE_TYPE_UPCA: return "upca"; case VDAR_CODE_TYPE_EAN13: return "ean13"; case VDAR_CODE_TYPE_ISBN13: return "isbn13"; case VDAR_CODE_TYPE_COMPOSITE: return "composite"; case VDAR_CODE_TYPE_I25: return "i25"; case VDAR_CODE_TYPE_CODE39: return "code39"; case VDAR_CODE_TYPE_QRCODE: return "qrcode"; } } @Override public void onCodesRecognized(ArrayList<com.vidinoti.android.vdarsdk.VDARCode> arrayList) { if (this.eventHandler != null) { for (VDARCode code : arrayList) { if (!code.isSpecialCode()) { JSONObject o = new JSONObject(); try { o.put("type", "codeRecognize"); o.put("codeType", getCodeTypeAsString(code.getCodeType())); o.put("code", code.getCodeData()); } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } } } @Override public void onFatalError(String s) { } @Override public void onPresentAnnotations() { if (this.eventHandler != null) { JSONObject o = new JSONObject(); try { o.put("type", "presentAnnotations"); } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } @Override public void onAnnotationsHidden() { if (this.eventHandler != null) { JSONObject o = new JSONObject(); try { o.put("type", "hideAnnotations"); } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } @Override public void onTrackingStarted(int w, int h) { } @Override public void onEnterContext(com.vidinoti.android.vdarsdk.VDARContext vdarContext) { if (this.eventHandler != null) { JSONObject o = new JSONObject(); try { o.put("type", "enterContext"); o.put("context", vdarContext.getRemoteID()); } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } @Override public void onExitContext(com.vidinoti.android.vdarsdk.VDARContext vdarContext) { if (this.eventHandler != null) { JSONObject o = new JSONObject(); try { o.put("type", "exitContext"); o.put("context", vdarContext.getRemoteID()); } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } @Override public void onReceiveContentEvent(final String eventName, final String eventParams) { if (this.eventHandler != null) { JSONObject o = new JSONObject(); try { o.put("type", "eventFromContent"); o.put("eventName", eventName); o.put("eventParams", eventParams); } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } @Override public void onRequireSynchronization(final ArrayList<com.vidinoti.android.vdarsdk.VDARPrior> priors) { Runnable r = new Runnable() { @Override public void run() { if (PixLive.this.eventHandler != null) { JSONObject o = new JSONObject(); try { JSONArray arr = new JSONArray(); for (VDARPrior p : priors) { if (p instanceof VDARTagPrior) { arr.put(((VDARTagPrior) p).getTag()); } } o.put("type", "requireSync"); o.put("tags", arr); } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } }; if (activityActive && pageLoaded) { r.run(); } else { foregroundCallbacks.add(r); } } @Override public void onSensorTriggered(Sensor sensor, VDARContext context) { if (this.eventHandler != null) { JSONObject o = new JSONObject(); try { o.put("type", sensor.isTriggered() ? "sensorTriggered" : "sensorUntriggered"); o.put("sensorId", sensor.getSensorId()); o.put("sensorType", sensor.getType()); o.put("context", createJSONForContext(context)); if (sensor.isTriggered()) { if (sensor instanceof VidiBeaconSensor) { o.put("rssi", ((VidiBeaconSensor) sensor).getRssi()); } else if (sensor instanceof IBeaconSensor) { o.put("rssi", ((IBeaconSensor) sensor).getRssi()); o.put("distance", ((IBeaconSensor) sensor).getDistance()); } } } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } @Override public void onSensorUpdated(Sensor sensor, VDARContext context) { if (this.eventHandler != null) { JSONObject o = new JSONObject(); try { o.put("type", "sensorUpdate"); o.put("sensorId", sensor.getSensorId()); o.put("sensorType", sensor.getType()); o.put("context", createJSONForContext(context)); if (sensor instanceof VidiBeaconSensor) { o.put("rssi", ((VidiBeaconSensor) sensor).getRssi()); } else if (sensor instanceof IBeaconSensor) { o.put("rssi", ((IBeaconSensor) sensor).getRssi()); o.put("distance", ((IBeaconSensor) sensor).getDistance()); } } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } @Override public void onSyncProgress(VDARRemoteController controller, float progress, boolean isReady, String folder) { if (this.eventHandler != null) { JSONObject o = new JSONObject(); try { o.put("type", "syncProgress"); o.put("progress", progress / 100.0f); } catch (JSONException e) { } PluginResult p = new PluginResult(PluginResult.Status.OK, o); p.setKeepCallback(true); try { PixLive.this.eventHandler.sendPluginResult(p); } catch (Exception e) { //To avoid webview crashes } } } }