Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Reaching out from ADF Mobile (ODTUG KScope 2014)

864 views

Published on

Reaching out from ADF Mobile (ODTUG KScope 2014)

Published in: Software
  • Be the first to comment

  • Be the first to like this

Reaching out from ADF Mobile (ODTUG KScope 2014)

  1. 1. Reaching out from ADF Mobile ODTUG Kscope 14, Seattle, June 2014
  2. 2. Who Am I • Luc Bors • Principal Consultant • AMIS, Netherlands • 3 times Oracle Fusion Middleware Partner of the year (2011, 2013, 2014)
  3. 3. 3 Types of Applications • Native Solution – Higher barrier to entry – Tight integration to device features • Browser-based Solution – Easiest to provide – Limited integration to device features • Hybrid Solution Image from http://wiki.developerforce.com (salesforce) – Combines ease of web development with the power of native applications – Good integration to device features
  4. 4. Oracle ADF Mobile • Build Once, Run on Multiple-Platforms – Phones, Tablets, iOS, Android, … • Java for business logic • HTML5/JavaScript user interface • Consistent business logic & data model • Disconnected: SQLite with encryption • Full access to native device features • Modular, reusable application components • JDeveloper and soon Eclipse
  5. 5. Native Mobile User Experience • Device native user experience • Spring board and tab bar for feature navigation • Advanced HTML5-based UI • Full animation, gesture, and touch interaction support • Interactive Data Visualization Components • Device Interaction using Cordova
  6. 6. ADF Mobile Overview
  7. 7. The Big Bad Mobile World
  8. 8. Todays Topics • Embedding remote content • Displaying remote files • Using GPS and Google APIs’ • Embedding Social Media • Inter App Communication • Notifications
  9. 9. Remote URLs • For embedding existing web pages in your ADF Mobile app. • For instance: – News Website – Existing enterprise app Mobile Browser Pages • Note: – Best use Optimized Mobile Browser Pages – Apache Trinidad components – Oracle recommends using ADF Mobile browser
  10. 10. Feature as Remote URL • Create New Feature as Remote URL • Create URL Connection
  11. 11. Disable Device Access • Device Access can be disabled
  12. 12. Browser Navigation • You can Enable Browser Navigation Buttons
  13. 13. Whitelisting • Why do we need to do this ? • Again; Why do we need to do this ?
  14. 14. FileContent Display • Integration with Device Native Viewers • Exposed as displayFile on DataControl • On Android: Use FileType to start appropriate viewer • On iOS QuickLook Preview is used
  15. 15. The File Processing • displayFile method is only able to display files that are local to the device. – This means that remote files first have to be downloaded. public void remotePreview(ActionEvent e){ URL remoteFileUrl; InputStream is; FileOutputStream fos; try{ // open connection to remote PDF file remoteFileUrl = new URL( "http://ilabs.uw.edu/sites/default/files/sample_0.pdf"); URLConnection connection = remoteFileUrl.openConnection(); is = connection.getInputStream(); // we write the file to the application directory File localFile = new File( AdfmfJavaUtilities.getDirectoryPathRoot( AdfmfJavaUtilities.ApplicationDirectory) + "/downloadedPDF.pdf"); fos = new FileOutputStream(localFile);
  16. 16. The Actual Display // displayFile takes a URL string which has to be encoded. // Call method in a utility class to do the encoding of the String String encodedString = MyUtils.EncodeUrlString(localFile); // create URL and invoke displayFile with its String representation URL localURL = new URL("file", "localhost", encodedString); DeviceManager dm = DeviceManagerFactory.getDeviceManager(); dm.displayFile(localURL.toString(), “Preview Header”);
  17. 17. Google Places
  18. 18. Enable API Acces • Enable Google Places API Access
  19. 19. The Places URL https://maps.googleapis.com/maps/api/place/nearbysearch/JSON?parameters
  20. 20. Parameters • location=52.35985,4.88510 (will be derived from the GPS location of your device) • radius=1000 • types – food – leisure (this is actually a set of types that can be combined by using a pipe symbol) • museum • art_gallery • zoo • movie_theater • sensor=false • key=<your google API key> https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=5 2.35985,4.88510&radius=1000&types=art_gallery&sensor=false&key=<you r google API key>
  21. 21. Result "results" : [ { "geometry" : { "location" : { "lat" : 52.363850, "lng" : 4.880790 } }, "icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/cafe-71.png", "id" : "7e7aa85e3e8fb7436bf77647cecbc6ce80db0b4a”, "name" : "American Hotel", "rating" : 3.60, "types" : [ "cafe", "lodging", "food", "establishment" ], "vicinity" : "Leidsekade 97, Amsterdam” }, … next results……
  22. 22. Two important classes • To handle a JSON response you need two classes – RestServiceAdapter – JSONBeanSerializationHelper • In this Example these are used in one method that does the search and processes the result public void searchAction(String mapType) { …. …
  23. 23. Connection • RestServiceAdapter interface in your ADF Mobile application, it needs a valid connection to the URL where the service is hosted. Make sure that there is a valid connection in the connections.xml or simply create a new connection.
  24. 24. RestServiceAdapter RestServiceAdapter restServiceAdapter =Model.createRestServiceAdapter(); // Clear previously request properties restServiceAdapter.clearRequestProperties(); // Set the connection restServiceAdapter.setConnectionName("GooglePlacesUrlConn"); // Specify the type restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_GET); restServiceAdapter.addRequestProperty("Content-Type”,"application/json"); restServiceAdapter.addRequestProperty("Accept”,"application/json; charset=UTF-8"); // Specify the number of retries restServiceAdapter.setRetryLimit(0); // Set the URI restServiceAdapter.setRequestURI("?location=52.35985,4.88510&radius=1000&types=" + mapType + "&sensor=false&key=<yourKey>"); String response = "error"; try { response = restServiceAdapter.send("");
  25. 25. JSONBeanSerializationHelper • For JSON deserialization JSONBeanSerializationHelper jsonHelper = new JSONBeanSerializationHelper(); try { response = restServiceAdapter.send(""); ServiceResult responseObject = (ServiceResult)jsonHelper.fromJSON(ServiceResult.class, response); if ( "OK".equalsIgnoreCase( responseObject.getStatus()) ) { placesResult = PlacesHelper.transformObject(responseObject).getResults(); } this.result = responseObject.getStatus(); } catch (Exception e) { e.printStackTrace(); this.result = "error"; }
  26. 26. Search and Result public class PlacesResult { private String vicinity; private Double rating; private String name; private String types; private String icon; private PlacesGeometry geometry;
  27. 27. The ADF DVT Map Component <dvtm:geographicMap id="map1" zoomLevel="4" centerX="52.37323" centerY="4.89166"> <dvtm:pointDataLayer value="#{bindings.placesResults.collectionModel}" id="pdl2" var="row"> <dvtm:pointLocation id="ptl1" type="address" pointName="#{row.name}" address="#{row.vicinity}"> <dvtm:marker id="mrk1" source="#{row.icon}"/> </dvtm:pointLocation> </dvtm:pointDataLayer> </dvtm:geographicMap>
  28. 28. Embedding Twitter • Two options: – Exactly like the previous sample using the Twitter REST API v1.1 https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=<name> – Using twitter Widgets (only on Android)
  29. 29. Twitter Widgets
  30. 30. The code for the Widget <a class="twitter-timeline” href="https://twitter.com/TamcappConf" data-widget-id="yourData-Widget-Id"> Tweets by @TamcappConf</a> <script type="text/javascript"> !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/ ^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d .createElement(s);js.id=id;js.src=p+"http://platform.twitter.com/widge ts.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitt er-wjs"); </script>
  31. 31. Whitelisting
  32. 32. Layout Components
  33. 33. Using Layout Components
  34. 34. Gesture Support • You can configure Button, Link, and List Item components to react to the following gestures: • Swipe to the right • Swipe to the left • Swipe up • Swipe down • Tap-and-hold
  35. 35. Use case example
  36. 36. Inter App Communication • Communicate between apps using URL Scheme – Call One ADF Mobile app from other ADF Mobile App – Call Skype from within ADF Mobile App – Call Barcode Scanner App form ADF Mobile App – Call any App from ADF Mobile App
  37. 37. Barcode Scanning
  38. 38. URL Scheme •
  39. 39. URL Scheme Listener public class UrlSchemeCalledListener implements EventListener { public UrlSchemeCalledListener() { super(); } public void onMessage(Event event){ } public void onError(AdfException adfException){ } public void onOpen(String string){ } }
  40. 40. URL Scheme Listener public void start(){ EventSource openUrl = EventSourceFactory.getEventSource( EventSourceFactory.OPEN_URL_EVENT_SOURCE_NAME); openUrl.addListener(new UrlSchemeCalledListener());
  41. 41. Interact with other App <amx:goLink url="zxing://scan/?ret=tamcapp://scan?scannedCode={CODE}" id="gl2"> <amx:image inlineStyle="height:102px;width:102px;margin-top:4px" source="/images/Barcode.png"/> </amx:goLink>
  42. 42. Work with the response public void onMessage(Event event){ AdfELContext elctx = AdfmfJavaUtilities.getAdfELContext(); String url = event.getPayload(); // Isolate the action. We do this because if there are more URL-Scheme // callbacks, we are able to respond to this in this one single method String action = url.substring(url.indexOf("//") + 2, url.indexOf("?")); if (action.equalsIgnoreCase("scan")) { String codeScanned = url.substring(url.indexOf("?scannedCode=")+ 13, url.length()); ValueExpression val2 = AdfmfJavaUtilities.getValueExpression( "#{applicationScope.scannedCode}", Object.class); try{ val2.setValue(elctx, codeScanned); } catch {………..} AdfmfContainerUtilities.gotoFeature("com.blogspot.lucbors.scan.Scanner"); } }
  43. 43. Demo
  44. 44. Push Notifications
  45. 45. Push Notifications •
  46. 46. Push Notifications • Subscribe to Messaging Service • Receive token • Register with Enterprise app • Enterprise app Pushes message to Messaging Service • Messaging Service delegates message to device(s)
  47. 47. Push Notification
  48. 48. Start GCM • ApplicationLifeCycleListener – Start() – getNotificationStyle() – getSourceAuthorizationId() public void start() { // Add code here... EventSource evtSource = EventSourceFactory.getEventSource( NativePushNotificationEventSource. NATIVE_PUSH_NOTIFICATION_REMOTE_EVENT_SOURCE_NAME); evtSource.addListener(new PushNotificationListener()); } public long getNotificationStyle() { return PushNotificationConfig.NOTIFICATION_STYLE_ALERT | PushNotificationConfig.NOTIFICATION_STYLE_BADGE | PushNotificationConfig.NOTIFICATION_STYLE_BADGE;}
  49. 49. Open the application • PushNotificationListener – OnMessage – OnError – OnOpen public void onOpen(String token) { // Invoked during the Push Notification registration process. // The parameter "token" contains the token received from APNs or GCMs // that uniquely identifies a specific device-application combination. ValueExpression ve = AdfmfJavaUtilities.getValueExpression( "#{applicationScope.deviceToken}", String.class); if (token != null){ ve.setValue(AdfmfJavaUtilities.getAdfELContext(), token); } else{ ve.setValue(AdfmfJavaUtilities.getAdfELContext(), "dummy Token"); } }
  50. 50. Example • Select device • Send message • Get notified
  51. 51. GCM Demo
  52. 52. Summary • Remote URL – Simple for (re-) using existing mobile websites • Display File – To download files and display them in the App in the device native viewer. • REST Services (such as Google Places) – Embed external data into your ADF Mobile APP • Twitter via Local HTML – To use twitter timeline via Twitter Widgets • URL Scheme – For inter app communication • Push Notifications – Rather complex setup but after that very powerful – Keep in mind that there is no guaranteed delivery
  53. 53. Luc Bors, AMIS, The Netherlands Luc.Bors@amis.nl LucBors@gmail.com Follow me on : @lucb_

×