2 * ******************************************************************
4 * Copyright 2017 Samsung Electronics All Rights Reserved.
6 * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
20 * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 package org.iotivity.base.examples;
25 import android.app.Activity;
26 import android.app.Fragment;
27 import android.content.Context;
28 import android.os.Bundle;
29 import android.os.Handler;
30 import android.os.Message;
31 import android.os.PowerManager;
32 import android.util.Log;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.view.ViewGroup;
36 import android.widget.Button;
37 import android.widget.TextView;
39 import org.iotivity.base.ModeType;
40 import org.iotivity.base.OcConnectivityType;
41 import org.iotivity.base.OcException;
42 import org.iotivity.base.OcHeaderOption;
43 import org.iotivity.base.OcPlatform;
44 import org.iotivity.base.OcRepresentation;
45 import org.iotivity.base.OcResource;
46 import org.iotivity.base.PlatformConfig;
47 import org.iotivity.base.QualityOfService;
48 import org.iotivity.base.ServiceType;
49 import org.iotivity.ca.CaInterface;
51 import java.util.EnumSet;
52 import java.util.HashMap;
53 import java.util.List;
57 * This class is for Keep Alive between the client and server (or Cloud).
58 * It can handle Keep Alive mechanism manually.
60 public class KeepAliveFragment extends Fragment implements
61 OcResource.OnGetListener, CaInterface.OnConnectionManagerStateListener {
63 private static final String TAG = "OIC_SIMPLE_KEEPALIVE";
64 private final String EOL = System.getProperties().getProperty("line.separator");
65 private final long MILLI_PER_SEC = 1000;
66 private final long ONE_MINUTE = 60 * MILLI_PER_SEC;
67 private final long MARGIN_SEC = 10;
68 private final int KEEPALIVE_MSG = 1;
69 private final int TIMER_MSG = 2;
70 private final int OC_STACK_OK = 0;
71 private final int OC_STACK_RESOURCE_CHANGED = 4;
73 private Activity mActivity;
74 private Context mContext;
75 private PowerManager.WakeLock mWakeLock;
77 private TextView mIntervalView;
78 private TextView mRemainView;
79 private TextView mStatusView;
81 private TextView mActionLog;
82 private TextView mResultLog;
84 private Button mDiscoveryButton;
85 private Button mFindButton;
86 private Button mSendButton;
88 private boolean isShowTimer = true;
90 private long mStartTime = 0;
91 private long mEndTime = 0;
92 private long mRemainTime = -1;
94 private int mInterval[] = {2, 4, 8};
95 private int mIndex = 0;
97 private String mHost = null;
100 public void onCreate(Bundle savedInstanceState) {
101 super.onCreate(savedInstanceState);
103 mActivity = getActivity();
104 mContext = mActivity.getBaseContext();
106 initOcPlatform(ModeType.CLIENT);
107 CaInterface.startManagerService(mContext, this);
109 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
110 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
114 public void onDestroy() {
116 CaInterface.stopManagerService();
121 View.OnClickListener discoveryButtonListener() {
122 return new View.OnClickListener() {
124 public void onClick(View view) {
125 Log.i(TAG, "discoveryButtonListener");
128 OcPlatform.findResource("",
129 OcPlatform.WELL_KNOWN_QUERY,
130 EnumSet.of(OcConnectivityType.CT_ADAPTER_IP),
131 resourceFoundListener, QualityOfService.LOW);
132 } catch (OcException e) {
136 mActivity.runOnUiThread(new Runnable() {
139 mActionLog.setText("[Action Log]" + EOL);
140 mActionLog.append("Discovery Click" + EOL);
142 mResultLog.setText("[Result Log]" + EOL);
143 mResultLog.append("Start Time : ");
144 mResultLog.append(Common.getDateCurrentTimeZone() + EOL);
145 mStartTime = System.currentTimeMillis();
154 OcPlatform.OnResourceFoundListener resourceFoundListener =
155 new OcPlatform.OnResourceFoundListener() {
157 public void onResourceFound(OcResource ocResource) {
158 synchronized (mActivity) {
159 final String resourceUri = ocResource.getUri();
160 Log.i(TAG, "onResourceFound : " + resourceUri);
162 if (resourceUri.contains(Common.RESOURCE_URI)
163 && ocResource.getConnectivityTypeSet().contains(OcConnectivityType.CT_ADAPTER_TCP)) {
165 mHost = ocResource.getHost();
166 mActivity.runOnUiThread(new Runnable() {
169 mEndTime = System.currentTimeMillis();
170 double flightTime = (double) (mEndTime - mStartTime) / MILLI_PER_SEC;
171 mResultLog.append("Discovery Time : "
172 + String.format("%.3f", flightTime) + "sec" + EOL);
176 sendGetToFoundResource(ocResource);
182 public void onFindResourceFailed(Throwable throwable, String uri) {
183 synchronized (mActivity) {
184 Log.i(TAG, "findResource request has failed");
185 Log.e(TAG, throwable.toString());
192 // [[ Find KeepAlive Resource
193 View.OnClickListener findButtonListener() {
194 return new View.OnClickListener() {
196 public void onClick(View view) {
197 Log.i(TAG, "findButtonListener");
200 OcPlatform.findKeepAliveResource(mHost, pingResourceFoundListener);
201 } catch (OcException e) {
205 mActivity.runOnUiThread(new Runnable() {
208 mActionLog.setText("[Action Log]" + EOL);
209 mActionLog.append("Find Ping" + EOL);
218 OcPlatform.KeepAliveListener pingResourceFoundListener =
219 new OcPlatform.KeepAliveListener() {
221 public void onKeepAliveListener(OcRepresentation ocRepresentation,
223 synchronized (mActivity) {
224 Log.i(TAG, "onKeepAliveListener : " + result);
226 mActivity.runOnUiThread(new Runnable() {
229 if (OC_STACK_OK == result || OC_STACK_RESOURCE_CHANGED == result) {
230 mSendButton.setEnabled(true);
233 mResultLog.append("Ping Resource Found Result : " + result + EOL);
240 // ]] Find KeepAlive Resource
243 // [[ Send KeepAlive Request
244 View.OnLongClickListener sendButtonLongListener() {
245 return new View.OnLongClickListener() {
247 public boolean onLongClick(View v) {
248 Log.i(TAG, "sendButtonLongListener");
250 mActivity.runOnUiThread(new Runnable() {
253 mActionLog.setText("[Action Log]" + EOL);
254 mActionLog.append("Send Interval" + EOL);
265 View.OnClickListener sendButtonListener() {
266 return new View.OnClickListener() {
268 public void onClick(View view) {
269 Log.i(TAG, "sendButtonListener");
271 mActivity.runOnUiThread(new Runnable() {
274 mActionLog.setText("[Action Log]" + EOL);
275 mActionLog.append("Send Ping" + EOL);
279 mSendButton.setEnabled(false);
285 private void sendPing(boolean updateInterval) {
286 if (updateInterval) {
287 mResultLog.append("Send Keep Alive Interval with {2, 4, 8}" + EOL);
289 mResultLog.append("Send Keep Alive Request with " + mInterval[mIndex] + "min" + EOL);
293 OcRepresentation rep = new OcRepresentation();
294 rep.setValue("in", mInterval[mIndex]);
295 if (updateInterval) {
296 rep.setValue("inarray", mInterval);
298 OcPlatform.sendKeepAliveRequest(mHost, rep, keepAliveListener);
299 } catch (OcException e) {
302 mWakeLock.acquire(ONE_MINUTE);
304 if (!updateInterval) {
306 mRemainTime = mInterval[mIndex] * ONE_MINUTE / MILLI_PER_SEC - MARGIN_SEC;
309 Message msg = new Message();
310 msg.what = KEEPALIVE_MSG;
311 mHandler.sendMessageDelayed(msg, mInterval[mIndex] * ONE_MINUTE);
314 if (mInterval.length - 1 > mIndex) {
320 OcPlatform.KeepAliveListener keepAliveListener =
321 new OcPlatform.KeepAliveListener() {
323 public void onKeepAliveListener(OcRepresentation ocRepresentation,
325 synchronized (mActivity) {
326 Log.i(TAG, "onKeepAliveListener : " + result);
328 mActivity.runOnUiThread(new Runnable() {
331 if (OC_STACK_OK != result && OC_STACK_RESOURCE_CHANGED != result) {
335 mResultLog.append("Keep Alive Request Result : " + result + EOL);
342 private void showTimer() {
343 mRemainView.setText("Remain Time : " + mRemainTime + "sec");
345 if (mRemainTime > 0) {
346 Message msg = new Message();
347 msg.what = TIMER_MSG;
348 mHandler.sendMessageDelayed(msg, MILLI_PER_SEC);
349 } else if (mRemainTime == 0) {
357 private Handler mHandler = new Handler() {
359 public void handleMessage(Message msg) {
372 // ]] Send KeepAlive Request
377 public void onAdapterStateChanged(OcConnectivityType ocConnectivityType, boolean b) {
378 Log.i(TAG, "onAdapterStateChanged");
382 public void onConnectionStateChanged(OcConnectivityType type,
383 String address, final boolean connected) {
384 Log.i(TAG, "onConnectionStateChanged address: " + address);
386 if (OcConnectivityType.CT_ADAPTER_TCP == type) {
387 final String msg = getString(R.string.action_onconnectionstatechanged) + connected;
389 mActivity.runOnUiThread(new Runnable() {
392 mStatusView.setText("TCP Connected : " + connected);
393 mFindButton.setEnabled(connected);
394 mResultLog.append(msg + EOL);
407 void sendGetToFoundResource(final OcResource ocResource) {
409 Log.i(TAG, "sendGetToFoundResource");
410 mActivity.runOnUiThread(new Runnable() {
413 mResultLog.append("Send get to : " + ocResource.getHost() + EOL);
417 Map<String, String> queryParameters = new HashMap<String, String>();
418 queryParameters.put(Common.GET_COMMAND, Common.STATE_GET);
419 ocResource.get(queryParameters, this, QualityOfService.LOW);
421 } catch (OcException e) {
427 public void onGetCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
428 Log.i(TAG, "onGetCompleted");
432 public void onGetFailed(Throwable throwable) {
433 Log.i(TAG, "onGetFailed");
437 private void resetInterval() {
438 mHandler.removeMessages(TIMER_MSG);
439 mRemainView.setText("Remain Time : -");
440 mSendButton.setEnabled(false);
445 private void initOcPlatform(ModeType type) {
446 PlatformConfig cfg = new PlatformConfig(mActivity, mContext,
451 QualityOfService.LOW);
452 OcPlatform.Configure(cfg);
456 public View onCreateView(LayoutInflater inflater, ViewGroup container,
457 Bundle savedInstanceState) {
458 View rootView = inflater.inflate(R.layout.fragment_keepalive, container, false);
460 mIntervalView = (TextView) rootView.findViewById(R.id.interval_view);
461 mIntervalView.setText("Interval : {2, 4, 8}");
462 mRemainView = (TextView) rootView.findViewById(R.id.remain_view);
463 mStatusView = (TextView) rootView.findViewById(R.id.status_view);
465 mActionLog = (TextView) rootView.findViewById(R.id.action_log_view);
466 mResultLog = (TextView) rootView.findViewById(R.id.result_log_view);
468 mDiscoveryButton = (Button) rootView.findViewById(R.id.discovery_button);
469 mFindButton = (Button) rootView.findViewById(R.id.find_button);
470 mSendButton = (Button) rootView.findViewById(R.id.send_button);
472 mDiscoveryButton.setOnClickListener(discoveryButtonListener());
473 mFindButton.setOnClickListener(findButtonListener());
474 mSendButton.setOnClickListener(sendButtonListener());
475 mSendButton.setOnLongClickListener(sendButtonLongListener());