[IOT-1560]Implementation of Provider and Consumer MQ cloud service sample application
authorabitha.s <abitha.s@samsung.com>
Tue, 15 Nov 2016 12:18:49 +0000 (17:48 +0530)
committerUze Choi <uzchoi@samsung.com>
Thu, 17 Nov 2016 07:55:55 +0000 (07:55 +0000)
https://jira.iotivity.org/browse/IOT-1560
API about subscription to MQ notification in Java is tested with sample application.

Change-Id: I0bf6c27afd2dd300a279c53e47d32f24f4edc5f9
Signed-off-by: abitha.s <abitha.s@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/14363
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
13 files changed:
service/notification/examples/android/NotiConsumerExample/app/src/main/AndroidManifest.xml
service/notification/examples/android/NotiConsumerExample/app/src/main/java/com/sec/noticonsumerexample/ConsumerSample.java
service/notification/examples/android/NotiConsumerExample/app/src/main/java/com/sec/noticonsumerexample/LoginActivity.java [new file with mode: 0755]
service/notification/examples/android/NotiConsumerExample/app/src/main/java/com/sec/noticonsumerexample/MainActivity.java
service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/activity_login.xml [new file with mode: 0755]
service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/activity_main.xml
service/notification/examples/android/NotiProviderExample/app/src/main/AndroidManifest.xml [changed mode: 0644->0755]
service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/LoginActivity.java [new file with mode: 0755]
service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/MainActivity.java
service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/ProviderSample.java
service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_login.xml [new file with mode: 0755]
service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_main.xml [changed mode: 0644->0755]
service/notification/examples/android/NotiProviderExample/app/src/main/res/values/strings.xml [changed mode: 0644->0755]

index fe09e0e..52373eb 100755 (executable)
@@ -29,7 +29,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />\r
             </intent-filter>\r
         </activity>\r
-\r
+        <activity android:name=".LoginActivity" />\r
 \r
     </application>\r
 \r
index 13f1908..f52eb74 100755 (executable)
@@ -135,7 +135,19 @@ public class ConsumerSample
             Log.e(TAG, "NSException: enableRemoteService : " + e);
         }
     }
+    public int subscribeMQService(String servAdd, String topicName) {
+        Log.i(TAG, "SubscribeMQService  - IN");
+        int result = 0;
+        try{
+            result = consumerService.subscribeMQService(servAdd, topicName);
+            Log.i(TAG, "Notification SubscribeMQService: "+ result );
+        }
+        catch(Exception e) {
 
+        }
+        Log.i(TAG, "SubscribeMQService  - OUT");
+        return result;
+    }
     public void rescanProvider()
     {
         try
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/main/java/com/sec/noticonsumerexample/LoginActivity.java b/service/notification/examples/android/NotiConsumerExample/app/src/main/java/com/sec/noticonsumerexample/LoginActivity.java
new file mode 100755 (executable)
index 0000000..56155e8
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * ******************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * 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 com.sec.noticonsumerexample;
+import android.app.Activity;
+import android.content.Intent;
+import android.net.UrlQuerySanitizer;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+
+/**
+ * This class is for login to the provider.
+ * Can be get auth code via web page.
+ */
+public class LoginActivity extends Activity {
+    private static final String TAG = "OIC_SIMPLE_LOGIN";
+
+    private WebView mWebView = null;
+    private final String samsungAccount = "https://account.samsung.com/mobile/account/check.do?serviceID=166135d296&actionID=StartOAuth2&countryCode="+ "US" + "&languageCode=" + "en";
+    private final String mAuthProvider = "samsung-us";
+
+
+    @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setContentView(R.layout.activity_login);
+
+            mWebView = (WebView) findViewById(R.id.webView);
+            mWebView.setInitialScale(200);
+            mWebView.getSettings().setJavaScriptEnabled(true);
+            mWebView.getSettings().setBuiltInZoomControls(true);
+            mWebView.setWebViewClient(new WebViewClientClass());
+
+            mWebView.loadUrl(samsungAccount);
+        }
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    private class WebViewClientClass extends WebViewClient {
+
+        @Override
+            public void onPageFinished(WebView view, String url) {
+                Log.i(TAG, "onPageFinished!!! Response received: called url=" + url);
+
+                    if (url.contains("code") && url.contains("code_expires_in")) {
+
+                    mWebView.setVisibility(View.INVISIBLE);
+
+                    // parsing url
+                    UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
+                    sanitizer.setAllowUnregisteredParamaters(true);
+                    sanitizer.parseUrl(url);
+
+                    String mAuthCode = sanitizer.getValue("code");
+                    Log.i(TAG, "onPageFinished!!! authCode=" + mAuthCode);
+
+                    Intent intent = getIntent();
+                    intent.putExtra("authCode", mAuthCode);
+                    intent.putExtra("authProvider", mAuthProvider);
+                    setResult(RESULT_OK, intent);
+
+                    finish();
+                }
+            }
+    }
+}
index f332ac2..98db966 100755 (executable)
@@ -18,6 +18,7 @@
 \r
 package com.sec.noticonsumerexample;\r
 \r
+import android.content.Intent;\r
 import android.os.Bundle;\r
 import android.os.Handler;\r
 import android.os.Message;\r
@@ -28,12 +29,32 @@ import android.widget.Button;
 import android.widget.TextView;\r
 import android.widget.Toast;\r
 \r
+import org.iotivity.base.ErrorCode;\r
+import org.iotivity.base.OcAccountManager;\r
+import org.iotivity.base.OcConnectivityType;\r
+import org.iotivity.base.OcException;\r
+import org.iotivity.base.OcHeaderOption;\r
+import org.iotivity.base.OcPlatform;\r
+import org.iotivity.base.OcRepresentation;\r
+import org.iotivity.base.OcResource;\r
 import org.iotivity.service.ns.common.TopicsList;\r
 import org.iotivity.service.ns.common.Topic;\r
 \r
-public class MainActivity extends Activity\r
+import java.util.Arrays;\r
+import java.util.EnumSet;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+\r
+public class MainActivity extends Activity  implements OcAccountManager.OnPostListener\r
 {\r
     private final String TAG = "NS_MAIN_ACTIVITY";\r
+    private final int REQUEST_LOGIN = 1;\r
+\r
+    public static final String deviceID = "9E09F4FE-978A-4BC3-B356-1F93BCA37829";\r
+    public static final String CIServer = "coap+tcp://52.40.216.160:5683";\r
+    public static final String RemoteAddress = "52.40.216.160:5683";\r
+    public static final String MQCloudAddress = "52.78.151.180:5683";\r
+    public static final String MQCloudTopic = "/oic/ps/notification";\r
 \r
     private Button btnStart;\r
     private Button btnStop;\r
@@ -43,10 +64,18 @@ public class MainActivity extends Activity
     private Button btnUpdateTopicList;\r
     private Button btnClearLog;\r
     private static TextView TvLog;\r
+    private Button signUp, signIn, signOut;\r
+    private Button subscribeMQ;\r
 \r
     private boolean isStarted = false;\r
 \r
     private ConsumerSample mConsumerSample = null;\r
+    private OcAccountManager mAccountManager;\r
+    String mAuthCode;\r
+    String mAuthProvider;\r
+    String mRefreshtoken;\r
+    String mUserID;\r
+    String mAccessToken;\r
 \r
     private static final int PROVIDER_DISCOVERED = 1;\r
     private static final int STATE_CHANGED = 2;\r
@@ -138,6 +167,10 @@ public class MainActivity extends Activity
         btnUpdateTopicList = (Button) findViewById(R.id.BtnUpdateTopicList);\r
         btnClearLog = (Button) findViewById(R.id.BtnClearLog);\r
 \r
+        signUp = (Button) findViewById(R.id.signup);\r
+        signIn = (Button) findViewById(R.id.signin);\r
+        signOut = (Button) findViewById(R.id.signout);\r
+        subscribeMQ = (Button) findViewById(R.id.subscribeMQService);\r
         TvLog = (TextView) findViewById(R.id.TvLog);\r
 \r
         btnStart.setOnClickListener(mClickListener);\r
@@ -148,6 +181,15 @@ public class MainActivity extends Activity
         btnUpdateTopicList.setOnClickListener(mClickListener);\r
         btnClearLog.setOnClickListener(mClickListener);\r
 \r
+        signIn.setEnabled(false);\r
+        signOut.setEnabled(false);\r
+        btnEnableRemoteService.setEnabled(false);\r
+\r
+        signUp.setOnClickListener(mClickListener);\r
+        signIn.setOnClickListener(mClickListener);\r
+        signOut.setOnClickListener(mClickListener);\r
+        subscribeMQ.setOnClickListener(mClickListener);\r
+\r
         mConsumerSample = new ConsumerSample(getApplicationContext());\r
         mConsumerSample.setHandler(mHandler);\r
     }\r
@@ -218,10 +260,7 @@ public class MainActivity extends Activity
                             break;\r
                         }\r
                         TvLog.append("EnableRemoteService NS-Consumer\n");\r
-\r
-                        //TODO: Update to read the serverAddress from UI\r
-                        String serverAddress = new String();\r
-                        mConsumerSample.enableRemoteService(serverAddress);\r
+                        mConsumerSample.enableRemoteService(RemoteAddress);\r
                     }\r
                     break;\r
                 case R.id.BtnGetTopicList:\r
@@ -265,7 +304,247 @@ public class MainActivity extends Activity
                     TvLog.setText("");\r
                 }\r
                 break;\r
+                case R.id.signup: {\r
+                    if(isStarted == false) {\r
+                        Log.e(TAG, "Fail to Sign Up");\r
+                        showToast("Start ConsumerService First");\r
+                        break;\r
+                    }\r
+                    TvLog.append("Initiating SignUp\n");\r
+                    signUp();\r
+                }\r
+                break;\r
+                case R.id.signin: {\r
+                    if(isStarted == false) {\r
+                        Log.e(TAG, "Fail to Sign In");\r
+                        showToast("Start ConsumerService First");\r
+                        break;\r
+                    }\r
+                    TvLog.append("Initiating SignIn\n");\r
+                    signIn();\r
+                }\r
+                break;\r
+                case R.id.signout: {\r
+                    if(isStarted == false) {\r
+                        Log.e(TAG, "Fail to Sign out");\r
+                        showToast("Start ConsumerService First");\r
+                        break;\r
+                    }\r
+                    TvLog.append("Initiating SignOut\n");\r
+                    signOut();\r
+                }\r
+                break;\r
+                case R.id.subscribeMQService: {\r
+                    if(isStarted == false) {\r
+                        Log.e(TAG, "Fail to SubscribeMQService");\r
+                        showToast("Start ProviderService First");\r
+                        break;\r
+                    }\r
+                    int result = mConsumerSample.subscribeMQService(MQCloudAddress, MQCloudTopic);\r
+                    TvLog.append("SubscribeMQService Result : " + result + "\n");\r
+                }\r
+                break;\r
+            }\r
+        }\r
+    };\r
+    public void logMessage(final String text) {\r
+        runOnUiThread(new Runnable() {\r
+            public void run() {\r
+                Message msg = new Message();\r
+                msg.obj = text;\r
+                TvLog.append(text + "\n");\r
+            }\r
+        });\r
+        Log.i(TAG, text);\r
+    }\r
+    OcAccountManager.OnPostListener onSignUp = new OcAccountManager.OnPostListener() {\r
+        @Override\r
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,\r
+                                                 OcRepresentation ocRepresentation) {\r
+            logMessage("signUp was successful");\r
+            runOnUiThread(new Runnable() {\r
+                public void run() {\r
+                    signIn.setEnabled(true);\r
+                    signUp.setEnabled(false);\r
+                }\r
+            });\r
+            try {\r
+                mUserID = ocRepresentation.getValue("uid");\r
+                mAccessToken = ocRepresentation.getValue("accesstoken");\r
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");\r
+\r
+                logMessage("\tuserID: " + mUserID);\r
+                logMessage("\taccessToken: " + mAccessToken);\r
+                logMessage("\trefreshToken: " + mRefreshtoken);\r
+\r
+                if (ocRepresentation.hasAttribute("expiresin")) {\r
+                    int expiresIn = ocRepresentation.getValue("expiresin");\r
+                    logMessage("\texpiresIn: " + expiresIn);\r
+                }\r
+            } catch (OcException e) {\r
+                Log.e(TAG, e.toString());\r
+            }\r
+        }\r
+\r
+\r
+        @Override\r
+        public synchronized void onPostFailed(Throwable throwable) {\r
+            logMessage("Failed to signUp");\r
+            if (throwable instanceof OcException) {\r
+                OcException ocEx = (OcException) throwable;\r
+                Log.e(TAG, ocEx.toString());\r
+                ErrorCode errCode = ocEx.getErrorCode();\r
+                logMessage("Error code: " + errCode);\r
             }\r
         }\r
     };\r
+    OcAccountManager.OnPostListener onSignIn = new OcAccountManager.OnPostListener() {\r
+        @Override\r
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,\r
+                                                 OcRepresentation ocRepresentation) {\r
+            logMessage("signIn was successful");\r
+            runOnUiThread(new Runnable() {\r
+                public void run() {\r
+                    signIn.setEnabled(false);\r
+                    signOut.setEnabled(true);\r
+                    btnEnableRemoteService.setEnabled(true);\r
+                }\r
+            });\r
+\r
+        }\r
+\r
+        @Override\r
+        public synchronized void onPostFailed(Throwable throwable) {\r
+            logMessage("Failed to signIn");\r
+            if (throwable instanceof OcException) {\r
+                OcException ocEx = (OcException) throwable;\r
+                Log.e(TAG, ocEx.toString());\r
+                ErrorCode errCode = ocEx.getErrorCode();\r
+                logMessage("Error code: " + errCode);\r
+                if (ErrorCode.UNAUTHORIZED_REQ != errCode) {\r
+                    RefreshToken();\r
+                }\r
+            }\r
+        }\r
+    };\r
+    @Override\r
+    public void onPostCompleted(List<OcHeaderOption> ocHeaderOptions, OcRepresentation ocRepresentation) {\r
+\r
+    }\r
+\r
+    @Override\r
+    public void onPostFailed(Throwable throwable) {\r
+\r
+    }\r
+    private void signIn() {\r
+        try {\r
+            if(mAccountManager==null)\r
+            {\r
+                mAccountManager = OcPlatform.constructAccountManagerObject(CIServer,\r
+                        EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));\r
+            }\r
+\r
+            mAccountManager.signIn(mUserID, mAccessToken, onSignIn);\r
+        } catch (OcException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    private void signOut() {\r
+        try {\r
+            logMessage("signOut");\r
+            if(mAccountManager==null)\r
+            {\r
+                try {\r
+                    mAccountManager = OcPlatform.constructAccountManagerObject(CIServer,\r
+                            EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));\r
+                } catch (OcException e) {\r
+                    e.printStackTrace();\r
+                }\r
+            }\r
+            mAccountManager.signOut(this);\r
+            signIn.setEnabled(false);\r
+            signUp.setEnabled(true);\r
+            btnEnableRemoteService.setEnabled(false);\r
+            logMessage("signOut Successful");\r
+        } catch (OcException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    private void signUp() {\r
+        try {\r
+            mAccountManager = OcPlatform.constructAccountManagerObject(CIServer,\r
+                    EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));\r
+        } catch (OcException e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        Intent intentLogin = new Intent(this,LoginActivity.class);\r
+        startActivityForResult(intentLogin, REQUEST_LOGIN);\r
+    }\r
+    @Override\r
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+        super.onActivityResult(requestCode, resultCode, data);\r
+        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_LOGIN) {\r
+            mAuthCode = data.getStringExtra("authCode");\r
+            mAuthProvider = data.getStringExtra("authProvider");\r
+            logMessage("authCode: " + mAuthCode);\r
+            logMessage("authProvider: " + mAuthProvider);\r
+\r
+            try {\r
+                mAccountManager = OcPlatform.constructAccountManagerObject(CIServer,\r
+                        EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));\r
+                logMessage("Calling signup API");\r
+\r
+                mAccountManager.signUp(mAuthProvider, mAuthCode, onSignUp);\r
+            } catch (OcException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+    }\r
+\r
+    OcResource.OnPostListener onRefreshTokenPost = new OcResource.OnPostListener() {\r
+        @Override\r
+        public void onPostCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {\r
+            logMessage("RefreshToken Completed.");\r
+            try {\r
+                mAccessToken = ocRepresentation.getValue("accesstoken");\r
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");\r
+            }\r
+            catch (OcException e)\r
+            {\r
+                e.printStackTrace();\r
+            }\r
+            signIn();\r
+        }\r
+\r
+        @Override\r
+        public void onPostFailed(Throwable throwable) {\r
+            logMessage("RefreshToken failed.");\r
+            Log.d(TAG, "onRefreshTokenPost failed..");\r
+        }\r
+    };\r
+    public void RefreshToken() {\r
+        try {\r
+            OcResource authResource = OcPlatform.constructResourceObject(CIServer, "/.well-known/ocf/account/tokenrefresh",\r
+                    EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP, OcConnectivityType.CT_IP_USE_V4),\r
+                    false, Arrays.asList("oic.wk.account"), Arrays.asList(OcPlatform.DEFAULT_INTERFACE));\r
+            OcRepresentation rep = new OcRepresentation();\r
+\r
+            showToast("RefreshToken in progress..");\r
+            logMessage("RefreshToken in progress..");\r
+            rep.setValue("di", deviceID);\r
+            rep.setValue("granttype", "refresh_token");\r
+            rep.setValue("refreshtoken", mRefreshtoken);\r
+            rep.setValue("uid", mUserID);\r
+            authResource.post(rep, new HashMap<String, String>(), onRefreshTokenPost);\r
+        }\r
+        catch(OcException e)\r
+        {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        Log.d(TAG, "No error while executing login");\r
+    }\r
 }\r
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/activity_login.xml b/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/activity_login.xml
new file mode 100755 (executable)
index 0000000..dfd8e3c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/loginLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".LoginActivity">
+
+    <WebView
+        android:id="@+id/webView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="visible" />
+
+</LinearLayout>
\ No newline at end of file
index b924bc2..3ca4861 100755 (executable)
@@ -9,6 +9,10 @@
     android:paddingTop="@dimen/activity_vertical_margin"\r
     tools:context="com.sec.noticonsumerexample.MainActivity">\r
 \r
+    <ScrollView\r
+        android:layout_width="match_parent"\r
+        android:layout_height="wrap_content"\r
+        android:fillViewport="true">\r
     <LinearLayout\r
         android:layout_width="match_parent"\r
         android:layout_height="wrap_content"\r
             android:layout_height="wrap_content"\r
             android:paddingLeft="5dp"\r
             android:paddingRight="5dp"\r
+            android:orientation="horizontal"\r
+            android:weightSum="1">\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signup"\r
+                android:text="Sign Up"/>\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signin"\r
+                android:text="Sign In" />\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signout"\r
+                android:text="Sign Out" />\r
+        </LinearLayout>\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal"\r
+            android:weightSum="1">\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/BtnEnableRemoteService"\r
+                android:text="Enable Remote Service"/>\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/subscribeMQService"\r
+                android:text="Subscribe MQ Service" />\r
+        </LinearLayout>\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
             android:orientation="vertical" >\r
             <LinearLayout\r
                 android:layout_width="match_parent"\r
                 android:orientation="vertical" >\r
             <Button\r
                 android:layout_gravity="center_vertical|center_horizontal"\r
-                android:layout_height="1dp"\r
-                android:layout_width="match_parent"\r
-                android:id="@+id/BtnEnableRemoteService"\r
-                android:text="Enable Remote Service"/>\r
-            <Button\r
-                android:layout_gravity="center_vertical|center_horizontal"\r
                 android:layout_height="60dp"\r
                 android:layout_width="match_parent"\r
                 android:id="@+id/BtnUpdateTopicList"\r
             android:background="@android:color/darker_gray"/>\r
 \r
     </LinearLayout>\r
-\r
-\r
+    </ScrollView>\r
 </RelativeLayout>\r
old mode 100644 (file)
new mode 100755 (executable)
index bc14e47..be52da1
@@ -29,7 +29,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />\r
             </intent-filter>\r
         </activity>\r
-\r
+        <activity android:name=".LoginActivity" />\r
         <service\r
             android:name="com.sec.notiproviderexample.NotiListener"\r
             android:label="@string/app_name"\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/LoginActivity.java b/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/LoginActivity.java
new file mode 100755 (executable)
index 0000000..7bb3b33
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * ******************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ *
+ * 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 com.sec.notiproviderexample;
+import android.app.Activity;
+import android.content.Intent;
+import android.net.UrlQuerySanitizer;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+
+/**
+ * This class is for login to the provider.
+ * Can be get auth code via web page.
+ */
+public class LoginActivity extends Activity {
+    private static final String TAG = "OIC_SIMPLE_LOGIN";
+
+    private WebView mWebView = null;
+    private final String samsungAccount = "https://account.samsung.com/mobile/account/check.do?serviceID=166135d296&actionID=StartOAuth2&countryCode="+ "US" + "&languageCode=" + "en";
+    private final String mAuthProvider = "samsung-us";
+
+
+    @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setContentView(R.layout.activity_login);
+
+            mWebView = (WebView) findViewById(R.id.webView);
+            mWebView.setInitialScale(200);
+            mWebView.getSettings().setJavaScriptEnabled(true);
+            mWebView.getSettings().setBuiltInZoomControls(true);
+            mWebView.setWebViewClient(new WebViewClientClass());
+
+            mWebView.loadUrl(samsungAccount);
+        }
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    private class WebViewClientClass extends WebViewClient {
+
+        @Override
+            public void onPageFinished(WebView view, String url) {
+                Log.i(TAG, "onPageFinished!!! Response received: called url=" + url);
+
+                    if (url.contains("code") && url.contains("code_expires_in")) {
+
+                    mWebView.setVisibility(View.INVISIBLE);
+
+                    // parsing url
+                    UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
+                    sanitizer.setAllowUnregisteredParamaters(true);
+                    sanitizer.parseUrl(url);
+
+                    String mAuthCode = sanitizer.getValue("code");
+                    Log.i(TAG, "onPageFinished!!! authCode=" + mAuthCode);
+
+                    Intent intent = getIntent();
+                    intent.putExtra("authCode", mAuthCode);
+                    intent.putExtra("authProvider", mAuthProvider);
+                    setResult(RESULT_OK, intent);
+
+                    finish();
+                }
+            }
+    }
+}
index 5d033fc..e6fd0ff 100755 (executable)
@@ -37,17 +37,32 @@ import android.widget.TextView;
 import android.widget.Toast;\r
 import android.app.Activity;\r
 \r
-import org.iotivity.service.ns.common.MediaContents;\r
-\r
-import java.text.DateFormat;\r
-import java.util.Date;\r
-\r
-public class MainActivity extends Activity {\r
+import org.iotivity.base.ErrorCode;\r
+import org.iotivity.base.OcAccountManager;\r
+import org.iotivity.base.OcConnectivityType;\r
+import org.iotivity.base.OcException;\r
+import org.iotivity.base.OcHeaderOption;\r
+import org.iotivity.base.OcPlatform;\r
+import org.iotivity.base.OcRepresentation;\r
+import org.iotivity.base.OcResource;\r
+\r
+import java.util.Arrays;\r
+import java.util.EnumSet;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+\r
+public class MainActivity extends Activity  implements OcAccountManager.OnPostListener {\r
 \r
     private final String TAG = "NS_MAIN_ACTIVITY";\r
     private static final int CONSUMER_SUBSCRIBED = 1;\r
     private static final int MESSAGE_SYNC = 2;\r
-    private static final int MESSAGE_NOTIFICATION = 3;\r
+    private final int REQUEST_LOGIN = 1;\r
+\r
+    public static final String deviceID = "9E09F4FE-978A-4BC3-B356-1F93BCA37829";\r
+    public static final String CIServer = "coap+tcp://52.40.216.160:5683";\r
+    public static final String RemoteAddress = "52.40.216.160:5683";\r
+    public static final String MQCloudAddress = "52.78.151.180:5683";\r
+    public static final String MQCloudTopic = "/oic/ps/notification";\r
 \r
     private Button btnTitle;\r
     private Button btnBody;\r
@@ -58,6 +73,8 @@ public class MainActivity extends Activity {
     private Button btnSet;\r
     private Button btnStop;\r
     private Button btnLog;\r
+    private Button signUp, signIn, signOut;\r
+    private Button remoteService, subscribeMQ;\r
     private EditText editTextTitle;\r
     private EditText editTextBody;\r
     private EditText editTextTopic;\r
@@ -65,11 +82,17 @@ public class MainActivity extends Activity {
     private RadioButton radioConsumer;\r
     private static TextView TvLog;\r
 \r
+    private OcAccountManager mAccountManager;\r
+    String mAuthCode;\r
+    String mAuthProvider;\r
+    String mRefreshtoken;\r
+    String mUserID;\r
+    String mAccessToken;\r
+\r
     private static int notiId = 100;\r
-    private static int subCnt = 0;\r
     private boolean isStarted = false;\r
-    private String consumerId;\r
     private boolean gAcceptor = true;\r
+    private boolean gRemoteService = true;\r
 \r
     private NotiListener mNotiListener = null;\r
     private ProviderSample mProviderSample = null;\r
@@ -122,6 +145,12 @@ public class MainActivity extends Activity {
         btnLog = (Button) findViewById(R.id.BtnLog);\r
         btnStop = (Button) findViewById(R.id.BtnStop);\r
 \r
+        signUp = (Button) findViewById(R.id.signup);\r
+        signIn = (Button) findViewById(R.id.signin);\r
+        signOut = (Button) findViewById(R.id.signout);\r
+        remoteService = (Button) findViewById(R.id.remoteService);\r
+        subscribeMQ = (Button) findViewById(R.id.subscribeMQService);\r
+\r
         editTextTitle = (EditText) findViewById(R.id.EditTextTitle);\r
         editTextBody = (EditText) findViewById(R.id.EditTextBody);\r
         editTextTopic = (EditText) findViewById(R.id.EditTextTopic);\r
@@ -135,6 +164,10 @@ public class MainActivity extends Activity {
         btnBody.setEnabled(false);\r
         btnTopic.setEnabled(false);\r
 \r
+        signIn.setEnabled(false);\r
+        signOut.setEnabled(false);\r
+        remoteService.setEnabled(false);\r
+\r
         btnSend.setOnClickListener(mClickListener);\r
         btnStart.setOnClickListener(mClickListener);\r
         btnRegister.setOnClickListener(mClickListener);\r
@@ -144,11 +177,17 @@ public class MainActivity extends Activity {
         radioProvider.setOnClickListener(mClickListener);\r
         radioConsumer.setOnClickListener(mClickListener);\r
 \r
+        signUp.setOnClickListener(mClickListener);\r
+        signIn.setOnClickListener(mClickListener);\r
+        signOut.setOnClickListener(mClickListener);\r
+\r
+        remoteService.setOnClickListener(mClickListener);\r
+        subscribeMQ.setOnClickListener(mClickListener);\r
+\r
         mProviderSample = new ProviderSample(getApplicationContext());\r
         mProviderSample.setHandler(mHandler);\r
 \r
         mNotiListener = new NotiListener(this);\r
-\r
         Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");\r
         startActivity(intent);\r
     }\r
@@ -285,8 +324,274 @@ public class MainActivity extends Activity {
 \r
                     TvLog.setText("");\r
                 }\r
-                break;  }\r
+                break;\r
+                case R.id.signup: {\r
+                    if(isStarted == false) {\r
+                        Log.e(TAG, "Fail to Sign Up");\r
+                        showToast("Start ProviderService First");\r
+                        break;\r
+                    }\r
+                    TvLog.append("Initiating SignUp\n");\r
+                    signUp();\r
+                }\r
+                break;\r
+                case R.id.signin: {\r
+                    if(isStarted == false) {\r
+                        Log.e(TAG, "Fail to Sign In");\r
+                        showToast("Start ProviderService First");\r
+                        break;\r
+                    }\r
+                    TvLog.append("Initiating SignIn\n");\r
+                    signIn();\r
+                }\r
+                break;\r
+                case R.id.signout: {\r
+                    if(isStarted == false) {\r
+                        Log.e(TAG, "Fail to Sign out");\r
+                        showToast("Start ProviderService First");\r
+                        break;\r
+                    }\r
+                    TvLog.append("Initiating SignOut\n");\r
+                    signOut();\r
+                }\r
+                break;\r
+                case R.id.remoteService: {\r
+                    remoteService.setEnabled(false);\r
+                    if(isStarted == false) {\r
+                        Log.e(TAG, "Fail to Enable/Disable RemoteService");\r
+                        showToast("Start ProviderService First");\r
+                        break;\r
+                    }\r
+                    if(gRemoteService){\r
+                        TvLog.append("Enable Remote Service\n");\r
+                        int result = mProviderSample.EnableRemoteService(RemoteAddress);\r
+                        remoteService.setText(R.string.disableRemoteService);\r
+                        gRemoteService = false;\r
+                        remoteService.setEnabled(true);\r
+                        TvLog.append("EnableRemoteService Result : " + result + "\n");\r
+                    }\r
+                    else {\r
+                        TvLog.append("Disable Remote Service\n");\r
+                        int result = mProviderSample.DisableRemoteService(RemoteAddress);\r
+                        remoteService.setText(R.string.enableRemoteService);\r
+                        gRemoteService = true;\r
+                        remoteService.setEnabled(true);\r
+                        TvLog.append("DisableRemoteService Result : " + result + "\n");\r
+                    }\r
+                }\r
+                break;\r
+                case R.id.subscribeMQService: {\r
+                    if(isStarted == false) {\r
+                        Log.e(TAG, "Fail to SubscribeMQService");\r
+                        showToast("Start ProviderService First");\r
+                        break;\r
+                    }\r
+                    int result = mProviderSample.subscribeMQService(MQCloudAddress, MQCloudTopic);\r
+                    TvLog.append("SubscribeMQService Result : " + result + "\n");\r
+                }\r
+                break;\r
+            }\r
+        }\r
+    };\r
+    public void logMessage(final String text) {\r
+        runOnUiThread(new Runnable() {\r
+            public void run() {\r
+                Message msg = new Message();\r
+                msg.obj = text;\r
+                TvLog.append(text + "\n");\r
+            }\r
+        });\r
+        Log.i(TAG, text);\r
+    }\r
+    OcAccountManager.OnPostListener onSignUp = new OcAccountManager.OnPostListener() {\r
+        @Override\r
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,\r
+                                                 OcRepresentation ocRepresentation) {\r
+            logMessage("signUp was successful");\r
+            runOnUiThread(new Runnable() {\r
+                public void run() {\r
+                    signIn.setEnabled(true);\r
+                    signUp.setEnabled(false);\r
+                }\r
+            });\r
+            try {\r
+                mUserID = ocRepresentation.getValue("uid");\r
+                mAccessToken = ocRepresentation.getValue("accesstoken");\r
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");\r
+\r
+                logMessage("\tuserID: " + mUserID);\r
+                logMessage("\taccessToken: " + mAccessToken);\r
+                logMessage("\trefreshToken: " + mRefreshtoken);\r
+\r
+                if (ocRepresentation.hasAttribute("expiresin")) {\r
+                    int expiresIn = ocRepresentation.getValue("expiresin");\r
+                    logMessage("\texpiresIn: " + expiresIn);\r
+                }\r
+            } catch (OcException e) {\r
+                Log.e(TAG, e.toString());\r
             }\r
+        }\r
+\r
+\r
+        @Override\r
+        public synchronized void onPostFailed(Throwable throwable) {\r
+            logMessage("Failed to signUp");\r
+            if (throwable instanceof OcException) {\r
+                OcException ocEx = (OcException) throwable;\r
+                Log.e(TAG, ocEx.toString());\r
+                ErrorCode errCode = ocEx.getErrorCode();\r
+                logMessage("Error code: " + errCode);\r
+            }\r
+        }\r
     };\r
+    OcAccountManager.OnPostListener onSignIn = new OcAccountManager.OnPostListener() {\r
+        @Override\r
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,\r
+                                                 OcRepresentation ocRepresentation) {\r
+            logMessage("signIn was successful");\r
+            runOnUiThread(new Runnable() {\r
+                public void run() {\r
+                    signIn.setEnabled(false);\r
+                    signOut.setEnabled(true);\r
+                    remoteService.setEnabled(true);\r
+                }\r
+            });\r
+\r
+        }\r
+\r
+        @Override\r
+        public synchronized void onPostFailed(Throwable throwable) {\r
+            logMessage("Failed to signIn");\r
+            if (throwable instanceof OcException) {\r
+                OcException ocEx = (OcException) throwable;\r
+                Log.e(TAG, ocEx.toString());\r
+                ErrorCode errCode = ocEx.getErrorCode();\r
+                logMessage("Error code: " + errCode);\r
+                if (ErrorCode.UNAUTHORIZED_REQ != errCode) {\r
+                    RefreshToken();\r
+                }\r
+            }\r
+        }\r
+    };\r
+    @Override\r
+    public void onPostCompleted(List<OcHeaderOption> ocHeaderOptions, OcRepresentation ocRepresentation) {\r
+\r
+    }\r
+\r
+    @Override\r
+    public void onPostFailed(Throwable throwable) {\r
+\r
+    }\r
+    private void signIn() {\r
+        try {\r
+            if(mAccountManager==null)\r
+            {\r
+                mAccountManager = OcPlatform.constructAccountManagerObject(CIServer,\r
+                        EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));\r
+            }\r
+\r
+            mAccountManager.signIn(mUserID, mAccessToken, onSignIn);\r
+        } catch (OcException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    private void signOut() {\r
+        try {\r
+            logMessage("signOut");\r
+            if(mAccountManager==null)\r
+            {\r
+                try {\r
+                    mAccountManager = OcPlatform.constructAccountManagerObject(CIServer,\r
+                            EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));\r
+                } catch (OcException e) {\r
+                    e.printStackTrace();\r
+                }\r
+            }\r
+            mAccountManager.signOut(this);\r
+            signIn.setEnabled(false);\r
+            signUp.setEnabled(true);\r
+            remoteService.setEnabled(false);\r
+            logMessage("signOut Successful");\r
+        } catch (OcException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    private void signUp() {\r
+        try {\r
+            mAccountManager = OcPlatform.constructAccountManagerObject(CIServer,\r
+                    EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));\r
+        } catch (OcException e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        Intent intentLogin = new Intent(this, LoginActivity.class);\r
+        startActivityForResult(intentLogin, REQUEST_LOGIN);\r
+    }\r
+    @Override\r
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+        super.onActivityResult(requestCode, resultCode, data);\r
+        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_LOGIN) {\r
+            mAuthCode = data.getStringExtra("authCode");\r
+            mAuthProvider = data.getStringExtra("authProvider");\r
+            logMessage("authCode: " + mAuthCode);\r
+            logMessage("authProvider: " + mAuthProvider);\r
+\r
+            try {\r
+                mAccountManager = OcPlatform.constructAccountManagerObject(CIServer,\r
+                        EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));\r
+                logMessage("Calling signup API");\r
+\r
+                mAccountManager.signUp(mAuthProvider, mAuthCode, onSignUp);\r
+            } catch (OcException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+    }\r
+\r
+    OcResource.OnPostListener onRefreshTokenPost = new OcResource.OnPostListener() {\r
+        @Override\r
+        public void onPostCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {\r
+            logMessage("RefreshToken Completed.");\r
+            try {\r
+                mAccessToken = ocRepresentation.getValue("accesstoken");\r
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");\r
+            }\r
+            catch (OcException e)\r
+            {\r
+                e.printStackTrace();\r
+            }\r
+            signIn();\r
+        }\r
+\r
+        @Override\r
+        public void onPostFailed(Throwable throwable) {\r
+            logMessage("RefreshToken failed.");\r
+            Log.d(TAG, "onRefreshTokenPost failed..");\r
+        }\r
+    };\r
+    public void RefreshToken() {\r
+        try {\r
+            OcResource authResource = OcPlatform.constructResourceObject(CIServer, "/.well-known/ocf/account/tokenrefresh",\r
+                    EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP, OcConnectivityType.CT_IP_USE_V4),\r
+                    false, Arrays.asList("oic.wk.account"), Arrays.asList(OcPlatform.DEFAULT_INTERFACE));\r
+            OcRepresentation rep = new OcRepresentation();\r
+\r
+            showToast("RefreshToken in progress..");\r
+            logMessage("RefreshToken in progress..");\r
+            rep.setValue("di", deviceID);\r
+            rep.setValue("granttype", "refresh_token");\r
+            rep.setValue("refreshtoken", mRefreshtoken);\r
+            rep.setValue("uid", mUserID);\r
+            authResource.post(rep, new HashMap<String, String>(), onRefreshTokenPost);\r
+        }\r
+        catch(OcException e)\r
+        {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        Log.d(TAG, "No error while executing login");\r
+    }\r
 }\r
 \r
index 55dcb1d..ce4e0c8 100755 (executable)
@@ -212,30 +212,46 @@ public class ProviderSample
         }
     }
 
-    public void EnableRemoteService(String servAdd) {
+    public int EnableRemoteService(String servAdd) {
         Log.i(TAG, "EnableRemoteService ProviderService - IN");
+        int result = 0;
         try{
-            int result = ioTNotification.enableRemoteService(servAdd);
+            result = ioTNotification.enableRemoteService(servAdd);
             Log.i(TAG, "Notification EnableRemoteService: "+ result );
         }
         catch(Exception e) {
 
         }
         Log.i(TAG, "EnableRemoteService ProviderService - OUT");
+        return result;
     }
 
-    public void DisableRemoteService(String servAdd) {
+    public int DisableRemoteService(String servAdd) {
         Log.i(TAG, "DisableRemoteService ProviderService - IN");
+        int result = 0;
         try{
-            int result = ioTNotification.disableRemoteService(servAdd);
+            result = ioTNotification.disableRemoteService(servAdd);
             Log.i(TAG, "Notification DisableRemoteService: "+ result );
         }
         catch(Exception e) {
 
         }
         Log.i(TAG, "DisableRemoteService ProviderService - OUT");
+        return result;
     }
+    public int subscribeMQService(String servAdd, String topicName) {
+        Log.i(TAG, "SubscribeMQService ProviderService - IN");
+        int result = 0;
+        try{
+            result = ioTNotification.subscribeMQService(servAdd, topicName);
+            Log.i(TAG, "Notification SubscribeMQService: "+ result );
+        }
+        catch(Exception e) {
 
+        }
+        Log.i(TAG, "SubscribeMQService ProviderService - OUT");
+        return result;
+    }
     public void AcceptSubscription(Consumer consumer, boolean accepted)
     {
         Log.i(TAG,"AcceptSubscription ProviderService - IN");
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_login.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_login.xml
new file mode 100755 (executable)
index 0000000..dfd8e3c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/loginLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".LoginActivity">
+
+    <WebView
+        android:id="@+id/webView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="visible" />
+
+</LinearLayout>
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index d109ae4..45cfebc
@@ -9,6 +9,10 @@
     android:paddingTop="@dimen/activity_vertical_margin"\r
     tools:context="com.sec.notificationexample.MainActivity">\r
 \r
+    <ScrollView\r
+        android:layout_width="match_parent"\r
+        android:layout_height="wrap_content"\r
+        android:fillViewport="true">\r
     <LinearLayout\r
         android:layout_width="match_parent"\r
         android:layout_height="wrap_content"\r
 \r
             </RadioGroup>\r
         </LinearLayout>\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal"\r
+            android:weightSum="1">\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signup"\r
+                android:text="Sign Up"/>\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signin"\r
+                android:text="Sign In" />\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signout"\r
+                android:text="Sign Out" />\r
+        </LinearLayout>\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal"\r
+            android:weightSum="1">\r
 \r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/remoteService"\r
+                android:text="Enable Remote Service"/>\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/subscribeMQService"\r
+                android:text="Subscribe MQ Service" />\r
+        </LinearLayout>\r
         <LinearLayout\r
             android:layout_width="match_parent"\r
             android:layout_height="wrap_content"\r
         </ScrollView>\r
 \r
     </LinearLayout>\r
-\r
+    </ScrollView>\r
 </RelativeLayout>\r
old mode 100644 (file)
new mode 100755 (executable)
index 80b63f8..9f0f4db
@@ -8,4 +8,6 @@
     <string name="btn_send">Send Notification</string>\r
     <string name="btn_create_noti">Send Notification</string>\r
     <string name="btn_log">Clear Logs</string>\r
+    <string name="enableRemoteService">Enable Remote Service</string>\r
+    <string name="disableRemoteService">Disable Remote Service</string>\r
 </resources>\r