Java tutorial
/* * Copyright 2014 CloudMatch.io * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.ticofab.cm_android_sdk.library.views; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.util.AttributeSet; import android.view.View; import com.codebutler.android_websockets.WebSocketClient; import org.json.JSONException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import io.ticofab.cm_android_sdk.library.consts.Criteria; import io.ticofab.cm_android_sdk.library.consts.ServerConsts; import io.ticofab.cm_android_sdk.library.exceptions.CloudMatchNotConnectedException; import io.ticofab.cm_android_sdk.library.exceptions.CloudMatchNotInitializedException; import io.ticofab.cm_android_sdk.library.handlers.ServerMessagesHandler; import io.ticofab.cm_android_sdk.library.helpers.Connector; import io.ticofab.cm_android_sdk.library.helpers.Matcher; import io.ticofab.cm_android_sdk.library.helpers.StringHelper; import io.ticofab.cm_android_sdk.library.helpers.UniqueIDHelper; import io.ticofab.cm_android_sdk.library.interfaces.CloudMatchEventListener; import io.ticofab.cm_android_sdk.library.interfaces.CloudMatchViewInterface; import io.ticofab.cm_android_sdk.library.interfaces.LocationProvider; import io.ticofab.cm_android_sdk.library.listeners.CloudMatchListener; import io.ticofab.cm_android_sdk.library.models.inputs.DeliveryInput; /** * Abstract custom view providing the basic functionality of GestureMatch views. */ public abstract class CloudMatchView extends View { // the WebSocket client object, used in all network operations WebSocketClient mWSClient; // we need a reference to an activity for various things Activity mActivity; // the client-provided implementation of OnCloudMatchEvent CloudMatchEventListener mListener; // helper to match devices Matcher mMatcher; // the interface for the client to control his view CloudMatchViewInterface mClientInterface; // pinch or swipe? Criteria mCriteria; public CloudMatchView(final Context context) { super(context); } public CloudMatchView(final Context context, final AttributeSet attrs) { super(context, attrs); } /** * Initializes the CloudMatch. Always call it at the beginning of your application. * * @param activity Provides the context where the application runs. * @param clientListener Implementation of the OnCloudMatchEvent interface. Will be used to notify any network communication. * @param locationProvider Implementation of LocationProvider, needs to serve coordinates when needed * @param clientInterface Implementation of the CloudMatchViewInterface * @throws PackageManager.NameNotFoundException Exception thrown if credentials were not found. */ public void initCloudMatch(final Activity activity, final CloudMatchEventListener clientListener, final LocationProvider locationProvider, final CloudMatchViewInterface clientInterface) throws PackageManager.NameNotFoundException { mActivity = activity; mListener = clientListener; mClientInterface = clientInterface; if (mActivity == null) { throw new CloudMatchNotInitializedException("Activity cannot be null."); } // initialize socket final ServerMessagesHandler myMessagesHandler = new ServerMessagesHandler(mActivity, mListener); final CloudMatchListener myListener = new CloudMatchListener(mActivity, mListener, myMessagesHandler); Connector connector = new Connector(mActivity, StringHelper.getApiKey(mActivity), StringHelper.getAppId(mActivity)); final URI uri; try { uri = connector.getConnectionUri(); mWSClient = new WebSocketClient(uri, myListener, null); mMatcher = new Matcher(mWSClient, locationProvider); } catch (URISyntaxException e) { e.printStackTrace(); } } public boolean isInitialized() { return mWSClient != null && mActivity != null && mListener != null && mClientInterface != null; } /** * Connects the CloudMatch. You need to call init() first. * * @throws CloudMatchNotInitializedException Thrown if this method is invoked before initialization. */ public void connect() throws CloudMatchNotInitializedException { if (mWSClient == null) { throw new CloudMatchNotInitializedException(); } if (mWSClient.isConnected()) { mWSClient.disconnect(); } mWSClient.connect(); } public boolean isConnected() { return mWSClient != null && mWSClient.isConnected(); } /** * Delivers payload to all the members of the provided group. * * @param payload The delivery payload. * @param groupId The group to which send the payload. * @param tag Optional tag for this delivery. Can be null. * @throws CloudMatchNotConnectedException Thrown if this method is invoked while CloudMatch is not connected. */ public void deliverPayloadToGroup(final String payload, final String groupId, final String tag) throws CloudMatchNotConnectedException { deliverPayload(null, payload, groupId, tag); } /** * Delivers payload to one or more devices (recipients) that are part of the provided group. * * @param recipients The devices that will receive this payload * @param payload The payload to deliver * @param groupId The group id * @param tag A string identifying this delivery * @throws CloudMatchNotConnectedException Thrown if this method is invoked while CloudMatch is not connected. */ // TODO: this should forward to a "deliverer" or something public void deliverPayload(final ArrayList<Integer> recipients, final String payload, final String groupId, final String tag) throws CloudMatchNotConnectedException, CloudMatchNotInitializedException { if (mWSClient == null) { throw new CloudMatchNotInitializedException(); } if (!mWSClient.isConnected()) { throw new CloudMatchNotConnectedException(); } final ArrayList<String> chunks = StringHelper.splitEqually(payload, ServerConsts.MAX_DELIVERY_CHUNK_SIZE); final DeliveryInput deliveryInput = new DeliveryInput(); final String deliveryId = UniqueIDHelper.createDeliveryId(); deliveryInput.mRecipients = recipients; deliveryInput.mGroupId = groupId; deliveryInput.mTag = tag; deliveryInput.mDeliveryId = deliveryId; final int totalChunks = chunks.size(); for (int i = 0; i < totalChunks; i++) { deliveryInput.mPayload = chunks.get(i); deliveryInput.mChunkNr = i; deliveryInput.mTotalChunks = totalChunks; try { final String jsonToSend = deliveryInput.toJsonStr(); mWSClient.send(jsonToSend); mActivity.runOnUiThread(new DeliveryProgressRunnable(tag, deliveryId, totalChunks, i, mListener)); } catch (final JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static class DeliveryProgressRunnable implements Runnable { String mTag; int mTotalChunks; int mCurrentChunk; String mDeliveryId; CloudMatchEventListener mListener; public DeliveryProgressRunnable(final String tag, final String deliveryId, final int totalChunks, final int currentChunk, final CloudMatchEventListener listener) { mTag = tag; mListener = listener; mDeliveryId = deliveryId; mTotalChunks = totalChunks; mCurrentChunk = currentChunk; } @Override public void run() { mListener.onDeliveryProgress(mTag, mDeliveryId, 100 * (mCurrentChunk + 1) / mTotalChunks); } } /** * Closes the connection with the server, disconnecting the WebSocketClient object. */ public void closeConnection() { if (mWSClient != null && mWSClient.isConnected()) { mWSClient.disconnect(); } } }