/** * Copyright (c) 2013 Nokia Corporation. All rights reserved. * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. * Oracle and Java are trademarks or registered trademarks of Oracle and/or its * affiliates. Other product and company names mentioned herein may be trademarks * or trade names of their respective owners. * See license text file delivered with this project for more information. */ package com.nokia.example.statusshout.engine; import java.util.Hashtable; import java.util.Vector; import javax.microedition.content.ContentHandlerException; import javax.microedition.content.ContentHandlerServer; import javax.microedition.content.Invocation; import javax.microedition.content.Registry; import javax.microedition.content.RequestListener; import javax.microedition.midlet.MIDlet; /** * Provides a simple interface for sharing images and message via Share API. * In addition, contains the logic for managing invocations i.e. if the app was * launched via share UI of the platform. */ public class ShareApiManager implements RequestListener { // Constants private static final String TAG = "ShareApiManager."; private static final String MIME_TYPE_TEXT = "text/plain"; private static final String MIME_TYPE_WILD_CARD = "*/*"; private static final String ARGS_PREFIX_URL = "url="; private static final String ARGS_PREFIX_TEXT = "text="; // Members private static ShareApiManager instance; private MIDlet midlet; private ContentHandlerServer contentHandlerServer; private Invocation invocation; private ShareListener listener; private String imageUriFromInvocation; private boolean wasLaunchedAsSharingDestination; /** * Returns the singleton instance of this class. * * @param midlet The app MIDlet instance. * @return The singleton instance. * @throws NullPointerException If the given MIDlet instance is null. * @throws IllegalArgumentException If the given MIDlet does not match the * previously set one. */ public static ShareApiManager getInstance(MIDlet midlet) throws NullPointerException, IllegalArgumentException { if (midlet == null) { throw new NullPointerException("MIDlet is null!"); } if (instance == null) { instance = new ShareApiManager(midlet); } else if (midlet != instance.midlet) { throw new IllegalArgumentException("The MIDlet instance does not match!"); } return instance; } /** * Constructor. * * @param listener The listener for events. */ private ShareApiManager(MIDlet midlet) { this.midlet = midlet; } /** * Starts listening to the given ContentHandlerServer and handles the * invocation, if handler has one. * * @see javax.microedition.content.RequestListener#invocationRequestNotify( * javax.microedition.content.ContentHandlerServer) */ public void invocationRequestNotify(ContentHandlerServer handler) { System.out.println(TAG + "invocationRequestNotify()"); contentHandlerServer = handler; contentHandlerServer.setListener(this); // If there is an existing invocation, finish it so that the next // invocation can be handled finishInvocation(Invocation.CANCELLED); invocation = contentHandlerServer.getRequest(false); if (invocation != null) { wasLaunchedAsSharingDestination = true; if (listener != null) { listener.onLaunchedWithInvocation(invocation); } handleInvocation(); } } /** * @return True if the app was launched as a sharing destination (via * platform share UI). */ public boolean getWasLaunchedAsSharingDestination() { return wasLaunchedAsSharingDestination; } /** * @param listener The listener for this class. */ public void setListener(ShareListener listener) { this.listener = listener; } /** * @return The image URI parsed from the invocation. */ public String getImageUriFromInvocation() { return imageUriFromInvocation; } /** * Gets the ContentHandlerServer instance and check if the app was launched * with invocation. * * @see ShareApiManager#invocationRequestNotify(ContentHandlerServer) */ public void checkForInvocation() { System.out.println(TAG + "checkForInvocation()"); ContentHandlerServer handler = null; try { handler = Registry.getServer(midlet.getClass().getName()); } catch (ContentHandlerException e) { // We have used static registration, so this exception should not // happen } invocationRequestNotify(handler); } /** * Finishes the existing invocation with the given result. * * @param result The result to use to finish the existing invocation, e.g. * Invocation.OK or Invocation.CANCEL. */ public void finishInvocation(int result) { if (contentHandlerServer != null && invocation != null) { System.out.println(TAG + "finishInvocation(): " + result); contentHandlerServer.finish(invocation, result); invocation = null; } else if (invocation == null) { System.out.println(TAG + "finishInvocation(): No invocation to finish."); } else if (contentHandlerServer == null) { System.out.println(TAG + "finishInvocation(): Error: No handler!"); } } /** * Shares an image. * * @param imageUri The URI of the image to share. * @param mimeType The mime type of the image to share. */ public void shareImage(final String imageUri, final String mimeType) { System.out.println("ShareApiManager.shareImage(): " + imageUri + ", " + mimeType); if (imageUri != null && imageUri.length() > 0) { String[] args = new String[] { ARGS_PREFIX_URL + imageUri }; doInvocation(args, mimeType); } else { System.out.println("ShareApiManager.shareImage(): No image to share!"); } } /** * Shares text. * * @param text The text to share. */ public void shareText(final String text) { System.out.println("ShareApiManager.shareText(): \"" + text + "\""); if (text != null && text.length() > 0) { String[] args = new String[] { ARGS_PREFIX_TEXT + text }; doInvocation(args, MIME_TYPE_TEXT); } else { System.out.println("ShareApiManager.shareText(): No text to share!"); } } /** * Launches the Share UI with the given arguments. * * @param args Contains the information about the content to be shared. * @param mimeType The mime type of the content to share. */ private void doInvocation(String[] args, String mimeType) { System.out.println("ShareApiManager.doInvocation(): ->"); if (args == null || args[0] == null) { System.out.println("ShareApiManager.doInvocation(): Invalid arguments!"); return; } if (mimeType == null || mimeType.length() == 0) { mimeType = MIME_TYPE_WILD_CARD; } System.out.println("ShareApiManager.doInvocation(): " + args[0] + ", " + ((args.length > 1 && args[1] != null) ? (args[1] + ", ") : "") + mimeType); try { final Registry registry = Registry.getRegistry(midlet.getClass().getName()); Invocation invocation = new Invocation(null, mimeType, "com.nokia.share"); invocation.setResponseRequired(false); invocation.setAction("share"); invocation.setArgs(args); if (registry.invoke(invocation)) { // If application must be closed before invocation //notifyDestroyed(); } } catch (Exception e) { System.out.println("ShareApiManager.doInvocation(): " + e.toString()); if (listener != null) { listener.onError(e.toString()); } } System.out.println("ShareApiManager.doInvocation(): <-"); } /** * Handles the invocation: Parses the data provided with the invocation. */ private void handleInvocation() { if (invocation == null) { return; } System.out.println(TAG + "handleInvocation(): " + "Action: " + invocation.getAction() + ", Response required: " + invocation.getResponseRequired()); Hashtable argsTable = parseArgs(invocation.getArgs()); /* * In case you want to share text content in your application, implement * this part. */ /*Vector texts = (Vector) argsTable.get("text"); if (texts != null) { // TODO }*/ Vector urls = (Vector) argsTable.get("url"); if (urls != null) { // Share API is capable of sharing multiple images at once but this // application only shares the first one in the array if (urls.elementAt(0) != null) { imageUriFromInvocation = (String)urls.elementAt(0); System.out.println(TAG + "handleInvocation(): Setting image URI to " + imageUriFromInvocation); } } } /** * Parses the <code>Invocation</code> arguments to <code>HashTable</code>. * * @param args The argument list as an array of Strings. * @return The arguments in HashTable. */ private static Hashtable parseArgs(String[] args) { Hashtable argsTable = new Hashtable(); for (int i = 0; i < args.length; ++i) { String arg = args[i]; int j = arg.indexOf("="); if (j > 0) { String key = arg.substring(0, j); String value = arg.substring(j + 1); Vector valueVector; if (argsTable.get(key) == null) { valueVector = new Vector(); } else { valueVector = (Vector) argsTable.get(key); } valueVector.addElement(value); argsTable.put(key, valueVector); } } return argsTable; } }