reaching out from adf mobile (odtug kscope 2014)
Post on 05-Jul-2015
173 Views
Preview:
DESCRIPTION
TRANSCRIPT
ODTUG Kscope 14, Seattle, June 2014
Reaching out from ADF Mobile
Who Am I
• Luc Bors
• Principal Consultant
• AMIS, Netherlands
• 3 times Oracle Fusion Middleware Partner
of the year (2011, 2013, 2014)
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
– Combines ease of web development with the power of native
applications
– Good integration to device features
Image from http://wiki.developerforce.com (salesforce)
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
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
ADF Mobile Overview
The Big Bad Mobile World
Todays Topics
• Embedding remote content
• Displaying remote files
• Using GPS and Google APIs’
• Embedding Social Media
• Inter App Communication
• Notifications
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
Feature as Remote URL
• Create New Feature as Remote URL
• Create URL Connection
Disable Device Access
• Device Access can be disabled
Browser Navigation
• You can Enable Browser Navigation Buttons
Whitelisting
• Why do we need to do this ?
• Again; Why do we need to do this ?
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
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);
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”);
Google Places
Enable API Acces
• Enable Google Places API Access
The Places URL
https://maps.googleapis.com/maps/api/place/nearbysearch/JSON?parameters
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>
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……
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) {
….
…
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.
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("");
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";
}
Search and Result
public class PlacesResult {
private String vicinity;
private Double rating;
private String name;
private String types;
private String icon;
private PlacesGeometry geometry;
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>
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)
Twitter Widgets
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>
Whitelisting
Layout Components
Using Layout Components
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
Use case example
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
Barcode Scanning
URL Scheme
•
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){
}
}
URL Scheme Listener
public void start(){
EventSource openUrl = EventSourceFactory.getEventSource(
EventSourceFactory.OPEN_URL_EVENT_SOURCE_NAME);
openUrl.addListener(new UrlSchemeCalledListener());
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>
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");
}
}
Demo
Push Notifications
Push Notifications
•
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)
Push Notification
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;}
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");
}
}
Example
• Select device
• Send message • Get notified
GCM Demo
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
Luc Bors, AMIS, The Netherlands
Luc.Bors@amis.nl
LucBors@gmail.com
Follow me on : @lucb_
top related